A Frame2d
has an origin point and a pair of X and Y directions (which are
always perpendicular to each other). It can be thought of as:
relativeTo
and placeIn
functions that convert values of that type from global
coordinates to local coordinates in a particular frame, and vice versa.Frame2d
could be
used to define the position and orientation of a spaceship in a 2D game.
Movement of the ship would then be done by translating and rotating the
frame.Geometry.Types.Frame2d units coordinates defines
The type parameters of a Frame2d
indicate what units and coordinate
systems it's defined in, and what coordinate system (if any) it itself defines.
A concrete Frame2d
type might look like
type alias Frame =
Frame2d Meters World { defines : Local }
which can be read as "a Frame2d
defined in meters in world coordinates, which
itself defines local coordinates". For frames that don't define a local
coordinate system, you could use
type alias Frame =
Frame2d Meters World {}
Many functions in this module don't care about the third type argument (whether
it's a record with a defines
field like in the first example, an empty record
like in the second example, or even something else entirely) but functions like
placeIn
and relativeTo
expect the { defines : localCoordinates }
pattern.
atOrigin : Frame2d units coordinates defines
The global XY frame, centered at the origin.
Frame2d.originPoint Frame2d.atOrigin
--> Point2d.origin
Frame2d.xDirection Frame2d.atOrigin
--> Direction2d.x
Frame2d.yDirection Frame2d.atOrigin
--> Direction2d.y
atPoint : Point2d units coordinates -> Frame2d units coordinates defines
Construct a frame aligned with the global XY frame but with the given origin point.
frame =
Frame2d.atPoint (Point2d.meters 2 3)
Frame2d.originPoint frame
--> Point2d.meters 2 3
Frame2d.xDirection frame
--> Direction2d.x
Frame2d.yDirection frame
--> Direction2d.y
withAngle : Angle -> Point2d units coordinates -> Frame2d units coordinates defines
Construct a frame with the given angle and origin point. The angle is the amount the returned frame will be rotated relative to the global XY frame, or equivalently the angle of the frame's X direction;
Frame2d.withAngle angle point
is equivalent to
Frame2d.withXDirection
(Direction2d.fromAngle givenAngle)
point
withXDirection : Direction2d coordinates -> Point2d units coordinates -> Frame2d units coordinates defines
Construct a frame with the given X axis direction, having the given origin point. The Y axis direction will be constructed by rotating the given X direction 90 degrees counterclockwise:
frame =
Frame2d.withXDirection (Direction2d.degrees 30)
(Point2d.meters 2 3)
Frame2d.yDirection frame
--> Direction2d.degrees 120
withYDirection : Direction2d coordinates -> Point2d units coordinates -> Frame2d units coordinates defines
Construct a frame with the given Y axis direction, having the given origin point. The X axis direction will be constructed by rotating the given Y direction 90 degrees clockwise:
frame =
Frame2d.withYDirection (Direction2d.degrees 30)
(Point2d.meters 2 3)
Frame2d.xDirection frame
--> Direction2d.degrees -60
fromXAxis : Axis2d units coordinates -> Frame2d units coordinates defines
Construct a Frame2d
given its X axis;
Frame2d.fromXAxis axis
is equivalent to
Frame2d.withXDirection (Axis2d.direction axis)
(Axis2d.originPoint axis)
fromYAxis : Axis2d units coordinates -> Frame2d units coordinates defines
Construct a Frame2d
given its Y axis;
Frame2d.fromYAxis axis
is equivalent to
Frame2d.withYDirection (Axis2d.direction axis)
(Axis2d.originPoint axis)
copy : Frame2d units coordinates defines1 -> Frame2d units coordinates defines2
Create a 'fresh copy' of a frame: one with the same origin point and X/Y directions, but that can be used to define a different local coordinate system. Sometimes useful in generic/library code. Despite the name, this is efficient: it really just returns the value you passed in, but with a different type.
unsafe : { originPoint : Point2d units coordinates, xDirection : Direction2d coordinates, yDirection : Direction2d coordinates } -> Frame2d units coordinates defines
Construct a frame directly from its origin point and X and Y directions:
frame =
Frame2d.unsafe
{ originPoint = Point2d.meters 2 3
, xDirection = Direction2d.degrees 45
, yDirection = Direction2d.degrees 135
}
In this case you must be careful to ensure that the X and Y directions are
perpendicular. To construct pairs of perpendicular directions,
Direction2d.orthonormalize
or
Direction2d.orthogonalize
may be useful.
originPoint : Frame2d units coordinates defines -> Point2d units coordinates
Get the origin point of a given frame.
xDirection : Frame2d units coordinates defines -> Direction2d coordinates
Get the X direction of a given frame.
yDirection : Frame2d units coordinates defines -> Direction2d coordinates
Get the Y direction of a given frame.
isRightHanded : Frame2d units coordinates defines -> Basics.Bool
Check if a frame is right-handed.
Frame2d.isRightHanded Frame2d.atOrigin
--> True
Frame2d.isRightHanded
(Frame2d.reverseX Frame2d.atOrigin)
--> False
All predefined frames are right-handed, and most operations on frames preserve
handedness, so about the only ways to end up with a left-handed frame are by
constructing one explicitly with unsafe
or by mirroring a right-handed frame.
xAxis : Frame2d units coordinates defines -> Axis2d units coordinates
Get the X axis of a given frame (the axis formed from the frame's origin point and X direction).
yAxis : Frame2d units coordinates defines -> Axis2d units coordinates
Get the Y axis of a given frame (the axis formed from the frame's origin point and Y direction).
reverseX : Frame2d units coordinates defines1 -> Frame2d units coordinates defines2
Reverse the X direction of a frame, leaving its Y direction and origin point the same. Note that this will switch the handedness of the frame.
reverseY : Frame2d units coordinates defines1 -> Frame2d units coordinates defines2
Reverse the Y direction of a frame, leaving its X direction and origin point the same. Note that this will switch the handedness of the frame.
moveTo : Point2d units coordinates -> Frame2d units coordinates defines1 -> Frame2d units coordinates defines2
Move a frame so that it has the given origin point.
point =
Point2d.meters 1 1
Frame2d.atOrigin |> Frame2d.moveTo point
--> Frame2d.atPoint point
rotateBy : Angle -> Frame2d units coordinates defines1 -> Frame2d units coordinates defines2
Rotate a frame counterclockwise by a given angle around the frame's own origin point. The resulting frame will have the same origin point, and its X and Y directions will be rotated by the given angle.
rotatedFrame =
Frame2d.atOrigin
|> Frame2d.rotateBy (Angle.degrees 30)
Frame2d.xDirection rotatedFrame
--> Direction2d.degrees 30
Frame2d.yDirection rotatedFrame
--> Direction2d.degrees 120
rotateAround : Point2d units coordinates -> Angle -> Frame2d units coordinates defines1 -> Frame2d units coordinates defines2
Rotate a frame counterclockwise around a given point by a given angle. The frame's origin point will be rotated around the given point by the given angle, and its X and Y basis directions will be rotated by the given angle.
rotatedFrame =
Frame2d.atPoint (Point2d.meters 1 1)
|> Frame2d.rotateAround Point2d.origin
(Angle.degrees 45)
Frame2d.originPoint rotatedFrame
--> Point2d.meters 0 1.4142
Frame2d.xDirection rotatedFrame
--> Direction2d.degrees 45
Frame2d.yDirection rotatedFrame
--> Direction2d.degrees 135
translateBy : Vector2d units coordinates -> Frame2d units coordinates defines1 -> Frame2d units coordinates defines2
Translate a frame by a given displacement.
frame =
Frame2d.atPoint (Point2d.meters 2 3)
displacement =
Vector2d.meters 1 1
Frame2d.translateBy displacement frame
--> Frame2d.atPoint (Point2d.meters 3 4)
translateIn : Direction2d coordinates -> Quantity Basics.Float units -> Frame2d units coordinates defines1 -> Frame2d units coordinates defines2
Translate a frame in a given direction by a given distance.
translateAlongOwn : (Frame2d units coordinates defines1 -> Axis2d units coordinates) -> Quantity Basics.Float units -> Frame2d units coordinates defines1 -> Frame2d units coordinates defines2
Translate a frame along one of its own axes by a given distance.
The first argument is a function that returns the axis to translate along, given
the current frame. The majority of the time this argument will be either
Frame2d.xAxis
or Frame2d.yAxis
. The second argument is the distance to
translate along the given axis.
This function is convenient when constructing frames via a series of transformations. For example,
frame =
Frame2d.atPoint (Point2d.meters 2 0)
|> Frame2d.rotateBy (Angle.degrees 45)
|> Frame2d.translateAlongOwn Frame2d.xAxis
(Length.meters 2)
means "construct a frame at the point (2, 0), rotate it around its own origin point by 45 degrees, then translate it along its own X axis by 2 meters", resulting in
Frame2d.originPoint frame
--> Point2d.meters 3.4142 1.4142
Frame2d.xDirection frame
--> Direction2d.degrees 45
Frame2d.yDirection frame
--> Direction2d.degrees 135
mirrorAcross : Axis2d units coordinates -> Frame2d units coordinates defines1 -> Frame2d units coordinates defines2
Mirror a frame across an axis.
frame =
Frame2d.atPoint (Point2d.meters 2 3)
mirroredFrame =
Frame2d.mirrorAcross Axis2d.x frame
Frame2d.originPoint mirroredFrame
--> Point2d.meters 2 -3
Frame2d.xDirection mirroredFrame
--> Direction2d.x
Frame2d.yDirection mirroredFrame
--> Direction2d.negativeY
Note that this will switch the handedness of the frame.
at : Quantity Basics.Float (Quantity.Rate units2 units1) -> Frame2d units1 coordinates defines -> Frame2d units2 coordinates defines
Convert a frame from one units type to another, by providing a conversion factor given as a rate of change of destination units with respect to source units.
at_ : Quantity Basics.Float (Quantity.Rate units1 units2) -> Frame2d units1 coordinates defines -> Frame2d units2 coordinates defines
Convert a frame from one units type to another, by providing an 'inverse' conversion factor given as a rate of change of source units with respect to destination units.
relativeTo : Frame2d units globalCoordinates { defines : localCoordinates } -> Frame2d units globalCoordinates defines -> Frame2d units localCoordinates defines
Take two frames defined in global coordinates, and return the second one expressed in local coordinates relative to the first.
placeIn : Frame2d units globalCoordinates { defines : localCoordinates } -> Frame2d units localCoordinates defines -> Frame2d units globalCoordinates defines
Take one frame defined in global coordinates and a second frame defined in local coordinates relative to the first frame, and return the second frame expressed in global coordinates.