Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions REQUIRE
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
PyPlot
Elliptic
Compat
5 changes: 3 additions & 2 deletions src/Geometry2D.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
module Geometry2D

using Compat
using PyPlot
import PyPlot: plot, fill, polar

Expand All @@ -19,11 +20,11 @@ abstract G2dSimpleObject <: G2dObject # objects for which area,perimeter,isin, m
abstract G2dCompoundObject <: G2dObject

# automated promotion rules for arrays of numbers
promote_rule{T<:Integer,S<:FloatingPoint}(::Type{Array{T,1}}, ::Type{Array{S,1}} ) = Array{S,1}
promote_rule{T<:Integer,S<:AbstractFloat}(::Type{Array{T,1}}, ::Type{Array{S,1}} ) = Array{S,1}
promote_rule{T<:Integer}(::Type{Array{Rational{T},1}}, ::Type{Array{T,1}}) = Array{Rational{T},1}
promote_rule{T<:Integer,S<:Integer}(::Type{Array{Rational{T},1}}, ::Type{Array{S,1}}) = Array{Rational{promote_type(T,S)},1}
promote_rule{T<:Integer,S<:Integer}(::Type{Array{Rational{T},1}}, ::Type{Array{Rational{S},1}}) = Array{Rational{promote_type(T,S)},1}
promote_rule{T<:Integer,S<:FloatingPoint}(::Type{Array{Rational{T},1}}, ::Type{Array{S,1}}) = Array{promote_type(T,S), 1}
promote_rule{T<:Integer,S<:AbstractFloat}(::Type{Array{Rational{T},1}}, ::Type{Array{S,1}}) = Array{promote_type(T,S), 1}
# should probably put something in here for complex numbers too

tolerance = eps() # global variable for tolerance of many operations in floating point
Expand Down
2 changes: 1 addition & 1 deletion src/circle.jl
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ closed(::Circle) = true
# approximate as a regular polygon
function approxpoly(c::Circle, n::Integer)
dtheta = 2.0*pi/n
theta = dtheta*[0:n]
theta = dtheta*collect(0:n)
x = c.center.x + c.radius * cos(theta)
y = c.center.y + c.radius * sin(theta)
return PointArray(x,y)
Expand Down
2 changes: 1 addition & 1 deletion src/intersection.jl
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ end
intersection( r::Ray, s::Segment; tolerance=1.0e-12 ) = intersection( s, r; tolerance=tolerance )

