Geometry2D.jl
Basic shapes and related geometrical concepts come up frequently, this basic module defines structures and functions providing common calculations. This module is not attempting to be a 2D sketcher but rather provides clear, explicit, and verbose functions that improve users' maintainability and conceptual clarity.
Included entities/concepts:
- Points
- Triangles
- Circles
- Ellipses
- Spirals
- Homogeneous transforms
Many more entities and functions are under consideration, pending need. Please open an enhancement issue to help us prioritize our efforts.
Installation
using Pkg
Pkg.add(url="https://github.com/mechanomy/Geometry2D.jl.git")
Basic Example
using Unitful, Unitful.DefaultSymbols
using Plots
using Geometry2D
p = Point(1mm,2u"inch")
plot(p, label="Point", title="Basic Example", aspect_ratio=:equal)
pa = Point(1mm,1u"inch")
r = 50mm
ca = Circle(pa, r)
plot!(ca, label="Circle A")
cb = Circle(5mm, 50mm, 20mm)
plot!(cb, label="Circle B")
API
Geometry2D.Geometry2D
— ModuleGeometry2D models basic geometric shapes and common geometric formulae. This is a flat module with entities grouped into similar files under src
.
See online documentation at https://mechanomy.github.io/Geometry2D.jl/dev/ and test for examples of each function.
Geometry2D.AngleOrReal
— TypeType union accepting Angle
or Real.
Geometry2D.LengthOrReal
— TypeType union accepting Unitful.Length or Real.
Geometry2D.PitchOrReal
— TypeType union accepting Pitch
or Real.
Geometry2D.ui
— ConstantConvenience unit vector in the x direction.
Geometry2D.uj
— ConstantConvenience unit vector in the y direction.
Geometry2D.uk
— ConstantConvenience unit vector in the z direction.
Geometry2D.Circle
— TypeA circle having a center::Point
and a radius::Unitful.Length
.
Geometry2D.Circle
— MethodCircle( x::Unitful.Length, y::Unitful.Length, r::Unitful.Length )
A circle having a center at x::Unitful.Length
and y::Unitful.Length
with radius::Unitful.Length
.
Geometry2D.Delta
— TypeA difference between two points on the cartesian plane, measured in dx
and dy
from the plane's origin. This is introduced as a separate type to avoid using Vector{}s with inexplicit length.
Geometry2D.Point
— TypeA point on the cartesian plane, measured in x
and y
from the plane's origin.
Geometry2D.Spiral
— TypeDescribes a spiral progressing from a0
,r0
to a1
,r1
. If thickness
is not specified it is calculated such that each layer touches neighbors, a tightly wound spiral, if it is specified then an open spiral is modeled.
a0::AngleOrReal
– start anglea1::AngleOrReal
– stop angler0::LengthOrReal
– start radiusr1::LengthOrReal
– stop radiuspitch::PitchOrReal
– pitch
Geometry2D.Spiral
— MethodSpiral( a0::AngleOrReal, a1::AngleOrReal, r0::LengthOrReal, r1::LengthOrReal ) Create a Spiral, calculating the pitch from a0
, a1
, r0
, and r1
.
Geometry2D.UnitVector
— TypeA UnitVector
type is unitless, expressing only relative magnitude. It has fields x
, y
, and z
x
Component in the x direction.
y
Component in the y direction.
z
Component in the z direction.
Geometry2D.UnitVector
— MethodUnitVector(vec::AbstractVector)
Given some subtype of AbstractVector, return a UnitVector.
Geometry2D.UnitVector2D
— TypeA UnitVector2D
type is unitless, expressing only relative magnitude. It has fields x
and y
.
Geometry2D.UnitVector2D
— MethodUnitVector2D(dl::Delta)
Constructs a UnitVector2D in the direction of dl
.
Geometry2D.Vector2D
— TypeA 2D vector from origin
to tip
. Functions are provided to convert from the struct's cartesian format to polar.
Base.:*
— Method(*)(p::Point, f::Real) :: Point
Multiplies p
by the given factor f
.
Base.:+
— Method(+)(p::Point, d::Delta) :: Point
Adds a d
Delta to Point p
.
Base.:-
— Method(-)(p::Point, d::Delta) :: Point
Subtracts a Delta d
from the Point p
.
Base.:-
— Method(-)(a::Point, b::Point) :: Delta
Finds the Delta between Points a
and b
.
Base.:-
— Method(-)(a::Real, uv::UnitVector) :: UnitVector
Provides negation of UnitVectors.
Base.:/
— Method(/)(d::Delta, f::Real) :: Delta
Divides d
by the given factor f
.
Base.:/
— Method(/)(p::Point, f::Real) :: Point
Divides p
by the given factor f
.
Base.angle
— Methodangle(d::Delta) :: Real
Calculate the angle of Delta d
relative to global x = horizontal.
Base.angle
— Methodangle(v::Vector2D) :: Angle
angled(v::Vector2D) :: typeof(1.0u"°")
Calculate the angle of Vector2D v
relative to global x = horizontal, via atan().
Base.isapprox
— Methodisapprox(a::Delta, b::Delta; atol=0, rtol=√eps()) :: Bool
Approximately compare Deltas a
and b
via absolute tolerance atol
and relative tolerance rtol
, as in isapprox.
Base.isapprox
— Methodisapprox(p::Point, q::Point; atol=0, rtol=√eps()) :: Bool
Approximately compare Points p
and q
via absolute tolerance atol
and relative tolerance rtol
, as in isapprox.
Base.isapprox
— Methodisapprox(a::UnitVector, b::UnitVector; atol=0, rtol=√eps()) :: Bool
Approximately compare UnitVectors a
to b
via absolute tolerance atol
and relative tolerance rtol
, as in isapprox.
Base.isapprox
— Methodisapprox(a::UnitVector2D, b::UnitVector2D; atol=0, rtol=√eps()) :: Bool
Approximately compare UnitVector2Ds a
and b
via absolute tolerance atol
and relative tolerance rtol
, as in isapprox.
Base.isapprox
— Methodisapprox(a::Vector2D, b::Vector2D; atol=0, rtol=√eps()) :: Bool
Approximately compare Vector2Ds a
to b
via absolute tolerance atol
and relative tolerance rtol
, as in isapprox.
Geometry2D.Rz
— MethodRz(p::Point, a::Angle)
Rotate p
in the plane an angle a
.
Geometry2D.Rz
— MethodRz(angle::Real)
Create a 2D rotation matrix effecting a rotation of angle
. Homogeneous transformation matrices are multiplicative and therefore should be unitless.
Geometry2D.Rz
— MethodRz(angle::Angle)
Create a 2D rotation matrix effecting a rotation of angle
. Homogeneous transformation matrices are multiplicative and therefore should be unitless.
Geometry2D.Tx
— MethodTx(p::Point, d::Unitful.Length)
Translate p
a distance of d
in the X direction. Homogeneous transformation matrices are multiplicative and therefore should be unitless.
Geometry2D.Tx
— MethodTx(a::Real) Create a 2D translation matrix translating along local X an angle a
. Homogeneous transformation matrices are multiplicative and therefore should be unitless.
Geometry2D.Ty
— MethodTy(p::Point, d::Unitful.Length)
Translate p
a distance of d
in the X direction. Homogeneous transformation matrices are multiplicative and therefore should be unitless.
Geometry2D.Ty
— MethodTy(b::Real) Create a 2D translation matrix translating along local Y by b
. Homogeneous transformation matrices are multiplicative and therefore should be unitless.
Geometry2D.angleAdjacent2Opposite
— MethodangleAdjacent2Opposite(angle::Angle, adjacent::Unitful.Length) :: Unitful.Length
angleAdjacent2Opposite(angle::Angle, adjacent::Unitful.Length) :: Unitful.Length
For a right triangle, find the length of the 'opposite' leg, given angle
and adjacent
.
Geometry2D.angleOpposite2Adjacent
— MethodangleOpposite2Adjacent(angle::Angle, opposite::Unitful.Length) :: Unitful.Length
angleOpposite2Adjacent(; angle::Angle, opposite::Unitful.Length) :: Unitful.Length
For a right triangle, find the length of the 'adjacent' leg, given angle
and opposite
.
Geometry2D.angleWrap
— MethodangleWrap(angle::Real) :: Real
Wraps angle
between 0 and 2π.
Geometry2D.angleWrap
— MethodangleWrap(angle::Radian) :: Radian
Wraps angle
between 0 and 2π.
Geometry2D.calcLength
— MethodcalcLength(a0::AngleOrReal, a1::AngleOrReal, r0::LengthOrReal, r1::LengthOrReal)
calcLength(;a0::AngleOrReal, a1::AngleOrReal, r0::LengthOrReal, r1::LengthOrReal)
calcLength(s::Spiral)
Length along the spiral, as if it were unrolled.
Geometry2D.calcPitch
— MethodcalcPitch(a0::AngleOrReal, a1::AngleOrReal, r0::LengthOrReal, r1::LengthOrReal)
calcPitch(; a0::AngleOrReal, a1::AngleOrReal, r0::LengthOrReal, r1::LengthOrReal)
calcPitch(s::Spiral)
Calculate a spiral's pitch from (r1
-r0
)/(a1
-a0
). The nominal units of Pitch defined to be [m/rev], but this will return Real if the arguments or Spiral are that, or a Pitch,m/rad,m/deg depending on __.
Geometry2D.circleArcLength
— MethodcircleArcLength( circle::Circle, angle::Angle )
Compute the circlular arc length of circle
over angle
.
Geometry2D.circleArcLength
— MethodcircleArcLength( radius::Unitful.Length, angle::Angle )
Compute the circlular arc length at radius
over angle
.
angle = 20u"°"
radius = 5u"mm"
len = circleArcLength(angle, radius)
Geometry2D.circleArea
— MethodcircleArea(c::Circle) :: Unitful.Area
Calculate the area of a circle with radius r
.
Geometry2D.circleArea
— MethodcircleArea(r::Unitful.Length) :: Unitful.Area
Calculate the area of a circle with radius r
.
Geometry2D.circumference
— Methodcircumference( circle::Circle )
Calculate the circumeference of circle
.
Geometry2D.circumference
— Methodcircumference( r::Unitful.Length ) :: Unitful.Length
Calculate the circumeference of circle
.
Geometry2D.delta
— Methoddelta(v::Vector2D) :: Delta
Given v
, return the difference in x and y as a Delta from v
's tip to origin.
Geometry2D.distance
— Methoddistance(a::Point, b::Point ) :: Unitful.Length
Finds the straight-line distance between a
and b
. (It is nonsensical to ask for the 'distance' of a Delta, rather Deltas have norm().)
Geometry2D.ellipticArcLength
— MethodellipticArcLength(a::Number, b::Number, start::Number, stop::Number)
Calculates the arc length of an ellipse from major axis a
towards minor axis b
between start
and stop
angles, as measured from the major axis a
.
Geometry2D.ellipticArcLength
— MethodellipticArcLength(a::Number, b::Number, angle::Number ) :: Number
Calculates the arc length of an ellipse from major axis a
towards minor axis b
through angle
, measured from a
, via elliptic integral: L = b * elliptic_e( atan(a/b*tan(angle)), 1-a^2/b^2 )
Geometry2D.ellipticArcLength
— MethodellipticArcLength(a::Unitful.Length, b::Unitful.Length, angle::Angle)
Unitful version. Calculates the arc length of an ellipse from major axis a
towards minor axis b
through angle
, measured from major axis a
, via elliptic integral:. L = b * elliptic_e( atan(a/b*tan(angle)), 1-a^2/b^2 )
Geometry2D.hvec2point
— Methodhvec2point(v::Vector{<:Unitful.Length}) :: Point
Convert a 1-terminated vector back into a Point.
Geometry2D.isClockwise
— MethodisClockwise(s::Spiral) :: Bool
Conversely, clockwise implies decreasing angle.
Geometry2D.isCounterClockwise
— MethodisCounterClockwise(s::Spiral) :: Bool
2D Spirals are 'counterclockwise' if of increasing angle, a0
to a1
.
Geometry2D.isDecreasing
— MethodisDecreasing(s::Spiral) :: Bool
Does the radius decrease
Geometry2D.isIncreasing
— MethodisIncreasing(s::Spiral) :: Bool
Does the radius increase?
Geometry2D.isSegmentMutuallyTangent
— MethodisSegmentMutuallyTangent(; cA::Circle, cB::Circle, thA::Radian, thB::Radian, tol::Number=1e-3) :: Bool
Given Circles
circleA
and circleB
, tests whether the points on their edges at angles thA
and thB
define a line segment that is tangent to both circles. tol
is the tolerance on the tangency criterion.
Geometry2D.isSegmentPerpendicularToParallelVectors
— FunctionisSegmentPerpendicularToParallelVectors( vA::Vector2D, vB::Vector2D, tol::Number=1e-3) :: Bool
Tests whether a segment connecting the tips of vA
and vB
is perpendicular to both, which implies parallelity of vA
and vB
. The calculation compares the direction of the cross products of vA
and the tip-connecting segment, and vB
and the segment, that these are within tol
of each other.
Geometry2D.lawOfCosines
— MethodlawOfCosines(legA::Unitful.Length, legB::Unitful.Length, angleAB::Angle) :: Unitful.Length
lawOfCosines(legA::Unitful.Length, legB::Unitful.Length, angleAB::Angle) :: Unitful.Length
For any triangle, finds the length of the unknown legC
from legA
, legB
, and angleAB
between them.
Geometry2D.lawOfSines
— MethodlawOfSines(legA::Unitful.Length, angleBC::Angle, angleCA::Angle) :: Unitful.Length
lawOfSines(; legA::Unitful.Length, angleBC::Angle, angleCA::Angle) :: Unitful.Length
For any triangle with legs A, B, C and angles AB, BC, CA, so that legA
is the open side of angleBC
, finds legB corresponding to angleCA
.
Geometry2D.legHypotenuse2Leg
— MethodlegHypotenuse2Leg( leg::Unitful.Length, hyp::Unitful.Length ) :: Unitful.Length
legHypotenuse2Leg(; leg::Unitful.Length, hyp::Unitful.Length ) :: Unitful.Length
For a right triangle, find the length of the third leg from hypotenuse hyp
and leg
.
Geometry2D.legLeg2Hypotenuse
— MethodlegLeg2Hypotenuse( a::Unitful.Length, b::Unitful.Length ) :: Unitful.Length
legLeg2Hypotenuse(; a::Unitful.Length, b::Unitful.Length ) :: Unitful.Length
For a right triangle, find the length of the hypotenuse from the shorter legs a
and b
.
Geometry2D.normalize
— Methodnormalize( d::Delta ) :: UnitVector2D
Return a UnitVector2D for Delta d
.
Geometry2D.normalize
— Methodnormalize( p::Point ) :: UnitVector2D
Return a UnitVector2D pointing toward Point p
.
Geometry2D.point2hvec
— Methodpoint2hvec(p::Point)
Convert p
into a 1-terminated Vector for multiplication with some homogeneous transformation matrix.
Geometry2D.pointOnCircle
— MethodpointOnCircle( c::Circle, a::Angle ) :: Point
Returns the Point
on c
at angle a
measured from +x.
Geometry2D.radialVector
— MethodradialVector( c::Circle, a::Angle ) :: Vector2D
Returns a Vector2D
with origin at c.center
and tip at angle a
and c.radius
.
Geometry2D.seriesCartesian
— FunctionseriesCartesian(s::Spiral, n::Int=1000)
seriesCartesian(; s::Spiral, n::Int=1000)
Spread n
points over spiral s
, returning an (xs
,ys
) tuple
Geometry2D.seriesPolar
— FunctionseriesPolar(s::Spiral, n::Int=1000)
seriesPolar(; s::Spiral, n::Int=1000)
Spread n
points over spiral s
, returning an (angles
,radii
) tuple.
Geometry2D.toVector
— MethodtoVector( uv::UnitVector ) :: AbstractVector
Convert uv
to a Base.Vector.
KeywordDispatch.kwcall
— MethodPoint(;x::Unitful.Length, y::Unitful.Length)
Keyword constructor for a point on the cartesian plane, measured in x
and y
from the plane's origin.
KeywordDispatch.kwcall
— MethodUnitVector2D(; x::Real, y::Real)
Keyword constructor.
KeywordDispatch.kwcall
— MethodVector2D(;origin::Point, tip::Point)
Keyword constructor for a vector from origin
to tip
.
KeywordDispatch.kwcall
— MethodCircle(; center::Point, radius::Unitful.Length )
A circle having a center::Point
and a radius::Unitful.Length
.
KeywordDispatch.kwcall
— MethodUnitVector(; x::Real, y::Real, z::Real)
A keyword constructor of UnitVectors.
KeywordDispatch.kwcall
— MethodSpiral(; a0::AngleOrReal, a1::AngleOrReal, r0::LengthOrReal, r1::LengthOrReal, pitch::PitchOrReal) = Spiral(a0, a1, r0, r1, pitch)
Keyword create a Spiral with a0
, a1
, r0
, r1
, and pitch
.
KeywordDispatch.kwcall
— MethodSpiral( a0::AngleOrReal, a1::AngleOrReal, r0::LengthOrReal, r1::LengthOrReal )
Keyword create a Spiral, calculating the pitch from a0
, a1
, r0
, and r1
.
KeywordDispatch.kwcall
— MethodSpiral(; a0::Real, a1::Real, r0::Real, r1::Real) = Spiral(a0, a1, r0, r1, calcPitch(a0,a1,r0,r1)::Real )
Keyword create a Spiral, calculating the pitch from a0
[rad], a1
[rad], r0
, and r1
.
LinearAlgebra.norm
— Methodnorm( d::Delta; p=2 ) :: Unitful.Length
Returns the p
-norm of d
.
LinearAlgebra.norm
— Methodnorm( pt::Point; p=2 ) :: Unitful.Length
Returns the p
-norm of pt
.
LinearAlgebra.norm
— Methodnorm( u::UnitVector2D; p=2 ) :: Real
Returns the p
-norm of u
.
LinearAlgebra.norm
— Methodnorm( uv::UnitVector; p=2 ) :: Real
Returns the UnitVector's 2-norm, which should always be 1.
RecipesBase.apply_recipe
— MethodA plot recipe for plotting Circles under Plots.jl.
c = Circle( 3mm,4mm, 5mm )
plot(c) #plot(c, linecolor=:red, ...kwArgs... )
RecipesBase.apply_recipe
— MethodA plot recipe for plotting Points under Plots.jl.
p = Point( 3mm,4mm )
plot(p)