Reference
The following summarizes the documentation of types and methods provided by the TwoDimensional
package. This information is also available from the REPL by typing ?
followed by the name of a method or a type.
Points
TwoDimensional.AbstractPoint
— TypeAbstractPoint{T} <: TwoDimensional.GeometricElement{T}
is the abstract type of objects with at least 2 properties: x
and y
, their respective abscissa and ordinate, both of type T
.
See also Point
.
TwoDimensional.AbstractPoint2D
— TypeTwoDimensional.AbstractPoint2D{T}
is an alias for TwoDimensional.AbstractPoint{T}
.
TwoDimensional.Point
— Typepnt = Point{T}(x,y)
pnt = Point{T}((x,y))
pnt = Point{T}(; x=..., y=...)
pnt = Point{T}(; r=..., θ=...)
construct a point given its Cartesian coordinates (x,y)
(in the 3 first examples) or its polar coordinates (in the last example) with r
the distance to the origin and θ
the counterclockwise angle relative to x
-axis. Parameter T
is the type used to store coordinates, it may be omitted.
Note that, in TwoDimensional
, x
and y
respectively correspond to the 1st and 2nd dimensions of 2-dimensional arrays.
A point may be multiplied or divided by a scalar to scale its coordinates. The addition (resp. subtraction) of two points adds (resp. subtracts) their coordinates.
Points have the following properties reflecting the keywords accepted by their constructor:
pnt.x -> x::T
pnt.y -> y::T
Points are indexable iterators:
length(pnt) -> 2
firstindex(pnt) -> 1
lastindex(pnt) -> 2
pnt[1] -> pnt.x
pnt[2] -> pnt.y
first(pnt) -> pnt.x
last(pnt) -> pnt.y
Tuple(pnt) -> (pnt.x, pnt.y)
The coordinates of pnt
can thus be retrieved by:
x, y = pnt
the polar coordinates of the point can be retrieved by hypot(pnt) -> r
, abs(pnt) -> r
, or norm(pnt) -> r
, and by atan(pnt) -> θ
.
See also AbstractPoint
, Rectangle
, and BoundingBox
.
TwoDimensional.Point2D
— TypeTwoDimensional.Point2D{T}
is an alias for TwoDimensional.Point{T}
.
TwoDimensional.PointLike
— TypeTwoDimensional.PointLike
is the union of types of objects that can be converted into a TwoDimensional.Point
.
The Point
constructor can build an instance from any argument of these types. Accessors TwoDimensional.get_x
and TwoDimensional.get_y
may be used on objects of such type to retrieve their abscissa and ordinate.
TwoDimensional.distance
— Functiondistance(A, B)
yields the Euclidean distance between the 2 points A
and B
.
TwoDimensional.get_x
— FunctionTwoDimensional.get_x(pnt::PointLike) -> x
yields the abscissa of point-like object pnt
.
See also TwoDimensional.get_y
, TwoDimensional.get_xy
, and TwoDimensional.PointLike
.
TwoDimensional.get_xy
— FunctionTwoDimensional.get_xy(pnt::PointLike) -> (x::T, y::T)
yields a 2-tuple with the abscissa x
and ordinate y
of point-like object pnt
. This is equivalent to, but more economical than, (get_x(pnt),get_y(pnt))
.
See also TwoDimensional.get_x
, TwoDimensional.get_y
and TwoDimensional.PointLike
.
TwoDimensional.get_y
— FunctionTwoDimensional.get_y(pnt::PointLike) -> y
yields the ordinate of point-like object pnt
.
See also TwoDimensional.get_x
, TwoDimensional.get_xy
, and TwoDimensional.PointLike
.
TwoDimensional.point_type
— FunctionTwoDimensional.point_type(arg)
yields the equivalent point type of arg
.
If arg
is a point-like object (or the type of such an object) the result is the point type of arg
when converted to a Point
.
If arg
is a tuple of point-like objects, the result is the promoted type of the conversion of each arg
to a Point
.
LinearAlgebra.cross
— Methodcross(a::Point, b::Point)
a * b
yields the cross product (a.k.a. vector product or directed area product) of the two points a
and b
which is given by:
a.x*b.y - a.y*b.x
LinearAlgebra.dot
— Methoddot(a::Point, b::Point)
a ⋅ b
yields the dot product (a.k.a. scalar product or inner product) of the two points a
and b
which is given by:
a.x*b.x + a.y*b.y
Rectangles
TwoDimensional.Rectangle
— Typerect = Rectangle{T}(start, stop)
rect = Rectangle{T}((x0,y0), (x1,y1))
rect = Rectangle{T}(; start=..., stop=...)
rect = Rectangle{T}(; x0=..., x1=..., y0=..., y1=...)
construct a rectangular rectangle with edges aligned with the Cartesian axes and given the coordinates of 2 opposite corners, start
and stop
, whose coordinates, (x0,y0)
and (x1,y1)
, may be specified as points, as 2-tuples, as 2-dimensional Cartesian indices, or by keywords. Parameter T
is the type used to store coordinates, it may be omitted.
Rectangles have the following properties reflecting the keywords accepted by their constructor:
rect.x0 -> min(x0, x1)::T
rect.x1 -> max(x0, x1)::T
rect.y0 -> min(y0, y1)::T
rect.y1 -> max(y0, y1)::T
rect.start -> start::Point{T}
rect.stop -> stop::Point{T}
Note that the coordinates are sorted. A rectangle is never empty and contains at least a single point.
Rectangles are indexable iterators:
length(rect) -> 2
firstindex(rect) -> 1
lastindex(rect) -> 2
rect[1] -> rect.start
rect[2] -> rect.stop
first(rect) -> rect.start
last(rect) -> rect.stop
Tuple(rect) -> (rect.start, rect.stop)
Hence, the parameters of a rectangle can be retrieved by:
start, stop = rect
(x0, y0), (x1, y1) = rect
See also Point
, BoundingBox
, interior
, and exterior
.
TwoDimensional.Rectangle2D
— TypeTwoDimensional.Rectangle2D{T}
is an alias for TwoDimensional.Rectangle{T}
.
TwoDimensional.RectangleLike
— TypeTwoDimensional.RectangleLike
is the union of types of objects that may be used to specify a rectangle in TwoDimensional
package.
The Rectangle
constructor can build an instance from any argument of these types.
Circles
TwoDimensional.Circle
— Typecirc = Circle{T}(center::Point, radius)
circ = Circle{T}((x, y), radius)
circ = Circle{T}(; center=..., radius=...)
construct a circle of given center
and radius
or diameter
. The center may be specified by its coordinates (x,y)
along the Cartesian axes. Parameter T
is the type used to store coordinates, it may be omitted.
Circles have the following properties reflecting the keywords accepted by their constructor (diameter
is provided for convenience):
circ.center -> center::Point{T}
circ.radius -> radius::T
circ.diameter -> 2*circ.radius
Circles can be iterated to retrieve their center and their radius (in that order):
center, radius = circ
(x0, y0), radius = circ
See also Point
, BoundingBox
.
TwoDimensional.Circle2D
— TypeTwoDimensional.Circle2D{T}
is an alias for TwoDimensional.Circle{T}
.
TwoDimensional.CircleLike
— TypeTwoDimensional.CircleLike
is the union of types of objects that may be used to specify a circle in TwoDimensional
package.
The Circle
constructor can build an instance from any argument of these types.
Polygons
TwoDimensional.Polygon
— Typepoly = Polygon{T}(pnts...)
poly = Polygon{T}(pnts)
construct a polygon with vertices given by point-like objects pnts...
or vector or tuple of point-like objects pnts
. Parameter T
is the type used to store coordinates, if omitted, a common coordinate type is automatically inferred.
The vertices of a polygon may be stored as a tuple or as a vector. Call values(poly)
to get the object backing the storage of the vertices of the polygon poly
. The method Tuple(poly)
yields a tuple of the vertices of poly
. The method vec(poly)
yields a vector of the vertices of the polygon which may be shared with poly
. Call collect(poly)
to make an independent copy of the vector of vertices.
Vertices are directly accessible by indexing the polygon object:
length(poly) # number of vertices
firstindex(poly) # index of first vertex
lastindex(poly) # index of last vertex
poly[i] # i-th vertex (a point)
first(poly) # first vertex
last(poly) # last vertex
values(poly) # vertices stored by `poly`
vec(poly) # vector of vertices
Vector(poly) # vector of vertices
Tuple(poly) # tuple of vertices
See also Point
, TwoDimensional.vertices
, and BoundingBox
.
TwoDimensional.Polygon2D
— TypeTwoDimensional.Polygon2D{T}
is an alias for TwoDimensional.Polygon{T}
.
TwoDimensional.PolygonLike
— TypeTwoDimensional.PolygonLike
is the union of types of objects that can be converted into a TwoDimensional.Polygon
. These are tuples or vectors of point-like objects.
The Polygon
constructor can build an instance from any argument of these types. Accessors TwoDimensional.get_x
and TwoDimensional.get_y
may be used on objects of such type to retrieve their abscissa and ordinate.
TwoDimensional.cross3
— FunctionTwoDimensional.cross3(A::Point, B::Point, C::Point) -> val
yields the cross vectorial product of AB
by AC
.
The returned value can be used to determine the position of point C
relatively to the infinite line defined by (A,B)
:
- if
val > 0
, thenC
is left of the line throughA
andB
; - if
val = 0
, thenC
is on the line throughA
andB
; - if
val < 0
, thenC
is right of the line throughA
andB
.
See: Algorithm 1 "Area of Triangles and Polygons"
TwoDimensional.crossing_number_test
— FunctionTwoDimensional.crossing_number_test(P::Point, V::List{<:Point}) -> bool
yields whether point P
is inside the polygon defined by vertices V
according to the crossing number method by Franklin (2000).
TwoDimensional.winding_number_test
— FunctionTwoDimensional.winding_number_test(P::Point, V::List{<:Point}) -> bool
yields whether point P
is inside the polygon defined by vertices V
according to the winding number method by Dan Sunday ("Inclusion of a Point in a Polygon", 2001).
Bounding-Boxes
TwoDimensional.BoundingBox
— Typebox = BoundingBox{T}(start, stop)
box = BoundingBox{T}((xmin,ymin), (xmax,ymax))
box = BoundingBox{T}(; start=..., stop=...)
box = BoundingBox{T}(; xmin=..., xmax=..., ymin=..., ymax=...)
construct a rectangular bounding-box with edges aligned with the Cartesian axes and given the coordinates of 2 opposite corners, start
and stop
, whose coordinates, (xmin,ymin)
and (xmax,ymax)
, may be specified as points, as 2-tuples, as 2-dimensional Cartesian indices, or by keywords. Parameter T
is the type used to store coordinates, it may be omitted.
Another possibility is:
BoundingBox{T}()
to build an empty bounding-box for coordinate type T
.
Bounding-boxes have the following properties reflecting the keywords accepted by their constructor:
box.xmin -> xmin::T
box.xmax -> xmax::T
box.ymin -> ymin::T
box.ymax -> ymax::T
box.start -> start::Point{T}
box.stop -> stop::Point{T}
A bounding-box is assumed to contain all points of coordinates (x,y)
such that xmin ≤ x ≤ xmax
and ymin ≤ y ≤ ymax
. If xmin > xmax
or ymin > ymax
, the bounding-box is considered as empty. This can be checked with isempty(box)
.
Boxes are used to represent grid cells and bounding-boxes of other geometric shape. Use TwoDimensional.Rectangle
if you want to define rectangular masks.
Bounding-boxes are indexable iterators:
length(box) -> 2
firstindex(box) -> 1
lastindex(box) -> 2
box[1] -> box.start
box[2] -> box.stop
first(box) -> box.start
last(box) -> box.stop
Tuple(box) -> (box.start, box.stop)
Hence, the parameters of a bounding-box can be retrieved by:
start, stop = box
(xmin, ymin), (xmax, ymax) = box
BoundingBox{T}(obj)
yields the bounding-box of the geometric object obj
. If the coordinate type T
is not provided, T = coord_type(obj)
is assumed.
This can be used to compute the union or the intersection of the bounding-boxes of objects:
mapreduce(BoundingBox, ∪, (obj1, obj2, obj3, ...))
mapreduce(BoundingBox, ∩, [obj1, obj2, obj3, ...])
BoundingBox(f, A::AbstractMatrix)
yields the minimal bounding-box of the entries of A
such that f(A[i,j])
is true. This can be used to extract this rectangular region:
A[BoundingBox(f, A)]
If A
is a matrix of Booleans, f
is assumed to be the identity if not specified.
TwoDimensional.BoundingBox2D
— TypeTwoDimensional.BoundingBox2D{T}
is an alias for TwoDimensional.BoundingBox{T}
.
TwoDimensional.BoundingBoxLike
— TypeTwoDimensional.BoundingBoxLike
is the union of types of objects that may be used to specify a bounding-box in TwoDimensional
package.
The BoundingBox
constructor can build an instance from any argument of these types.
TwoDimensional.interior
— Functioninterior([T,] box)
yields the largest bounding-box with integer valued bounds and which is contained by the bounding-box box
. Optional argument T
is to specify the type of the result or the type of the coordinates of the result which is the same as box
by default.
TwoDimensional.exterior
— Functionexterior([T,] box)
yields the smallest bounding-box with integer valued bounds and which contains the bounding-box box
. Optional argument T
is to specify the type of the result or the type of the coordinates of the result which is the same as box
by default.
TwoDimensional.grow
— FunctionTwoDimensional.grow(box, dx, dy=dx)
yields a new bounding-box object corresponding to the input box
object with 1st and 2nd dimensions respectively grown by dx
and dy
.
Note that the algebraic (not absolute) values of dx
and dy
are applied. Hence, if dx
and dy
are both negative, the bounding-box is effectively shrunk by abs(dx)
and abs(dy)
.
See also TwoDimensional.shrink
.
TwoDimensional.shrink
— FunctionTwoDimensional.shrink(box, dx, dy=dx)
yields a new bounding-box object corresponding to the input box
object with 1st and 2nd dimensions respectively shrunk by dx
and dy
.
Note that the algebraic (not absolute) values are applied. Hence, if dx
and dy
are both negative, the bounding-box is effectively grown by abs(dx)
and abs(dy)
.
See also TwoDimensional.grow
.
Coordinate Type
TwoDimensional.coord_type
— Functioncoord_type(A) -> T
yields the coordinate type of a geometrical object or of its type. With several arguments:
coord_type(A...) -> T
or if single argument a tuple or a vector of geometrical objects, the promoted coordinate type is returned.
TwoDimensional.convert_coord_type
— Functionconvert_coord_type(T::Type, obj::GeometricObject)
GeometricObject{T}(obj)
convert the coordinate type of a geometrical object obj
to T
. If the coordinate type of obj
is already T
, obj
itself is returned.
convert_coord_type(T::Type, objs::GeometricObject...) -> objs′
yields the tuple of geometric objects objs...
converted to the coordinate type T
.
TwoDimensional.promote_coord_type
— Functionpromote_coord_type(objs...)
converts all arguments objs...
to a common coordinate type and return them as a tuple.
Affine 2D Coordinate Transforms
TwoDimensional.AffineTransform
— TypeAffineTransform(Axx, Axy, Ax, Ayx, Ayy, Ay) -> A
yields a callable object implementing a 2-dimensional affine transform such that:
A(x, y) -> (Axx*x + Axy*y + Ax, Ayx*x + Ayy*y + Ay)
A((x, y)) -> (Axx*x + Axy*y + Ax, Ayx*x + Ayy*y + Ay)
A(pnt::Point) -> Point(A(pnt.x, pnt.y))
A(pnt::CartesianIndex{2}) -> Point(A(pnt[1], pnt[2]))
The constructor optionally takes one or three parameters:
AffineTransform{T}(Axx, Axy, Ax, Ayx, Ayy, Ay)
AffineTransform{T,R,S}(Axx, Axy, Ax, Ayx, Ayy, Ay)
where T
is the concrete floating-point type of the coefficients, R
is the type for storing the factors Axx
, Axy
, Ayx
, and Ayy
, and S
is the type for storing the offsets Ax
and Ay
. The bare types of R
and S
must be T
but they may have units.
Changing the floating-point type of an existing 2-dimensional affine transform A
can be done by one of:
B = AffineTransform{T}(A)
B = convert(AffineTransform{T}, A)
B = convert_bare_type(T, A)
B = convert_real_type(T, A)
B = convert_floating_point_type(T, A)
the 3 last assume using TypeUtils
. Using TypeUtils
API, the floating-point type T
can be retrieved by either of bare_type(A)
, realtype(A), or
floatingpoint_type(A)with
A` a 2-dimensional affine transform instance or type.
Applying the 2-dimensional affine transform A
can be done by:
(xp, yp) = A(x,y) # apply affine transform A to coordinates (x,y)
(xp, yp) = A*(x,y) # idem
(xp, yp) = A((x,y)) # idem
A(Point(x,y)) -> Point(xp, yp)
A*Point(x,y) -> Point(xp, yp)
C = compose(A, B, ...) # compose 2 (or more) transforms, apply C = apply B then A
C = A∘B # compose A and B
C = A*B # idem
B = translate(x, y, A) # B = apply A then translate by (x,y)
B = translate(pnt, A) # idem with pnt = (x,y)
B = pnt + A # idem
B = translate(A, x, y) # B = translate by (x,y) then apply A
B = translate(A, pnt) # idem with pnt = (x,y)
B = A + pnt # idem
B = rotate(θ, A) # B = apply A then rotate by angle θ
C = rotate(A, θ) # C = rotate by angle θ then apply A
B = scale(ρ, A) # B = apply A then scale by ρ
B = ρ*A # idem
C = scale(A, ρ) # C = scale by ρ then apply A
C = A*ρ # idem
B = inv(A) # reciprocal coordinate transform
C = A/B # right division, same as: C = A ∘ inv(B)
C = A\B # left division, same as: C = inv(A) ∘ B
"∘
" can be typed by \circ<tab>
.
AffineTransform() -> Id
AffineTransform{T}() -> Id
AffineTransform{T,R,S}() -> Id
yields a 2-dimensional affine transform corresponding to the identity (up to possible change of type and units). Parameter T
is the floating-point type of the coefficients (Float64
by default). Parameters R
and S
are the types of the factors and of the offsets (by default both are assumed to be T
). These are shortcuts to:
AffineTransform(oneunit(R),zero(R),zero(S), zero(R),oneunit(R),zero(S))
TwoDimensional.AffineTransform2D
— TypeTwoDimensional.AffineTransform2D{T,R,S}
is an alias for TwoDimensional.AffineTransform{T,R,S}
.
TwoDimensional.compose
— FunctionTwoDimensional.compose(A::AffineTransform, B::AffineTransform)
yields the affine transform which combines the two affine transforms A
and B
, that is the affine transform which applies B
and then A
. Composition is accessible via: A*B
or A∘B
("∘
" can be typed by \circ<tab>
).
It is possible to compose more than two affine transforms. For instance, compose(A,B,C)
yields the affine transform which applies C
then B
, then A
.
TwoDimensional.factors_type
— FunctionTwoDimensional.factors_type(A) -> R
yields the type of the factors of the 2-dimensional affine transform A
. The factors of A
are the coefficients A.xx
, A,xy
, A.yx
, and A.yy
. Argument may also be the type of an affine transform.
See also: offsets_type
.
TwoDimensional.offsets_type
— FunctionTwoDimensional.offsets_type(A) -> R
yields the type of the offsets of the 2-dimensional affine transform A
. The offsets of A
are the coefficients A.x
and A.y
. Argument may also be the type of an affine transform.
See also: factors_type
.
TwoDimensional.rotate
— FunctionB = rotate(θ, A)
C = rotate(A, θ)
yield 2-dmensional affine transforms B
and C
such that:
B(x,y) = (R∘A)(x,y) = R(A(x,y))
C(x,y) = (A∘R)(x,y) = A(R(x,y))
where R
implements rotation by angle θ
counterclockwise around the origin at coordimates (0,0)
. The rotation angle θ
is assumed to be in radians if it has no units.
See also: AffineTransform
, scale
, translate
.
TwoDimensional.scale
— FunctionB = scale(ρ, A)
B = ρ*A
C = scale(A, ρ)
C = A*ρ
yield 2-dimensional affine transforms B
and C
such that:
B(x,y) -> ρ*A(x,y)
C(x,y) -> A(ρ*x,ρ*y)
See also: AffineTransform
, rotate
, translate
.
TwoDimensional.translate
— FunctionB = translate(x, y, A)
B = translate((x,y), A)
B = translate(pnt, A)
B = (x,y) + A
B = pnt + A
perform a left-translation of the 2-dimensional affine transform A
. Applying B
yields the same result as if coordinates (x,y)
are added to the output of A
. Here, pnt = Point(x,y)
or pnt = CartesianIndex(x,y)
.
C = translate(A, x, y)
C = translate(A, (x,y))
C = translate(A, pnt)
C = A + (x,y)
C = A + pnt
perform a right-translation of the 2-dimensional affine transform A
. Applying B
yields the same result as if coordinates (x,y)
are added to the input of A
.
See also: AffineTransform
, rotate
, scale
.
TwoDimensional.ldiv
— FunctionA\B -> inv(A) ∘ B
TwoDimensional.ldiv(A::AffineTransform, B::AffineTransform) -> inv(A) ∘ B
yield the "left division" of the affine transform A
by the affine transform B
.
It is an abuse of notation to have A\B
being a shortcut to inv(A) ∘ B
but this is in-line with the overloading of *
such that A * B -> A ∘ B
. This function is motivated by the fact that it takes only 29 flops whereas inv(A) ∘ B
takes 37 flops (17 flops for inv
and 20 flops for ∘
).
TwoDimensional.rdiv
— FunctionA/B -> A ∘ inv(B)
TwoDimensional.rdiv(A::AffineTransform, B::AffineTransform) -> A ∘ inv(B)
yield the "right division" of the affine transform A
by the affine transform B
.
It is an abuse of notation to have A/B
being a shortcut to A ∘ inv(B)
but this is in-line with the overloading of *
such that A * B -> A ∘ B
. This function is motivated by the fact that it takes only 29 flops whereas inv(A) ∘ B
takes 37 flops (17 flops for inv
and 20 flops for ∘
).
Masks
TwoDimensional.Mask
— TypeTwoDimensional.Mask(elems...)
TwoDimensional.Mask{T}(elems...)
build a composite mask consisting in the ordered list of mask elements elems...
. Optional type parameter T
is the coordinate type of the masks elements. All arguments are converted as needed to have this coordinate type. If T
is not specified, it is inferred by promoting the coordinate types of the mask elements.
A mask can be moved, scaled, rotated, etc., the coordinate type of its elements may be converted to another type.
Masks with a large number of elements should be created with a vector of mask elements.
TwoDimensional.MaskElement
— TypeTwoDimensional.MaskElement(shape::ShapeElement; opaque::Bool)
builds a simple mask whose boundaries are defined by shape
and which is opaque (i.e., an obscuration) if opaque
is true and transparent (i.e., an aperture) otherwise.
TwoDimensional.MaskElement2D
— TypeTwoDimensional.MaskElement2D{T,S}
is an alias for TwoDimensional.MaskElement{T,S}
. T
is the coordinate type, S
is the type of the elementary geometrical object defining the shape of the mask.
TwoDimensional.Overlap
— TypeTwoDimensional.Overlap(pxl, obj)
yields the overlapping of pixel pxl
with shape object obj
. pxl
may be a point, a bounding-box, or a rectangle. Returned value is:
INSIDE
ifpxl
is fully inside the boundaries ofobj
;OUTSIDE
ifpxl
is fully outside the boundaries ofobj
;PARTIAL
ifpxl
straddles some boundaries ofobj
.
TwoDimensional.apply_mask
— FunctionTwoDimensional.apply_mask(Aᵢₙ, args...; kwds...) -> Aₒᵤₜ
multiplies the values of the input 2-dimensional array Aᵢₙ
by a mask defined by arguments args...
and keywords kwds...
and returns the resulting output array Aₒᵤₜ
. The input array Aᵢₙ
is left unmodified, method TwoDimensional.apply_mask!
may be used for in-place operation. See TwoDimensional.forge_mask
for how to define a mask.
TwoDimensional.apply_mask!
— FunctionTwoDimensional.apply_mask!(A, args...; kwds...) -> A
multiplies in-place the 2-dimensional array A
by a mask defined by arguments args...
and keywords kwds...
and returns A
. See TwoDimensional.apply_mask
for an out-of-place version and for details.
TwoDimensional.forge_mask
— FunctionTwoDimensional.forge_mask(A::AbstractMatrix, msk; kwds...)
TwoDimensional.forge_mask(A::AbstractMatrix, objs...; kwds...)
yield a 2-dimensional array whose entries given the transmission by the mask msk
for the corresponding entry in A
. The mask may also be specified by the list objs...
of elementary mask objects. The coordinates of the mask are assumed to be given in fractional Cartesian indices for A
.
TwoDimensional.forge_mask([T,] X, Y, msk; kwds...) -> arr
TwoDimensional.forge_mask([T,] X, Y, elems...; kwds...) -> arr
yield a 2-dimensional array filled with transmission values computed for the mask msk
at coordinates given by X
and Y
along the 1st and 2nd dimensions. The mask may also be specified by combining elementary mask objects elems...
. Optional argument T
is to specify the element type of the result.
The following painting algorithm is used:
The mask array is initially filled with the transparent or opaque value depending on whether the first component is opaque or transparent.
Then, for each component in turn, the cells of the mask array that are inside the component are painted with the opaque or transparent value depending on whether the component is opaque or transparent.
The cells of the mask array overlapping the boundaries of the topmost components are set to an intermediate value between the opaque and transparent ones and (approximately) proportionally to the transparent fraction of the cell area.
Note that the order of the components of the mask is relevant: an aperture component drills holes in the previously opaque parts while an obscuration hides previously transparent parts.
Keyword antialiasing
can be set to specify the number of sub-cells (per side) to determine the transmission of grid cells partially overlapping the boundary delimiting the mask components. By default, antialiasing = 11
. If antialiasing ≤ 1
, a 50% transmission is assumed for partially overlapping cells (sharp edges); otherwise, overlapping cells are subdivided in antialiasing × antialiasing
sub-cells to estimate their partial transmission.
Keywords opaque
and transparent
can be used to specify the values of the the respectively opaque and transparent parts of the mask. Values of partially opaque/transparent parts will be interpolated between these.
Keyword multithreading
specifies whether to use multiple threads for the computations.
Example to forge a mask representing the primary mirror of a telescope with its spider arms:
using TwoDimensional
using Unitful: μm, mm, cm, m
center = Point(0mm,0mm) # central position
outer_radius = 1.8m
inner_radius = outer_radius/3
spider_thickness = 2.3cm # thickness of spider arms
grid_step = 2.0mm # grid sampling step
spider_length = 2*(outer_radius + grid_step) # length of spider arms
margin = 5 # margin in pixels
xmin = floor(Int, (center.x - outer_radius)/grid_step) - margin
ymin = floor(Int, (center.y - outer_radius)/grid_step) - margin
xmax = ceil(Int, (center.x + outer_radius)/grid_step) + margin
ymax = ceil(Int, (center.y + outer_radius)/grid_step) + margin
X = (xmin:xmax)*grid_step # coordinates along 1st dimension
Y = (ymin:ymax)*grid_step # coordinates along 2nd dimension
voff = Point(spider_thickness, spider_length)
hoff = Point(spider_length, spider_thickness)
mask = forge_mask(
X, Y,
circular_aperture(center, outer_radius), # aperture
circular_obscuration(center, inner_radius), # central obscuration
rectangular_obscuration(center - voff/2, center + voff/2),
rectangular_obscuration(center - hoff/2, center + hoff/2))
TwoDimensional.forge_mask!
— FunctionTwoDimensional.forge_mask!(dst, [X, Y,] msk; kwds...) -> dst
TwoDimensional.forge_mask!(dst, [X, Y,] elems...; kwds...) -> dst
In-place version of TwoDimensional.forge_mask
, it overwrites the destination array dst
with the mask and returns it. If coordinates X
and Y
along the axes of dst
are not specified, (X, Y) = axes(dst)
is assumed.
TwoDimensional.grid_step
— FunctionTwoDimensional.grid_step(x::AbstractVector) -> stp
yields the step along a vector of coordinates, throwing an error if the increment between successive values of x
is not positive or not uniform.
TwoDimensional.interpolate
— FunctionTwoDimensional.interpolate(a, b, f) -> x
yields linearly interpolated value between a
and b
by a fraction f
. If f
is a dimensionless factor, then the result is:
x = a + f*(b - a)
otherwise, e.g. if f
has units, the result is:
x = (oneunit(f) - f)*a + f*b
In any case, a
and b
are promoted to the same type.
Hence, if f
is a real, then f = 0
yields a
while f = 1
yields b
.
TwoDimensional.is_opaque
— FunctionTwoDimensional.is_opaque(msk)
yields whether mask element msk
is opaque.
TwoDimensional.is_transparent
— FunctionTwoDimensional.is_transparent(msk)
yields whether mask element msk
is transparent.
TwoDimensional.aperture
— FunctionTwoDimensional.aperture(obj)
yields a transparent mask element of same shape as obj
.
TwoDimensional.obscuration
— FunctionTwoDimensional.obscuration(obj)
yields an opaque mask element of same shape as obj
.
TwoDimensional.rectangular_aperture
— FunctionTwoDimensional.rectangular_aperture(args...; kwds...)
yields an elementary mask object representing a rectangular aperture defined by given arguments args...
and keywords kwds...
and whose edges are aligned with the Cartesian axes. See TwoDimensional.Rectangle
constructor for possible arguments and keywords. A rectangular aperture is a transparent rectangular mask.
TwoDimensional.rectangular_obscuration
— FunctionTwoDimensional.rectangular_obscuration(args...; kwds...)
yields an elementary mask object representing a rectangular obscuration defined by given arguments args...
and keywords kwds...
and whose edges are aligned with the Cartesian axes. See TwoDimensional.Rectangle
constructor for possible arguments and keywords. A rectangular obscuration is an opaque rectangular mask.
TwoDimensional.circular_aperture
— FunctionTwoDimensional.circular_aperture(args...; kwds...)
yields an elementary mask object representing a circular aperture defined by given arguments args...
and keywords kwds...
. See TwoDimensional.Circle
constructor for possible arguments and keywords. A circular aperture is a transparent circular mask.
TwoDimensional.circular_obscuration
— FunctionTwoDimensional.circular_obscuration(args...; kwds...)
yields an elementary mask object representing a circular obscuration defined by given arguments args...
and keywords kwds...
. See TwoDimensional.Circle
constructor for possible arguments and keywords. A circular obscuration is an opaque circular mask.
TwoDimensional.polygonal_aperture
— FunctionTwoDimensional.polygonal_aperture(args...; kwds...)
yields an elementary mask object representing a polygonal aperture defined by given arguments args...
and keywords kwds...
. See TwoDimensional.Polygon
constructor for possible arguments and keywords. A polygonal aperture is a transparent polygonal mask.
TwoDimensional.polygonal_obscuration
— FunctionTwoDimensional.polygonal_obscuration(args...; kwds...)
yields an elementary mask object representing a polygonal obscuration defined by given arguments args...
and keywords kwds...
. See TwoDimensional.Polygon
constructor for possible arguments and keywords. A polygonal obscuration is an opaque polygonal mask.
Other Public Methods
TwoDimensional.area
— FunctionTwoDimensional.area(obj)
yields the area of the geometric object obj
.
TwoDimensional.center
— Functioncenter(obj::GeometricObject) -> c::Point
yields the central point of the geometric object obj
. For a polygon, the center of gravity of the vertices is returned.
TwoDimensional.radius
— FunctionTwoDimensional.radius(obj::GeometricObject)
yields the radius of the geometric object obj
. The result is the radius of the smallest circle enclosing the object.
For circle-like and point-like objects with integer coordinate type, the radius is also integer. For all other geometric objects, the raius is floating-point.
TwoDimensional.vertices
— FunctionTwoDimensional.vertices(obj)
yields the vertices defining the vertex-based graphical object obj
. The result is a tuple or a vector of points.
Base.floor
— Methodfloor([T,] obj)
applies the floor
function to the coordinates of the vertices defining the vertex-based geometric object obj
and returns an object of the same kind built with the resulting vertices. Optional argument T
can be the type of the returned object or the type of the coordinates for the returned object.
Base.ceil
— Methodceil([T,] obj)
applies the ceil
function to the coordinates of the vertices defining the vertex-based geometric object obj
and returns an object of the same kind built with the resulting vertices. Optional argument T
can be the type of the returned object or the type of the coordinates for the returned object.
Base.round
— Methodround([T,] obj, [r::RoundingMode])
applies the round
function to the coordinates of the vertices defining the vertex-based geometric object obj
and returns an object of the same kind built with the resulting vertices. Optional argument T
can be the type of the returned object or the type of the coordinates for the returned object. Rounding mode may be specified by optional argument r
, the default being the same as the round
method for a scalar value.
Base.vec
— Methodvec(poly::TwoDimensional.Polygon)
yields a vector of the vertices of the polygon poly
.
Call collect(poly)
to make an independent copy of the vector of vertices.
Internal Methods and Types
TwoDimensional.VertexBasedObject
— TypeTwoDimensional.VertexBasedObject{T}
is the union of types of objects defined by their vertices and with coordinate type T
.
See also TwoDimensional.apply
.
TwoDimensional.apply
— FunctionTwoDimensional.apply(f, obj)
applies function f
to each part of geometric object obj
and rebuild an object of the same kind with the result. Here f
is supposed to be a function implementing an elementary geometric operation such as moving, scaling, etc. the geometric object obj
.
If obj
is a bounding-box, keyword, swap
(default false
) specifies whether to swap the first and last end-points of the box.
See also TwoDimensional.elements
and TwoDimensional.VertexBasedObject
.
TwoDimensional.apply(f, g=f, A::AffineTransform)
applies functions f
and g
respectively to each factors and each offsets of the affine tranform A
and rebuild an affine transform with the resulting values.
TwoDimensional.geometric_properties
— FunctionTwoDimensional.geometric_properties(poly) -> prop
yields a named tuple with the geometric properties of the polygon poly
:
prop.singular # `true` if successive polygon vertices are not distinct
prop.convex # `true` if polygon is convex
prop.direct # `true` if vertices are ordered with direct trigonometric
# orientation (anti-clockwise)
TwoDimensional.is_convex
— FunctionTwoDimensional.is_convex(obj) -> bool
yields whether the geometric object obj
is convex.
TwoDimensional.is_nothing
— FunctionTwoDimensional.is_nothing(x)
TwoDimensional.is_nothing(x, y...)
yield whether x
is nothing
and, if other arguments y...
are specified, that all other y...
are nothing
.
See also TwoDimensional.is_nothing
.
TwoDimensional.is_something
— FunctionTwoDimensional.is_something(x)
TwoDimensional.is_something(x, y...)
yield whether x
is not nothing
and, if other arguments y...
are specified, that none of the other y...
is nothing
.
See also TwoDimensional.is_nothing
.
TwoDimensional.elements
— FunctionTwoDimensional.elements(obj::GeometricElement)
yields the individual elements of elementary geometric obj
from which it can be re-built without ambiguities. For example, for a point pnt
:
Point(elements(pnt)...) === pnt
Point(elements(pnt)) === pnt
both hold.
Geometrical objects that have homogeneous elements (see TwoDimensional.VertexBasedObject
) extend the Base.Tuple
method to return these elements, the Base.getindex
method to directly index among these elements, and the TwoDimensional.apply
method.
TwoDimensional.shape
— FunctionTwoDimensional.shape(obj)
yields the elementary geometric object defining the shape of obj
. The result is obj
itself if it is an elementary geometric object.