ianmackenzie/elm-geometry/3.8.0

NOTE: the latest version is 4.0.0

Frame2d

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:

  • A local coordinate system: Most geometric types have associated relativeTo and placeIn functions that convert values of that type from global coordinates to local coordinates in a particular frame, and vice versa.
  • A pair of X and Y axes: It is often convenient to (for example) mirror across the X axis of a frame, or project onto its Y axis. Frames can also themselves be translated, rotated and mirrored!
  • A combined 2D position and orientation: For example, a 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.
type alias Frame2d units coordinates defines =
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.

Constants

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

Constructors

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
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
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
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)
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.

{ 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.

Properties

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 -> 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).

Transformations

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.

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.

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
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
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
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)
Direction2d coordinates
-> Quantity Float units
-> Frame2d units coordinates defines1
-> Frame2d units coordinates defines2

Translate a frame in a given direction by a given distance.

(Frame2d units coordinates defines1 -> Axis2d units coordinates)
-> Quantity 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
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.

Unit conversions

at :
Quantity Float (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 Float (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.

Coordinate conversions

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.

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.