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:
The simplest way to construct a Direction3d value is by passing a tuple of X,
Y and Z components to the Direction3d constructor, for example
Direction3d ( 0, 1, 0 ). However, if you
do this you must ensure that the sum of the squares of the given components is
exactly one:
Direction3d ( 1, 0, 0 )
Direction3d ( 0, -1, 0 )
Direction3d ( 0.6, 0, 0.8 )are all valid but
Direction3d ( 2, 0, 0 )
Direction3d ( 1, 1, 1 )are not. Instead of manually constructing Direction3d values, it may be easier
to start with existing directions and transform them as necessary.
The positive Y direction.
Direction3d.y
--> Direction3d ( 0, 1, 0 )The positive Z direction.
Direction3d.z
--> Direction3d ( 0, 0, 1 )Construct 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 ( 0, 0, -1 )
Direction3d.perpendicularTo Direction3d.y
--> Direction3d ( 0, 0, 1 )
direction =
Direction3d ( 0.6, 0, 0.8 )
Direction3d.perpendicularTo direction
--> Direction3d ( 0.8, 0, -0.6 )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).
Direction3d.perpendicularBasis Direction3d.x
--> ( Direction3d ( 0, 0, -1 )
--> , Direction3d ( 0, 1, 0 )
--> )
Direction3d.perpendicularBasis Direction3d.y
--> ( Direction3d ( 0, 0, 1 )
--> , Direction3d ( 1, 0, 0 )
--> )Get the components of a direction as a tuple (the components it would have as a unit vector, also know as its direction cosines).
( x, y, z ) =
Direction3d.components directionGet 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 ( 0.6, 0.8, 0 )
Direction3d.componentIn Direction3d.x direction
--> 0.6
Direction3d.componentIn Direction3d.z direction
--> 0
Direction3d.componentIn direction 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 directionCompare two directions within a tolerance. Returns true if the angle between the two given directions is less than the given tolerance.
direction =
Direction3d.rotateAround Axis3d.z (degrees 2) Direction3d.x
Direction3d.equalWithin (degrees 5) Direction3d.x direction
--> True
Direction3d.equalWithin (degrees 1) Direction3d.x direction
--> FalseConvert a direction to a unit vector.
Direction3d.toVector Direction3d.y
--> Vector3d ( 0, 1, 0 )Find the angle from one direction to another. The result will be in the range 0 to π.
Direction3d.angleFrom Direction3d.x Direction3d.x
--> degrees 0
Direction3d.angleFrom Direction3d.x Direction3d.z
--> degrees 90
Direction3d.angleFrom Direction3d.y (Direction3d ( 0, -1, 0 ))
--> degrees 180Reverse a direction.
Direction3d.flip Direction3d.y
--> Direction3d ( 0, -1, 0 )Construct a vector of a particular length by treating a direction as a unit vector and scaling it by the given length.
Direction3d.scaleBy 3 Direction3d.z
--> Vector3d ( 0, 0, 3 )The length can be negative, in which case the resulting vector will have the opposite direction.
Rotate a direction around an axis by a given angle.
Direction3d.rotateAround Axis3d.x (degrees 90) Direction3d.y
--> 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
{ originPoint = Point3d ( 100, 200, 300 )
, direction = Direction3d.z
}
Direction3d.rotateAround offsetAxis (degrees 90) Direction3d.x
--> Direction3d.yMirror a direction across a plane.
direction =
Direction3d ( 0.6, 0, 0.8 )
Direction3d.mirrorAcross Plane3d.xy direction
--> Direction3d ( 0.6, 0, -0.8 )Note that only the normal direction of the plane affects the result, not the position of its origin point, since directions are position-independent:
offsetPlane =
Plane3d.offsetBy 10 Plane3d.yz
Direction3d.mirrorAcross offsetPlane direction
--> Direction3d ( -0.6, 0, 0.8 )Project a direction onto a plane. This is effectively the direction of the
given direction's 'shadow' on the given plane. If the given direction is
exactly perpendicular to the given plane, then Nothing is returned.
direction =
Direction3d ( 0.6, -0.8, 0 )
Direction3d.projectOnto Plane3d.xy direction
--> Just (Direction3d ( 0.6, -0.8, 0 ))
Direction3d.projectOnto Plane3d.xz direction
--> Just (Direction3d ( 1, 0, 0 ))
Direction3d.projectOnto Plane3d.yz direction
--> Just (Direction3d ( 0, -1, 0 ))
Direction3d.projectOnto Plane3d.xy Direction3d.z
--> NothingFunctions for transforming directions between local and global coordinates in different coordinate frames. Like 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.rotateAround Axis3d.z (degrees 30) Frame3d.xyzTake 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 ( 0.866, -0.5, 0 )
Direction3d.relativeTo rotatedFrame Direction3d.y
--> Direction3d ( 0.5, 0.866, 0 )
Direction3d.relativeTo rotatedFrame Direction3d.z
--> Direction3d ( 0, 0, 1 )Take 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 ( 0.866, 0.5, 0 )
Direction3d.placeIn rotatedFrame Direction3d.y
--> Direction3d ( -0.5, 0.866, 0 )
Direction3d.placeIn rotatedFrame Direction3d.z
--> Direction3d ( 0, 0, 1 )Project a direction into a given sketch plane. Conceptually, this projects the direction onto the plane 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 ( 0.6, -0.8, 0 )
Direction3d.projectInto SketchPlane3d.xy direction
--> Just (Direction2d ( 0.6, -0.8 ))
Direction3d.projectInto SketchPlane3d.xz direction
--> Just (Direction2d ( 1, 0 ))
Direction3d.projectInto SketchPlane3d.yz direction
--> Just (Direction2d ( -1, 0 ))
Direction3d.projectInto SketchPlane3d.xy Direction3d.z
--> Nothing
The positive X direction.