ianmackenzie / elm-geometry / Block3d

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

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 =
Geometry.Types.Block3d units coordinates

Construction

with : { x1 : Quantity Basics.Float units, y1 : Quantity Basics.Float units, z1 : Quantity Basics.Float units, x2 : Quantity Basics.Float units, y2 : Quantity Basics.Float units, z2 : Quantity Basics.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.

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

centeredOn : Frame3d units coordinates defines -> ( Quantity Basics.Float units, Quantity Basics.Float units, Quantity Basics.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

dimensions : Block3d units coordinates -> ( Quantity Basics.Float units, Quantity Basics.Float units, Quantity Basics.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 Basics.Float (Quantity.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.

edges : 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

interpolate : Block3d units coordinates -> Basics.Float -> Basics.Float -> Basics.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 -> Basics.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.

scaleAbout : Point3d units coordinates -> Basics.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.

rotateAround : Axis3d units coordinates -> Angle -> Block3d units coordinates -> Block3d units coordinates

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

translateBy : Vector3d units coordinates -> Block3d units coordinates -> Block3d units coordinates

Translate a block by a given displacement.

translateIn : Direction3d coordinates -> Quantity Basics.Float units -> Block3d units coordinates -> Block3d units coordinates

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

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

relativeTo : 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.

placeIn : 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.