ianmackenzie/elm-geometry/3.6.0

NOTE: the latest version is 4.0.0

Rectangle2d

A Rectangle2d represents a rectangle in 2D space. This module contains rectangle-related functionality such as:

  • Constructing rectangles in various ways
  • Extracting rectangle vertices and edges
  • Scaling, rotating, translating and mirroring rectangles
  • Converting rectangles between different coordinate systems

Unlike bounding boxes, rectangles are not constrained to be axis-aligned - they can have arbitrary orientation and so can be rotated, mirrored etc.

type alias Rectangle2d units coordinates =
Rectangle2d units coordinates

Construction

{ x1 : Quantity Float units
, y1 : Quantity Float units
, x2 : Quantity Float units
, y2 : Quantity Float units
}
-> Rectangle2d units coordinates

Construct an axis-aligned rectangle given the X and Y coordinates of two diagonally opposite vertices. The X and Y directions of the resulting rectangle are determined by the order of the given values:

  • If x1 <= x2, then the rectangle's X direction will be Direction2d.positiveX, otherwise it will be Direction2d.negativeX
  • If y1 <= y2, then the rectangle's Y direction will be Direction2d.positiveY, otherwise it will be Direction2d.negativeY

Therefore, something like

Rectangle2d.with
    { x1 = Pixels.pixels 0
    , y1 = Pixels.pixels 300
    , x2 = Pixels.pixels 500
    , y2 = Pixels.pixels 0
    }

would have its X direction equal to Direction2d.positiveX and its Y direction equal to Direction2d.negativeY.

Point2d units coordinates
-> Point2d units coordinates
-> Rectangle2d units coordinates

Construct an axis-aligned rectangle stretching from one point to another;

Rectangle2d.from p1 p2

is equivalent to

Rectangle2d.with
    { x1 = Point2d.xCoordinate p1
    , y1 = Point2d.yCoordinate p1
    , x2 = Point2d.xCoordinate p2
    , y2 = Point2d.yCoordinate p2
    }

and so the same logic about the resulting rectangle's X and Y directions applies (see above for details). Therefore, assuming a Y-up coordinate system, something like

Rectangle2d.from lowerLeftPoint upperRightPoint

would have positive X and Y directions, while

Rectangle2d.from upperLeftPoint lowerRightPoint

would have a positive X direction but a negative Y direction.

( Quantity Float units, Quantity Float units )
-> Angle
-> Point2d units coordinates
-> Rectangle2d units coordinates

Construct a rectangle with the given overall dimensions (width/height) and angle, centered on the given point. For an axis-aligned rectangle you can pass Angle.degrees 0 (or equivalently Angle.radians 0 or even Quantity.zero) as the second argument:

rectangle =
    Rectangle2d.withDimensions
        ( Pixels.pixels 200, Pixels.pixels 100 )
        (Angle.degrees 0)
        (Point2d.pixels 400 300)


Rectangle2d.vertices rectangle
--> [ Point2d.pixels 300 250
--> , Point2d.pixels 500 250
--> , Point2d.pixels 500 350
--> , Point2d.pixels 300 350
--> ]

Passing a non-zero angle lets you control the orientation of a rectangle; to make a diamond shape you might do something like

diamond =
    Rectangle2d.withDimensions
        ( Length.meters 2, Length.meters 2 )
        (Angle.degrees 45)
        Point2d.origin


Rectangle2d.vertices diamond
--> [ Point2d.meters 0 -1.4142
--> , Point2d.meters 1.4142 0
--> , Point2d.meters 0 1.4142
--> , Point2d.meters -1.4142 0
--> ]
Frame2d units coordinates defines
-> ( Quantity Float units, Quantity Float units )
-> Rectangle2d units coordinates

Construct a frame centered on the given axes, with the given overall dimensions;

Rectangle2d.withDimensions dimensions angle centerPoint

could be written as

Rectangle2d.centeredOn
    (Frame2d.withAngle angle centerPoint)
    dimensions
Axis2d units coordinates
-> ( Quantity Float units, Quantity Float units )
-> Rectangle2d units coordinates

Construct a rectangle with the given X axis and overall dimensions. The rectangle will be centered on the axis' origin point.

Axis2d units coordinates
-> ( Quantity Float units, Quantity Float units )
-> Rectangle2d units coordinates

Construct a rectangle with the given Y axis and overall dimensions. The rectangle will be centered on the axis' origin point.

fromBoundingBox : BoundingBox2d units coordinates -> Rectangle2d units coordinates

Convert a BoundingBox2d to the equivalent axis-aligned Rectangle2d.

Properties

Rectangle2d units coordinates
-> ( Quantity Float units, Quantity Float units )

Get the overall dimensions (width and height) of a rectangle:

rectangle =
    Rectangle2d.with
        { x1 = Length.meters 2
        , x2 = Length.meters 5
        , y1 = Length.meters 1
        , y2 = Length.meters 3
        }


