A Direction3d represents a direction like 'up' or 'north' or 'forwards'.
They are represented using X, Y and Z components, and can be converted to
vectors if necessary, but should be thought of as conceptually different.
Directions have several uses, such as:
Synonym for Direction3d.positiveX.
Synonym for Direction3d.positiveY.
Synonym for Direction3d.positiveZ.
The positive X direction.
The negative X direction.
The positive Y direction.
The negative Y direction.
The positive Z direction.
The negative Z direction.
Attempt to construct the direction from the first given point to the second.
If the two points are coincident, returns Nothing.
point =
Point3d.meters 1 0 1
Direction3d.from Point3d.origin point
--> Just (Direction3d.xz (Angle.degrees 45))
Direction3d.from point Point3d.origin
--> Just (Direction3d.xz (Angle.degrees -135))
Direction3d.from point point
--> NothingConstruct a direction in the XY plane given an angle measured from positive X towards positive Y:
Direction3d.xy (Angle.degrees 0)
--> Direction3d.positiveX
Direction3d.xy (Angle.degrees 90)
--> Direction3d.positiveY
Direction3d.xy (Angle.degrees 180)
--> Direction3d.negativeXConstruct a direction in the XY plane given an angle measured from positive Y towards positive X:
Direction3d.yx (Angle.degrees 0)
--> Direction3d.positiveY
Direction3d.yx (Angle.degrees 90)
--> Direction3d.positiveX
Direction3d.yx (Angle.degrees -90)
--> Direction3d.negativeXConstruct a direction in the YZ plane given an angle measured from positive Y towards positive Z.
Construct a direction in the YZ plane given an angle measured from positive Z towards positive Y.
Construct a direction in the XZ plane given an angle measured from positive Z towards positive X.
Construct a direction in the XZ plane given an angle measured from positive X towards positive Z.
Construct a 3D direction lying on a sketch plane by providing a 2D
direction specified in XY coordinates within the sketch plane. This is a
generalized version of Direction3d.xy, Direction3d.yz etc.; for example,
Direction3d.xy (Angle.degrees 45)is equivalent to
Direction3d.on SketchPlane3d.xy (Direction2d.degrees 45)Construct a direction given:
See
here
for an illustration of these two angles (except that this function measures
azimuth from positive X towards positive Y, not negative Y towards positive
X). Note that Direction3d.xyZ is a generalized version of Direction3d.xy;
Direction3d.xy angleis equivalent to
Direction3d.xyZ angle (Angle.degrees 0)Construct a direction given:
This is generally not as useful as Direction3d.xyZ or Direction3d.zxY.
Construct a direction given:
This may be useful if you like to use positive Y as your global up vector.
Construct a direction given:
This is a generalized version of Direction3d.xyZ, Direction3d.yzX and
Direction3d.zxY; for example,
Direction3d.xyZ azimuth elevationis equivalent to
Direction3d.fromAzimuthInAndElevationFrom
SketchPlane3d.xy
azimuth
elevationConstruct an arbitrary direction perpendicular to the given direction. The exact resulting direction is not specified, but it is guaranteed to be perpendicular to the given direction.
Direction3d.perpendicularTo Direction3d.x
--> Direction3d.negativeZ
Direction3d.perpendicularTo Direction3d.y
--> Direction3d.positiveZ
direction =
Direction3d.xz (Angle.degrees 60)
Direction3d.perpendicularTo direction
--> Direction3d.xz (Angle.degrees -30)Construct a pair of directions that are perpendicular to each other and both perpendicular to the given direction.
The given direction and the two returned directions will form a
right-handed
system (that is, a right-handed Frame3d could be constructed by using the
given direction as the X direction and the two returned directions as the Y and
Z directions, or the given direction as the Z direction and the two returned
directions as the X and Y directions).
Direction3d.perpendicularBasis Direction3d.x
--> ( Direction3d.negativeZ
--> , Direction3d.positiveY
--> )
Direction3d.perpendicularBasis Direction3d.y
--> ( Direction3d.positiveZ
--> , Direction3d.positiveX
--> )Attempt to form a set of three mutually perpendicular directions from the three given vectors by performing Gram-Schmidt normalization:
If any of the given vectors are zero, any two of them are parallel, or the three
are coplanar, returns Nothing.
Direction3d.orthonormalize
(Vector3d.meters 3 3 0)
(Vector3d.meters 0 2 0)
(Vector3d.meters 1 2 3)
--> Just
--> ( Direction3d.xy (Angle.degrees 45)
--> , Direction3d.xy (Angle.degrees 135)
--> , Direction3d.z
--> )
-- Three vectors in the XY plane:
Direction3d.orthonormalize
(Vector3d.meters 2 0 0)
(Vector3d.meters 3 1 0)
(Vector3d.meters 4 2 0)
--> NothingAttempt to form a set of three mutually perpendicular directions from the three given directions;
Direction3d.orthogonalize
xDirection
yDirection
zDirectionis equivalent to
Direction3d.orthonormalize
(Direction3d.toVector xDirection)
(Direction3d.toVector yDirection)
(Direction3d.toVector zDirection)Convert a direction to a unitless vector of length 1.
Direction3d.toVector Direction3d.y
--> Vector3d.unitless 0 1 0Get the X component of a direction.
Direction3d.xComponent Direction3d.x
--> 1
Direction3d.xComponent Direction3d.y
--> 0Get the Y component of a direction.
Direction3d.yComponent Direction3d.y
--> 1
Direction3d.yComponent Direction3d.z
--> 0Get the Z component of a direction.
Direction3d.zComponent Direction3d.z
--> 1
Direction3d.zComponent Direction3d.x
--> 0Find the component of one direction in another direction. This is equal to the cosine of the angle between the directions, or equivalently the dot product of the two directions converted to unit vectors.
direction =
Direction3d.xz (Angle.degrees 60)
Direction3d.componentIn Direction3d.x direction
--> 0.5
Direction3d.componentIn Direction3d.z direction
--> 0.866
Direction3d.componentIn direction direction
--> 1
direction
|> Direction3d.componentIn
(Direction3d.reverse direction)
--> -1This is more general and flexible than using xComponent, yComponent or
zComponent, all of which can be expressed in terms of componentIn; for
example,
Direction3d.zComponent directionis equivalent to
Direction3d.componentIn Direction3d.z directionFind the angle from one direction to another. The result will be in the range 0 to 180 degrees
Direction3d.angleFrom Direction3d.x Direction3d.x
--> Angle.degrees 0
Direction3d.angleFrom Direction3d.x Direction3d.z
--> Angle.degrees 90
Direction3d.angleFrom
Direction3d.y
Direction3d.negativeY
--> Angle.degrees 180Get the azimuth of a direction in a given sketch plane (the angle of that direction projected into the sketch plane), measured from its X axis towards its Y axis (counterclockwise around the sketch plane's normal axis). The result will be in the range -180 degrees to 180 degrees.
Direction3d.x
|> Direction3d.azimuthIn SketchPlane3d.xy
--> Angle.degrees 0
Direction3d.y
|> Direction3d.azimuthIn SketchPlane3d.xy
--> Angle.degrees 90
Direction3d.negativeY
|> Direction3d.azimuthIn SketchPlane3d.xy
--> Angle.degrees -90
Direction3d.negativeX
|> Direction3d.azimuthIn SketchPlane3d.xy
--> Angle.degrees 180Vertical directions are considered to have an azimuth of zero:
Direction3d.z |> Direction3d.azimuthIn SketchPlane3d.xy
--> Angle.degrees 0Get the elevation angle of a direction from a given sketch plane (the angle between the direction and the sketch plane, in the direction of the sketch plane's normal). Directions in (coplanar with) the sketch plane have an elevation angle of zero. The result will be in the range -90 degrees to 90 degrees.
Direction3d.x
|> Direction3d.elevationFrom SketchPlane3d.xy
--> Angle.degrees 0
Direction3d.y
|> Direction3d.elevationFrom SketchPlane3d.xy
--> Angle.degrees 0
Direction3d.z
|> Direction3d.elevationFrom SketchPlane3d.xy
--> Angle.degrees 90
Direction3d.negativeZ
|> Direction3d.elevationFrom SketchPlane3d.xy
--> Angle.degrees -90Compare two directions within an angular tolerance. Returns true if the angle between the two given directions is less than the given tolerance.
rotatedDirection =
Direction3d.x
|> Direction3d.rotateAround Axis3d.z
(Angle.degrees 2)
Direction3d.equalWithin (Angle.degrees 5)
Direction3d.x
rotatedDirection
--> True
Direction3d.equalWithin (Angle.degrees 1)
Direction3d.x
rotatedDirection
--> FalseReverse a direction.
Rotate a direction around an axis by a given angle.
Direction3d.y
|> Direction3d.rotateAround Axis3d.x
(Angle.degrees 90)
--> Direction3d.zNote that only the direction of the axis affects the result, not the position of its origin point, since directions are position-independent:
offsetAxis =
Axis3d.withDirection Direction3d.z
(Point3d.meters 100 200 300)
Direction3d.x
|> Direction3d.rotateAround offsetAxis
(Angle.degrees 90)
--> Direction3d.yMirror a direction across a plane.
direction =
Direction3d.xyZ (Angle.degrees 30)
(Angle.degrees 60)
Direction3d.mirrorAcross Plane3d.xy direction
--> Direction3d.xyZ (Angle.degrees 30)
--> (Angle.degrees -60)Note that only the normal direction of the plane affects the result, not the position of its origin point, since directions are position-independent:
Direction3d.mirrorAcross Plane3d.yz direction
--> Direction3d.xyZ (Angle.degrees 150)
--> (Angle.degrees 60)
offsetPlane =
Plane3d.offsetBy 10 Plane3d.yz
Direction3d.mirrorAcross offsetPlane direction
--> Direction3d.xyZ (Angle.degrees 150)
--> (Angle.degrees 60)Find the orthographic projection
of a direction onto a plane (renormalized to have unit length). If the given
direction is exactly perpendicular to the given plane, returns Nothing.
direction =
Direction3d.xyZ (Angle.degrees -60)
(Angle.degrees 0)
Direction3d.projectOnto Plane3d.xy direction
--> Just direction
Direction3d.projectOnto Plane3d.xz direction
--> Just Direction3d.x
Direction3d.projectOnto Plane3d.yz direction
--> Just Direction3d.negativeY
Direction3d.projectOnto Plane3d.xy Direction3d.z
--> NothingLike other transformations, coordinate transformations of directions depend only on the orientations of the relevant frames, not their positions.
For the examples, assume the following definition of a local coordinate frame, one that is rotated 30 degrees counterclockwise around the Z axis from the global XYZ frame:
rotatedFrame =
Frame3d.atOrigin
|> Frame3d.rotateAround Axis3d.z (Angle.degrees 30)Take a direction defined in global coordinates, and return it expressed in local coordinates relative to a given reference frame.
Direction3d.relativeTo rotatedFrame Direction3d.x
--> Direction3d.xy (Angle.degrees -30)
Direction3d.relativeTo rotatedFrame Direction3d.y
--> Direction3d.xy (Angle.degrees 60)
Direction3d.relativeTo rotatedFrame Direction3d.z
--> Direction3d.zTake a direction defined in local coordinates relative to a given reference frame, and return that direction expressed in global coordinates.
Direction3d.placeIn rotatedFrame Direction3d.x
--> Direction3d.xy (Angle.degrees 30)
Direction3d.placeIn rotatedFrame Direction3d.y
--> Direction3d.xy (Angle.degrees 120)
Direction3d.placeIn rotatedFrame Direction3d.z
--> Direction3d.zProject a direction into a given sketch plane. Conceptually, this finds the orthographic projection of the direction onto the plane, re-normalizes it to have unit length, and then expresses the projected direction in 2D sketch coordinates.
This is only possible if the direction is not perpendicular to the sketch
plane; if it is perpendicular, Nothing is returned.
direction =
Direction3d.xy (Angle.degrees -60)
Direction3d.projectInto SketchPlane3d.xy direction
--> Just (Direction2d.degrees -60)
Direction3d.projectInto SketchPlane3d.xz direction
--> Just Direction2d.x
Direction3d.projectInto SketchPlane3d.yz direction
--> Just Direction2d.negativeX
Direction3d.projectInto SketchPlane3d.xy Direction3d.z
--> NothingConstruct a direction directly from its X, Y and Z components. Note that you must ensure that the sum of the squares of the given components is exactly one:
Direction3d.unsafe { x = 1, y = 0, z = 0 }
Direction3d.unsafe { x = 0, y = -1, z = 0 }
Direction3d.unsafe { x = 0.6, y = 0, z = 0.8 }are all valid but
Direction3d.unsafe { x = 2, y = 0, z = 0 }
Direction3d.unsafe { x = 1, y = 1, z = 1 }are not. Instead of using Direction3d.unsafe, it may be easier to use
constructors like Direction3d.on or Direction3d.xyZ (which will always
result in a valid direction), or start with existing directions and transform
them as necessary.
Extract the X, Y and Z components of a direction as a record.