ianmackenzie/elm-geometry/4.0.0

Block3d

A Block3d represents a rectangular block in 3D space. This module contains block-related functionality such as:

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

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

type alias Block3d units coordinates =
Block3d units coordinates

Construction

{ x1 : Quantity Float units
, y1 : Quantity Float units
, z1 : Quantity Float units
, x2 : Quantity Float units
, y2 : Quantity Float units
, z2 : Quantity Float units
}
-> Block3d units coordinates

Construct an axis-aligned block given the X, Y and Z coordinates of two diagonally opposite vertices. The X, Y and Z directions of the resulting block are determined by the order of the given values. For example, if x1 <= x2, then the block's X direction will be Direction3d.positiveX, otherwise it will be Direction3d.negativeX, and similar for Y and Z. Therefore, something like

Block3d.with
    { x1 = Length.meters 0
    , x2 = Length.meters 500
    , y1 = Length.meters 300
    , y2 = Length.meters 0
    , z1 = Length.meters 100
    , z2 = Length.meters 200
    }

would have its X direction equal to Direction3d.positiveX, its Y direction equal to Direction3d.negativeY, and its Z direction equal to Direction3d.positiveZ.

Point3d units coordinates
-> Point3d units coordinates
-> Block3d units coordinates

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

Block3d.from p1 p2

is equivalent to

Block3d.with
    { x1 = Point3d.xCoordinate p1
    , y1 = Point3d.yCoordinate p1
    , z1 = Point3d.zCoordinate p1
    , x2 = Point3d.xCoordinate p2
    , y2 = Point3d.yCoordinate p2
    , z2 = Point3d.zCoordinate p2
    }

and so the same logic about the resulting block's X, Y and Z directions applies (see above for details).

Frame3d units coordinates defines
-> ( Quantity Float units
, Quantity Float units
, Quantity Float units
)
-> Block3d units coordinates

Construct a frame centered on the given axes, with the given overall dimensions (length/width/height):

block =
    Block3d.centeredOn Frame3d.atOrigin
        ( meters 20, meters 10, meters 30 )


Block3d.vertices block
--> [ Point3d.meters -10 -5 -15
--> , Point3d.meters -10 -5 15
--> , Point3d.meters -10 5 -15
--> , Point3d.meters -10 5 15
--> , Point3d.meters 10 -5 -15
--> , Point3d.meters 10 -5 15
--> , Point3d.meters 10 5 -15
--> , Point3d.meters 10 5 15
--> ]
fromBoundingBox : BoundingBox3d units coordinates -> Block3d units coordinates

Convert a BoundingBox3d to the equivalent axis-aligned Block3d.

Properties

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

Get the overall dimensions (e.g. length, width, height) of a block.

axes : Block3d units coordinates -> Frame3d units coordinates defines

Get the central axes of a block as a Frame3d. The origin point of the frame will be the center point of the block.

xAxis : Block3d units coordinates -> Axis3d units coordinates

Get the X axis of a block.

yAxis : Block3d units coordinates -> Axis3d units coordinates

Get the Y axis of a block.

zAxis : Block3d units coordinates -> Axis3d units coordinates

Get the Z axis of a block.

centerPoint : Block3d units coordinates -> Point3d units coordinates

Get the center point of a block.

volume : Block3d units coordinates -> Quantity Float (Cubed units)

Get the volume of a block.

vertices : Block3d units coordinates -> List (Point3d units coordinates)

Get the 8 vertices of a block as a list. The order of the vertices returned is unspecified.

Block3d units coordinates
-> List (LineSegment3d units coordinates)

Get the 12 edges of a block as a list. The orientation of each edge and the order in which they are returned are unspecified.

boundingBox : Block3d units coordinates -> BoundingBox3d units coordinates

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

cube =
    Block3d.from
        (Point3d.meters 0 0 0)
        (Point3d.meters 1 1 1)


rotatedCube =
    cube
        |> Block3d.rotateAround Axis3d.y
            (Angle.degrees -45)


Block3d.boundingBox rotatedCube
--> BoundingBox3d.fromExtrema
-->     { minX = Length.meters -0.7071
-->     , maxX = Length.meters 0.7071
-->     , minY = Length.meters 0
-->     , maxY = Length.meters 1
-->     , minZ = Length.meters 0
-->     , maxZ = Length.meters 1.4142
-->     }

Interpolation

Block3d units coordinates
-> Float
-> Float
-> Float
-> Point3d units coordinates

Interpolate within a block based on coordinates which range from 0 to 1. For example, the center point of a block is

Block3d.interpolate block 0.5 0.5 0.5

Querying

contains : Point3d units coordinates -> Block3d units coordinates -> Bool

Check if a block contains a given point:

block =
    Block3d.from
        (Point3d.meters 2 1 0)
        (Point3d.meters 5 3 4)


block |> Block3d.contains (Point3d.meters 3 2 3)
--> True


block |> Block3d.contains (Point3d.meters 3 4 1)
--> False

Transformation

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

Point3d units coordinates
-> Float
-> Block3d units coordinates
-> Block3d units coordinates

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

Axis3d units coordinates
-> Angle
-> Block3d units coordinates
-> Block3d units coordinates

Rotate a block around a given axis by a given angle.

Vector3d units coordinates
-> Block3d units coordinates
-> Block3d units coordinates

Translate a block by a given displacement.

Direction3d coordinates
-> Quantity Float units
-> Block3d units coordinates
-> Block3d units coordinates

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

Plane3d units coordinates
-> Block3d units coordinates
-> Block3d units coordinates

Mirror a block across a given plane. Note that this will flip the handedness of the block's axes.

Unit conversions

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

Convert a block 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)
-> Block3d units1 coordinates
-> Block3d units2 coordinates

Convert a block 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

Frame3d units globalCoordinates { defines : localCoordinates }
-> Block3d units globalCoordinates
-> Block3d units localCoordinates

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

Frame3d units globalCoordinates { defines : localCoordinates }
-> Block3d units localCoordinates
-> Block3d units globalCoordinates

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