Rectangle2d.dimensions rectangle
--> ( Length.meters 3, Length.meters 2 )
Rectangle2d units coordinates
-> Frame2d units coordinates defines

Get the central axes of a rectangle as a Frame2d:

rectangle =
    Rectangle2d.with
        { x1 = Length.meters 2
        , x2 = Length.meters 5
        , y1 = Length.meters 1
        , y2 = Length.meters 3
        }


Rectangle2d.axes rectangle
--> Frame2d.atPoint (Point2d.meters 3.5 2)

The origin point of the frame will be the center point of the rectangle.

xAxis : Rectangle2d units coordinates -> Axis2d units coordinates

Get the X axis of a rectangle.

yAxis : Rectangle2d units coordinates -> Axis2d units coordinates

Get the Y axis of a rectangle.

centerPoint : Rectangle2d units coordinates -> Point2d units coordinates

Get the center point of a rectangle.

area : Rectangle2d units coordinates -> Quantity Float (Squared units)

Get the area of a rectangle.

vertices : Rectangle2d units coordinates -> List (Point2d units coordinates)

Get the vertices of a rectangle as a list. The vertices will be returned in counterclockwise order if the rectangle's axes are right-handed, and clockwise order if the axes are left-handed.

Rectangle2d units coordinates
-> List (LineSegment2d units coordinates)

Get the edges of a rectangle as a list. The edges will be returned in counterclockwise order if the rectangle's axes are right-handed, and clockwise order if the axes are left-handed.

boundingBox : Rectangle2d units coordinates -> BoundingBox2d units coordinates

Get the minimal bounding box containing a given rectangle. This will have exactly the same shape and size as the rectangle itself if the rectangle is axis-aligned, but will be larger than the rectangle if the rectangle is at an angle.

square =
    Rectangle2d.with
        { x1 = Length.meters 0
        , x2 = Length.meters 1
        , y1 = Length.meters 0
        , y2 = Length.meters 1
        }


diamond =
    square
        |> Rectangle2d.rotateAround Point2d.origin
            (Angle.degrees 45)


Rectangle2d.boundingBox diamond
--> BoundingBox2d.from
-->     (Point2d.meters -0.7071 0)
-->     (Point2d.meters 0.7071 1.4142)

Interpolation

Rectangle2d units coordinates
-> Float
-> Float
-> Point2d units coordinates

Interpolate within a rectangle based on coordinates which range from 0 to 1. For example, the four vertices of a given rectangle are

[ Rectangle2d.interpolate rectangle 0 0
, Rectangle2d.interpolate rectangle 1 0
, Rectangle2d.interpolate rectangle 1 1
, Rectangle2d.interpolate rectangle 0 1
]

and its center point is

Rectangle2d.interpolate rectangle 0.5 0.5

Querying

contains : Point2d units coordinates -> Rectangle2d units coordinates -> Bool

Check if a rectangle contains a given point.

Conversion

toPolygon : Rectangle2d units coordinates -> Polygon2d units coordinates

Convert a rectangle to a Polygon2d.

Transformation

These transformations generally behave just like the ones in the Point2d module.

Point2d units coordinates
-> Float
-> Rectangle2d units coordinates
-> Rectangle2d units coordinates

Scale a rectangle about a given point by a given scale. Note that scaling by a negative value will flip the handedness of the rectangle's axes, and therefore the order/direction of results from Rectangle2d.vertices and Rectangle2d.edges will change.

Point2d units coordinates
-> Angle
-> Rectangle2d units coordinates
-> Rectangle2d units coordinates

Rotate a rectangle around a given point by a given angle.

Vector2d units coordinates
-> Rectangle2d units coordinates
-> Rectangle2d units coordinates

Translate a rectangle by a given displacement.

Direction2d coordinates
-> Quantity Float units
-> Rectangle2d units coordinates
-> Rectangle2d units coordinates

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

Axis2d units coordinates
-> Rectangle2d units coordinates
-> Rectangle2d units coordinates

Mirror a rectangle across a given axis. Note that this will flip the handedness of the rectangle's axes, and therefore the order/direction of results from Rectangle2d.vertices and Rectangle2d.edges will change.

Unit conversions

at :
Quantity Float (Rate units2 units1)
-> Rectangle2d units1 coordinates
-> Rectangle2d units2 coordinates

Convert a rectangle 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)
-> Rectangle2d units1 coordinates
-> Rectangle2d units2 coordinates

Convert a rectangle 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 }
-> Rectangle2d units globalCoordinates
-> Rectangle2d units localCoordinates

Take a rectangle defined in global coordinates, and return it expressed in local coordinates relative to a given reference frame.

Frame2d units globalCoordinates { defines : localCoordinates }
-> Rectangle2d units localCoordinates
-> Rectangle2d units globalCoordinates

Take a rectangle considered to be defined in local coordinates relative to a given reference frame, and return that rectangle expressed in global coordinates.