ianmackenzie / elm-geometry / 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:


type alias Frame2d units coordinates defines =
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.

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

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.

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

Transformations

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.

Unit conversions

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.

Coordinate conversions

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.