# intersection of lines with segments or Rays
RayOrSegment = Union(Ray, Segment)
RayOrSegment = @compat Union{Ray, Segment}
function intersection( s::RayOrSegment, l::Line; tolerance=1.0e-12 )
#OUTPUTS:
# intersect = 0 means no intersection
Expand Down
22 changes: 11 additions & 11 deletions src/line.jl
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ Segment{T<:Number}(startpoint::Point{T}, endpoint::Point{T}) = Segment{T}(promot
Segment{T<:Number, S<:Number}(startpoint::Point{T}, endpoint::Point{S}) = Segment(promote(startpoint, endpoint)...)

# could have done this with an abstract type above the three, but wanted to try out Unions
LINETYPE = Union(Line, Ray, Segment)
LINETYPE = @compat Union{Line, Ray, Segment}

# lots of alternate representations we could build constructors for
# ray constructed using two points (with one as start), or point and a slope (and + or -)
Expand All @@ -94,23 +94,23 @@ copy(r::Ray) = Ray(r.startpoint, r.direction)
copy(s::Segment) = Segment(s.startpoint, s.endpoint)


# promote_rule{T<:Integer,S<:FloatingPoint}(::Type{Line{T}}, ::Type{Line{S}} ) = Line{S}
# promote_rule{T<:Integer,S<:AbstractFloat}(::Type{Line{T}}, ::Type{Line{S}} ) = Line{S}
# promote_rule{T<:Integer}(::Type{Line{Rational{T}}}, ::Type{Line{T}}) = Line{Rational{T}}
# promote_rule{T<:Integer,S<:Integer}(::Type{Line{Rational{T}}}, ::Type{Line{S}}) = Line{Rational{promote_type(T,S)}}
# promote_rule{T<:Integer,S<:Integer}(::Type{Line{Rational{T}}}, ::Type{Line{Rational{S}}}) = Line{Rational{promote_type(T,S)}}
# promote_rule{T<:Integer,S<:FloatingPoint}(::Type{Line{Rational{T}}}, ::Type{Line{S}}) = Line{promote_type(T,S)}
# promote_rule{T<:Integer,S<:AbstractFloat}(::Type{Line{Rational{T}}}, ::Type{Line{S}}) = Line{promote_type(T,S)}

# promote_rule{T<:Integer,S<:FloatingPoint}(::Type{Ray{T}}, ::Type{Ray{S}} ) = Ray{S}
# promote_rule{T<:Integer,S<:AbstractFloat}(::Type{Ray{T}}, ::Type{Ray{S}} ) = Ray{S}
# promote_rule{T<:Integer}(::Type{Ray{Rational{T}}}, ::Type{Ray{T}}) = Ray{Rational{T}}
# promote_rule{T<:Integer,S<:Integer}(::Type{Ray{Rational{T}}}, ::Type{Ray{S}}) = Ray{Rational{promote_type(T,S)}}
# promote_rule{T<:Integer,S<:Integer}(::Type{Ray{Rational{T}}}, ::Type{Ray{Rational{S}}}) = Ray{Rational{promote_type(T,S)}}
# promote_rule{T<:Integer,S<:FloatingPoint}(::Type{Ray{Rational{T}}}, ::Type{Ray{S}}) = Ray{promote_type(T,S)}
# promote_rule{T<:Integer,S<:AbstractFloat}(::Type{Ray{Rational{T}}}, ::Type{Ray{S}}) = Ray{promote_type(T,S)}

# promote_rule{T<:Integer,S<:FloatingPoint}(::Type{Segment{T}}, ::Type{Segment{S}} ) = Segment{S}
# promote_rule{T<:Integer,S<:AbstractFloat}(::Type{Segment{T}}, ::Type{Segment{S}} ) = Segment{S}
# promote_rule{T<:Integer}(::Type{Segment{Rational{T}}}, ::Type{Segment{T}}) = Segment{Rational{T}}
# promote_rule{T<:Integer,S<:Integer}(::Type{Segment{Rational{T}}}, ::Type{Segment{S}}) = Segment{Rational{promote_type(T,S)}}
# promote_rule{T<:Integer,S<:Integer}(::Type{Segment{Rational{T}}}, ::Type{Segment{Rational{S}}}) = Segment{Rational{promote_type(T,S)}}
# promote_rule{T<:Integer,S<:FloatingPoint}(::Type{Segment{Rational{T}}}, ::Type{Segment{S}}) = Segment{promote_type(T,S)}
# promote_rule{T<:Integer,S<:AbstractFloat}(::Type{Segment{Rational{T}}}, ::Type{Segment{S}}) = Segment{promote_type(T,S)}

# conversion of one type to another: note though that these loose information
convert{T<:Number}(::Type{Ray}, s::Segment{T}) = Ray(s.startpoint, s.endpoint-s.startpoint)
Expand Down Expand Up @@ -277,16 +277,16 @@ function displayPath(line::Line; bounds=default_bounds)
# choose the two points that are in the bounding rectangle
P = []
if i1==1 && isin(p1, bounds)[1]
P = [P, p1]
P = vcat(P, p1)
end
if i2==1 && isin(p2, bounds)[1]
P = [P, p2]
P = vcat(P, p2)
end
if i3==1 && isin(p3, bounds)[1]
P = [P, p3]
P = vcat(P, p3)
end
if i4==1 && isin(p4, bounds)[1]
P = [P, p4]
P = vcat(P, p4)
end
return unique(P) # doesn't eliminate all possible redundant points because of roundoff errors
end
Expand Down
18 changes: 9 additions & 9 deletions src/point.jl
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,16 @@ origin{T<:Number}(::Point{T}) = Point(convert(T,0), convert(T,0))
typealias Vect Point

# automated promotion rules for Points
promote_rule{T<:Integer,S<:FloatingPoint}(::Type{Point{T}}, ::Type{Point{S}} ) = Point{S}
promote_rule{T<:Integer,S<:AbstractFloat}(::Type{Point{T}}, ::Type{Point{S}} ) = Point{S}
promote_rule{T<:Integer}(::Type{Point{Rational{T}}}, ::Type{Point{T}}) = Point{Rational{T}}
promote_rule{T<:Integer,S<:Integer}(::Type{Point{Rational{T}}},::Type{Point{S}}) = Point{Rational{promote_type(T,S)}}
promote_rule{T<:Integer,S<:Integer}(::Type{Point{Rational{T}}},::Type{Point{Rational{S}}}) = Point{Rational{promote_type(T,S)}}
promote_rule{T<:Integer,S<:FloatingPoint}(::Type{Point{Rational{T}}}, ::Type{Point{S}}) = Point{promote_type(T,S)}
promote_rule{T<:FloatingPoint,S<:FloatingPoint}(::Type{Point{T}}, ::Type{Point{S}}) = Point{promote_type(T,S)}
promote_rule{T<:Integer,S<:AbstractFloat}(::Type{Point{Rational{T}}}, ::Type{Point{S}}) = Point{promote_type(T,S)}
promote_rule{T<:AbstractFloat,S<:AbstractFloat}(::Type{Point{T}}, ::Type{Point{S}}) = Point{promote_type(T,S)}
# should probably put something in here for complex numbers too

# don't seem to need these?
# convert{T<:FloatingPoint}(::Type{Point{T}}, p::Point) = Point(convert(T,p.x), convert(T,p.y))
# convert{T<:AbstractFloat}(::Type{Point{T}}, p::Point) = Point(convert(T,p.x), convert(T,p.y))
# convert{T<:Integer}(::Type{Point{Rational{T}}}, p::Point) = Point(convert(Rational{T},p.x), convert(Rational{T},p.y))
# convert{T<:Integer}(::Type{Point{T}}, p::Point) = Point(convert(T,p.x), convert(T,p.y))

Expand All @@ -58,13 +58,13 @@ inner(p1::Point, p2::Point) = p1.x * p2.x + p1.y * p2.y
isequal(p1::Point, p2::Point) = ( p1.x==p2.x && p1.y==p2.y )
isless(p1::Point, p2::Point) = ( p1.x<p2.x || (p1.x==p2.x && p1.y<p2.y) )
!=(p1::Point, p2::Point) = !isequal(p1, p2)
< (p1::Point, p2::Point) = isless(p1,p2)
> (p1::Point, p2::Point) = p2<p1
# isequal{T<:FloatingPoint}(p1::Point{T}, p2::Point{T}) = ( abs(p1-p2) <= Point(tolerance, tolerance))
<(p1::Point, p2::Point) = isless(p1,p2)
>(p1::Point, p2::Point) = p2<p1
# isequal{T<:AbstractFloat}(p1::Point{T}, p2::Point{T}) = ( abs(p1-p2) <= Point(tolerance, tolerance))
# isequal{T<:Number, S<:Number}(p1::Point{T}, p2::Point{S}) = isequal(promote(p1,p2)...)
==(p1::Point, p2::Point) = isequal(p1, p2)
.< (p1::Point, p2::Point) = p1<p2
.> (p1::Point, p2::Point) = p2<p1
.<(p1::Point, p2::Point) = p1<p2
.>(p1::Point, p2::Point) = p2<p1
.>=(p1::Point, p2::Point) = p1<=p2
.<=(p1::Point, p2::Point) = p2<=p1
cmp(p1::Point, p2::Point) = p1<p2 ? -1 : p2<p1 ? 1 : 0
Expand Down
28 changes: 14 additions & 14 deletions src/random.jl
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
# functions for generating random objects
# nominally these are "uniform over unit square" for Float types
# but what does that mean actually?
# only implemented for FloatingPoint types, as this is all that makes sense???
# only implemented for AbstractFloat types, as this is all that makes sense???
#
export rand

# generate a random object
rand{T<:FloatingPoint}(::Type{Point{T}}) = Point{T}(rand(T), rand(T))
rand{T<:FloatingPoint}(::Type{Circle{T}}) = Circle{T}(rand(Point{T}), rand(T))
rand{T<:FloatingPoint}(::Type{Ellipse{T}}) = Ellipse{T}(rand(Point{T}), rand(T), rand(T), randangle(T))
rand{T<:FloatingPoint}(::Type{Arc{T}}) = Arc{T}(rand(Point{T}), rand(), randangle(T), randangle(T))
rand{T<:FloatingPoint}(::Type{Line{T}}) = Line{T}(rand(Point{T}), randangle(T))
rand{T<:FloatingPoint}(::Type{Ray{T}}) = Ray{T}(rand(Point{T}), rand(Point{T}))
rand{T<:FloatingPoint}(::Type{Segment{T}}) = Segment{T}(rand(Point{T}), rand(Point{T}))
rand{T<:FloatingPoint}(::Type{Triangle{T}}) = Triangle{T}( rand(Point{T}, (3,)) )
rand{T<:FloatingPoint}(::Type{Polygon{T}}, n::Integer) = Polygon( rand(Point{T}, (n,)) )
rand{T<:AbstractFloat}(::Type{Point{T}}) = Point{T}(rand(T), rand(T))
rand{T<:AbstractFloat}(::Type{Circle{T}}) = Circle{T}(rand(Point{T}), rand(T))
rand{T<:AbstractFloat}(::Type{Ellipse{T}}) = Ellipse{T}(rand(Point{T}), rand(T), rand(T), randangle(T))
rand{T<:AbstractFloat}(::Type{Arc{T}}) = Arc{T}(rand(Point{T}), rand(), randangle(T), randangle(T))
rand{T<:AbstractFloat}(::Type{Line{T}}) = Line{T}(rand(Point{T}), randangle(T))
rand{T<:AbstractFloat}(::Type{Ray{T}}) = Ray{T}(rand(Point{T}), rand(Point{T}))
rand{T<:AbstractFloat}(::Type{Segment{T}}) = Segment{T}(rand(Point{T}), rand(Point{T}))
rand{T<:AbstractFloat}(::Type{Triangle{T}}) = Triangle{T}( rand(Point{T}, (3,)) )
rand{T<:AbstractFloat}(::Type{Polygon{T}}, n::Integer) = Polygon( rand(Point{T}, (n,)) )

# random angle uniformly distributed over [-pi,pi]
randangle{T<:FloatingPoint}(::Type{T}) = pi*(rand(T)-1)
randangle{T<:AbstractFloat}(::Type{T}) = pi*(rand(T)-1)
# does this even make sense for integer?

################################################################
Expand All @@ -41,7 +41,7 @@ rand(::Type{Polygon}, n::Integer) = rand(Polygon{Float64}, n)
# my own code here to make the default type work, so we can create random arrays of objects
for object in (Point, Circle, Ellipse, Arc, Line, Ray, Segment, Triangle)
@eval begin
rand{T<:FloatingPoint}(::Type{$(object){T}}, dims::Dims) = rand!(Array($(object){T}, dims))
rand{T<:AbstractFloat}(::Type{$(object){T}}, dims::Dims) = rand!(Array($(object){T}, dims))
rand(::Type{$(object)}, dims::Dims) = rand!(Array($(object){Float64}, dims))
end
end
Expand All @@ -52,7 +52,7 @@ end
# technically, we are generating a 2D Poisson Process on the shape in question
# using repeated censoring of points (there are faster approaches for particular shapes
# but this will work for any, with the codicil that they have non-zero area).
function rand{T<:FloatingPoint}(::Type{Point{T}}, b::Bounds)
function rand{T<:AbstractFloat}(::Type{Point{T}}, b::Bounds)
xscale = b.right - b.left
yscale = b.top - b.bottom
p = Point(convert(T, b.left + xscale*rand(T)), convert(T, b.bottom + yscale*rand(T)))
Expand All @@ -62,7 +62,7 @@ rand(::Type{Point}, b::Bounds) = rand(Point{Float64}, b)

for object in (Circle, Ellipse, Triangle, Polygon)
@eval begin
function rand{T<:FloatingPoint}(::Type{Point{T}}, o::$(object))
function rand{T<:AbstractFloat}(::Type{Point{T}}, o::$(object))
B = bounds(o)
i = 0
p = rand(Point{T}, B)
Expand Down
2 changes: 1 addition & 1 deletion test/test_ccw.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ n = 5
srand(1)
X = rand(3,n)
Y = rand(3,n)
X[:,1] = [1:3] # make sure there is at least one colinear case
X[:,1] = collect(1:3) # make sure there is at least one colinear case
Y[:,1] = [0,0,0]
CCW = Array(Float64,6,n)

Expand Down
4 changes: 2 additions & 2 deletions test/test_point.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ plot(p3; marker="o", color="blue")
p4 = Point(1, 1.0)
p5 = Point(2, 3//4)
p6 = Point(3.0, 2//3)
p7 = Point(convert(Uint32,2), convert(Uint16,3))
p8 = Point(convert(Uint32,2)//convert(Uint32,4), convert(Uint16,3))
p7 = Point(convert(UInt32,2), convert(UInt16,3))
p8 = Point(convert(UInt32,2)//convert(UInt32,4), convert(UInt16,3))

# some tests of promotion of Points
dump(promote(p1,p2))
Expand Down