diff --git a/src/Arc/SweptAngle.elm b/src/Arc/SweptAngle.elm
index 6dbb0ab0..558ea921 100644
--- a/src/Arc/SweptAngle.elm
+++ b/src/Arc/SweptAngle.elm
@@ -26,38 +26,30 @@ The `SweptAngle` type is used in these cases to specify which arc you want.
import Geometry.Types as Types
-{-| Indicate which of four possible arcs you would like to construct. Used by
-[`Arc2d.withRadius`](Arc2d#withRadius) and [`EllipticalArc2d.fromEndpoints`](EllipticalArc2d#fromEndpoints).
--}
+{-| -}
type alias SweptAngle =
Types.SweptAngle
-{-| Construct a counterclockwise arc with a swept angle between 0 and 180
-degrees.
--}
+{-| -}
smallPositive : SweptAngle
smallPositive =
Types.SmallPositive
-{-| Construct a clockwise arc with a swept angle between 0 and -180 degrees.
--}
+{-| -}
smallNegative : SweptAngle
smallNegative =
Types.SmallNegative
-{-| Construct a counterclockwise arc with a swept angle between 180 and 360
-degrees.
--}
+{-| -}
largePositive : SweptAngle
largePositive =
Types.LargePositive
-{-| Construct a clockwise arc with a swept angle between -180 and -360 degrees.
--}
+{-| -}
largeNegative : SweptAngle
largeNegative =
Types.LargeNegative
diff --git a/src/Arc2d.elm b/src/Arc2d.elm
index 06a7fb76..0ed834f4 100644
--- a/src/Arc2d.elm
+++ b/src/Arc2d.elm
@@ -109,46 +109,7 @@ twoPi =
2 * pi
-{-| Construct an arc with from the first given point to the second, with the
-given swept angle.
-
- p1 =
- Point2d.fromCoordinates ( 2, 1 )
-
- p2 =
- Point2d.fromCoordinates ( 1, 2 )
-
- arc1 =
- Arc2d.from p1 p2 (degrees 90)
-
- Arc2d.centerPoint arc1
- --> Point2d.fromCoordinates ( 1, 1 )
-
- arc2 =
- Arc2d.from p1 p2 (degrees -90)
-
- Arc2d.centerPoint arc2
- --> Point2d.fromCoordinates ( 2, 2 )
-
- arc3 =
- Arc2d.from p1 p2 (degrees 180)
-
- Arc2d.centerPoint arc3
- --> Point2d.fromCoordinates ( 1.5, 1.5 )
-
- arc4 =
- Arc2d.from p1 p2 (degrees -180)
-
- Arc2d.centerPoint arc4
- --> Point2d.fromCoordinates ( 1.5, 1.5 )
-
- arc5 =
- Arc2d.from p1 p2 (degrees 45)
-
- Arc2d.centerPoint arc5
- --> Point2d.fromCoordinates ( 0.2929, 0.2929 )
-
--}
+{-| -}
from : Point2d -> Point2d -> Float -> Arc2d
from startPoint_ endPoint_ sweptAngle_ =
let
@@ -185,25 +146,7 @@ from startPoint_ endPoint_ sweptAngle_ =
}
-{-| Construct an arc with the given center point, radius, start angle and swept
-angle:
-
- arc =
- Arc2d.with
- { centerPoint =
- Point2d.fromCoordinates ( 2, 0 )
- , radius = 1
- , startAngle = degrees 45
- , sweptAngle = degrees -90
- }
-
- Arc2d.startPoint arc
- --> Point2d.fromCoordinates ( 2.7071, 0.7071 )
-
- Arc2d.endPoint arc
- --> Point2d.fromCoordinates ( 2.7071, -0.7071 )
-
--}
+{-| -}
with : { centerPoint : Point2d, radius : Float, startAngle : Float, sweptAngle : Float } -> Arc2d
with properties =
let
@@ -223,36 +166,7 @@ with properties =
}
-{-| Construct an arc by sweeping (rotating) a given start point around a given
-center point by a given angle. The center point to sweep around is given first
-and the start point to be swept is given last.
-
- exampleArc =
- Point2d.fromCoordinates ( 3, 1 )
- |> Arc2d.sweptAround
- (Point2d.fromCoordinates ( 1, 1 ))
- (degrees 90)
-
- Arc2d.endPoint exampleArc
- --> Point2d.fromCoordinates ( 1, 3 )
-
-Note that the 'actual' form of this function is
-
- arc =
- Arc2d.sweptAround centerPoint sweptAngle startPoint
-
-but it is generally written using the pipe operator `|>` (as in the first
-example) to improve readability:
-
- arc =
- startPoint
- |> Arc2d.sweptAround centerPoint sweptAngle
-
-A positive swept angle means that the arc is formed by rotating the start point
-counterclockwise around the center point. A negative swept angle results in
-a clockwise arc instead.
-
--}
+{-| -}
sweptAround : Point2d -> Float -> Point2d -> Arc2d
sweptAround centerPoint_ sweptAngle_ startPoint_ =
case Vector2d.lengthAndDirection (Vector2d.from startPoint_ centerPoint_) of
@@ -273,46 +187,7 @@ sweptAround centerPoint_ sweptAngle_ startPoint_ =
}
-{-| Attempt to construct an arc that starts at the first given point, passes
-through the second given point and ends at the third given point:
-
- Arc2d.throughPoints
- Point2d.origin
- (Point2d.fromCoordinates ( 1, 0 ))
- (Point2d.fromCoordinates ( 0, 1 ))
- --> Just
- --> (Point2d.origin
- --> |> Arc2d.sweptAround
- --> (Point2d.fromCoordinates ( 0.5, 0.5 ))
- --> (degrees 270)
- --> )
-
- Arc2d.throughPoints
- (Point2d.fromCoordinates ( 1, 0 ))
- Point2d.origin
- (Point2d.fromCoordinates ( 0, 1 ))
- --> Just
- --> (Point2d.fromCoordinates ( 1, 0 )
- --> |> Arc2d.sweptAround
- --> (Point2d.fromCoordinates ( 0.5, 0.5 ))
- --> (degrees -180)
- --> )
-
-If the three points are collinear, returns `Nothing`:
-
- Arc2d.throughPoints
- Point2d.origin
- (Point2d.fromCoordinates ( 1, 0 ))
- (Point2d.fromCoordinates ( 2, 0 ))
- --> Nothing
-
- Arc2d.throughPoints
- Point2d.origin
- Point2d.origin
- (Point2d.fromCoordinates ( 1, 0 ))
- --> Nothing
-
--}
+{-| -}
throughPoints : Point2d -> Point2d -> Point2d -> Maybe Arc2d
throughPoints firstPoint secondPoint thirdPoint =
Point2d.circumcenter firstPoint secondPoint thirdPoint
@@ -357,78 +232,7 @@ throughPoints firstPoint secondPoint thirdPoint =
)
-{-| Attempt to construct an arc with the given radius between the given start
-and end points. Note that this is only possible if the given radius is large
-enough! For any given valid radius, start point and end point, there are four
-possible results, so the [`SweptAngle`](Arc-SweptAngle) argument is used to
-specify which arc to create. For example:
-
- p1 =
- Point2d.fromCoordinates ( 1, 0 )
-
- p2 =
- Point2d.fromCoordinates ( 0, 1 )
-
- Arc2d.withRadius 1 SweptAngle.smallPositive p1 p2
- --> Just
- --> (Point2d.fromCoordinates ( 1, 0 )
- --> |> Arc2d.sweptAround Point2d.origin
- --> (degrees 90)
- --> )
-
- Arc2d.withRadius 1 SweptAngle.smallNegative p1 p2
- --> Just
- --> (Point2d.fromCoordinates ( 1, 0 )
- --> |> Arc2d.sweptAround
- --> (Point2d.fromCoordinates ( 1, 1 ))
- --> (degrees -90)
- --> )
-
- Arc2d.withRadius 1 SweptAngle.largePositive p1 p2
- --> Just
- --> (Point2d.fromCoordinates ( 1, 0 )
- --> |> Arc2d.sweptAround
- --> (Point2d.fromCoordinates ( 1, 1 ))
- --> (degrees 270)
- --> )
-
- Arc2d.withRadius 1 SweptAngle.largeNegative p1 p2
- --> Just
- --> (Point2d.fromCoordinates ( 1, 0 )
- --> |> Arc2d.sweptAround Point2d.origin
- --> (degrees -270)
- --> )
-
- Arc2d.withRadius 2 SweptAngle.smallPositive p1 p2
- --> Just
- --> (Point2d.fromCoordinates ( 1, 0 )
- --> |> Arc2d.sweptAround
- --> (Point2d.fromCoordinates
- --> ( -0.8229, -0.8229 )
- --> )
- --> (degrees 41.4096)
- --> )
-
-If the start and end points are coincident or the distance between them is more
-than twice the given radius, returns `Nothing`:
-
- -- p1 and p2 are too far apart to be connected by an
- -- arc of radius 0.5
- Arc2d.withRadius 0.5 SweptAngle.smallPositive p1 p2
- --> Nothing
-
-Note that this means it is dangerous to use this function to construct 180
-degree arcs (half circles), since in this case due to numerical roundoff the
-distance between the two given points may appear to be slightly more than twice
-the given radius. In this case it is safer to use `Arc2d.from`, such as (for a
-counterclockwise arc):
-
- halfCircle =
- Arc2d.from firstPoint secondPoint (degrees 180)
-
-(Use `degrees -180` for a clockwise arc.)
-
--}
+{-| -}
withRadius : Float -> SweptAngle -> Point2d -> Point2d -> Maybe Arc2d
withRadius radius_ sweptAngle_ startPoint_ endPoint_ =
let
@@ -498,12 +302,7 @@ withRadius radius_ sweptAngle_ startPoint_ endPoint_ =
Nothing
-{-| Get the center point of an arc.
-
- Arc2d.centerPoint exampleArc
- --> Point2d.fromCoordinates ( 1, 1 )
-
--}
+{-| -}
centerPoint : Arc2d -> Point2d
centerPoint (Types.Arc2d arc) =
let
@@ -519,65 +318,31 @@ centerPoint (Types.Arc2d arc) =
Point2d.fromCoordinates ( x0 - r * dy, y0 + r * dx )
-{-| Get the radius of an arc.
-
- Arc2d.radius exampleArc
- --> 2
-
--}
+{-| -}
radius : Arc2d -> Float
radius (Types.Arc2d arc) =
arc.signedLength / arc.sweptAngle
-{-| Get the start point of an arc.
-
- Arc2d.startPoint exampleArc
- --> Point2d.fromCoordinates ( 3, 1 )
-
--}
+{-| -}
startPoint : Arc2d -> Point2d
startPoint (Types.Arc2d properties) =
properties.startPoint
-{-| Get the end point of an arc.
-
- Arc2d.endPoint exampleArc
- --> Point2d.fromCoordinates ( 1, 3 )
-
--}
+{-| -}
endPoint : Arc2d -> Point2d
endPoint arc =
pointOn arc ParameterValue.one
-{-| Get the swept angle of an arc in radians.
-
- Arc2d.sweptAngle exampleArc
- --> 1.5708
-
-The result will be positive for a counterclockwise arc and negative for a
-clockwise one.
-
--}
+{-| -}
sweptAngle : Arc2d -> Float
sweptAngle (Types.Arc2d properties) =
properties.sweptAngle
-{-| Get the point along an arc at a given parameter value:
-
- Arc2d.pointOn exampleArc ParameterValue.zero
- --> Point2d.fromCoordinates ( 3, 1 )
-
- Arc2d.pointOn exampleArc ParameterValue.half
- --> Point2d.fromCoordinates ( 2.4142, 2.4142 )
-
- Arc2d.pointOn exampleArc ParameterValue.one
- --> Point2d.fromCoordinates ( 1, 3 )
-
--}
+{-| -}
pointOn : Arc2d -> ParameterValue -> Point2d
pointOn (Types.Arc2d arc) parameterValue =
let
@@ -628,32 +393,13 @@ pointOn (Types.Arc2d arc) parameterValue =
)
-{-| Get points along an arc at a given set of parameter values:
-
- exampleArc |> Arc2d.pointsAt (ParameterValue.steps 2)
- --> [ Point2d.fromCoordinates ( 3, 1 )
- --> , Point2d.fromCoordinates ( 2.4142, 2.4142 )
- --> , Point2d.fromCoordinates ( 1, 3 )
- --> ]
-
--}
+{-| -}
pointsAt : List ParameterValue -> Arc2d -> List Point2d
pointsAt parameterValues arc =
List.map (pointOn arc) parameterValues
-{-| Get the first derivative of an arc at a given parameter value:
-
- Arc2d.firstDerivative exampleArc ParameterValue.zero
- --> Vector2d.fromComponents ( 0, 3.1416 )
-
- Arc2d.firstDerivative exampleArc ParameterValue.half
- --> Vector2d.fromComponents ( -2.2214, 2.2214 )
-
- Arc2d.firstDerivative exampleArc ParameterValue.one
- --> Vector2d.fromComponents ( -3.1416, 0 )
-
--}
+{-| -}
firstDerivative : Arc2d -> ParameterValue -> Vector2d
firstDerivative (Types.Arc2d arc) =
let
@@ -668,43 +414,18 @@ firstDerivative (Types.Arc2d arc) =
startDerivative |> Vector2d.rotateBy (t * arc.sweptAngle)
-{-| Evaluate the first derivative of an arc at a given set of parameter values:
-
- exampleArc
- |> Arc2d.firstDerivativesAt
- (ParameterValue.steps 2)
- --> [ Vector2d.fromComponents ( 0, 3.1416 )
- --> , Vector2d.fromComponents ( -2.2214, 2.2214 )
- --> , Vector2d.fromComponents ( -3.1416, 0 )
- --> ]
-
--}
+{-| -}
firstDerivativesAt : List ParameterValue -> Arc2d -> List Vector2d
firstDerivativesAt parameterValues arc =
List.map (firstDerivative arc) parameterValues
-{-| If a curve has zero length (consists of just a single point), then we say
-that it is 'degenerate'. Some operations such as computing tangent directions
-are not defined on degenerate curves.
-
-A `Nondegenerate` value represents an arc that is definitely not degenerate. It
-is used as input to functions such as `Arc2d.tangentDirection` and can be
-constructed using `Arc2d.nondegenerate`.
-
--}
+{-| -}
type Nondegenerate
= Nondegenerate Arc2d
-{-| Attempt to construct a nondegenerate arc from a general `Arc2d`. If the arc
-is in fact degenerate (consists of a single point), returns an `Err` with that
-point.
-
- Arc2d.nondegenerate exampleArc
- --> Ok nondegenerateExampleArc
-
--}
+{-| -}
nondegenerate : Arc2d -> Result Point2d Nondegenerate
nondegenerate arc =
let
@@ -717,33 +438,13 @@ nondegenerate arc =
Ok (Nondegenerate arc)
-{-| Convert a nondegenerate arc back to a general `Arc2d`.
-
- Arc2d.fromNondegenerate nondegenerateExampleArc
- --> exampleArc
-
--}
+{-| -}
fromNondegenerate : Nondegenerate -> Arc2d
fromNondegenerate (Nondegenerate arc) =
arc
-{-| Get the tangent direction to a nondegenerate arc at a given parameter
-value:
-
- Arc2d.tangentDirection nondegenerateExampleArc
- ParameterValue.zero
- --> Direction2d.fromAngle (degrees 90)
-
- Arc2d.tangentDirection nondegenerateExampleArc
- ParameterValue.half
- --> Direction2d.fromAngle (degrees 135)
-
- Arc2d.tangentDirection nondegenerateExampleArc
- ParameterValue.one
- --> Direction2d.fromAngle (degrees 180)
-
--}
+{-| -}
tangentDirection : Nondegenerate -> ParameterValue -> Direction2d
tangentDirection (Nondegenerate (Types.Arc2d arc)) parameterValue =
let
@@ -753,45 +454,13 @@ tangentDirection (Nondegenerate (Types.Arc2d arc)) parameterValue =
arc.xDirection |> Direction2d.rotateBy (t * arc.sweptAngle)
-{-| Get tangent directions to a nondegenerate arc at a given set of parameter
-values:
-
- nondegenerateExampleArc
- |> Arc2d.tangentDirectionsAt
- (ParameterValue.steps 2)
- --> [ Direction2d.fromAngle (degrees 90)
- --> , Direction2d.fromAngle (degrees 135)
- --> , Direction2d.fromAngle (degrees 180)
- --> ]
-
--}
+{-| -}
tangentDirectionsAt : List ParameterValue -> Nondegenerate -> List Direction2d
tangentDirectionsAt parameterValues nondegenerateArc =
List.map (tangentDirection nondegenerateArc) parameterValues
-{-| Get both the point and tangent direction of a nondegenerate arc at a given
-parameter value:
-
- Arc2d.sample nondegenerateExampleArc
- ParameterValue.zero
- --> ( Point2d.fromCoordinates ( 3, 1 )
- --> , Direction2d.fromAngle (degrees 90)
- --> )
-
- Arc2d.sample nondegenerateExampleArc
- ParameterValue.half
- --> ( Point2d.fromCoordinates ( 2.4142, 2.4142 )
- --> , Direction2d.fromAngle (degrees 135)
- --> )
-
- Arc2d.sample nondegenerateExampleArc
- ParameterValue.one
- --> ( Point2d.fromCoordinates ( 1, 3 )
- --> , Direction2d.fromAngle (degrees 180)
- --> )
-
--}
+{-| -}
sample : Nondegenerate -> ParameterValue -> ( Point2d, Direction2d )
sample nondegenerateArc parameterValue =
( pointOn (fromNondegenerate nondegenerateArc) parameterValue
@@ -799,23 +468,7 @@ sample nondegenerateArc parameterValue =
)
-{-| Get points and tangent directions of a nondegenerate arc at a given set of
-parameter values:
-
- nondegenerateExampleArc
- |> Arc2d.samplesAt (ParameterValue.steps 2)
- --> [ ( Point2d.fromCoordinates ( 3, 1 )
- --> , Direction2d.fromAngle (degrees 90)
- --> )
- --> , ( Point2d.fromCoordinates ( 2.4142, 2.4142 )
- --> , Direction2d.fromAngle (degrees 135)
- --> )
- --> , ( Point2d.fromCoordinates ( 1, 3 )
- --> , Direction2d.fromAngle (degrees 180)
- --> )
- --> ]
-
--}
+{-| -}
samplesAt : List ParameterValue -> Nondegenerate -> List ( Point2d, Direction2d )
samplesAt parameterValues nondegenerateArc =
List.map (sample nondegenerateArc) parameterValues
@@ -837,20 +490,7 @@ numApproximationSegments maxError arc =
ceiling (abs (sweptAngle arc) / maxSegmentAngle)
-{-| Approximate an arc as a polyline, within a given tolerance:
-
- exampleArc |> Arc2d.toPolyline { maxError = 0.1 }
- --> Polyline2d.fromVertices
- --> [ Point2d.fromCoordinates ( 3, 1 )
- --> , Point2d.fromCoordinates ( 2.732, 2 )
- --> , Point2d.fromCoordinates ( 2, 2.732 )
- --> , Point2d.fromCoordinates ( 1, 3 )
- --> ]
-
-In this example, every point on the returned polyline will be within 0.1 units
-of the original arc.
-
--}
+{-| -}
toPolyline : { maxError : Float } -> Arc2d -> Polyline2d
toPolyline { maxError } arc =
let
@@ -863,16 +503,7 @@ toPolyline { maxError } arc =
Polyline2d.fromVertices points
-{-| Reverse the direction of an arc, so that the start point becomes the end
-point and vice versa.
-
- Arc2d.reverse exampleArc
- --> Point2d.fromCoordinates ( 1, 3 )
- --> |> Arc2d.sweptAround
- --> (Point2d.fromCoordinates ( 1, 1 ))
- --> (degrees -90)
-
--}
+{-| -}
reverse : Arc2d -> Arc2d
reverse ((Types.Arc2d arc) as arc_) =
Types.Arc2d
@@ -883,18 +514,7 @@ reverse ((Types.Arc2d arc) as arc_) =
}
-{-| Scale an arc about a given point by a given scale.
-
- point =
- Point2d.fromCoordinates ( 0, 1 )
-
- Arc2d.scaleAbout point 2 exampleArc
- --> Point2d.fromCoordinates ( 6, 1 )
- --> |> Arc2d.sweptAround
- --> (Point2d.fromCoordinates ( 2, 1 ))
- --> (degrees 90)
-
--}
+{-| -}
scaleAbout : Point2d -> Float -> Arc2d -> Arc2d
scaleAbout point scale (Types.Arc2d arc) =
Types.Arc2d
@@ -909,15 +529,7 @@ scaleAbout point scale (Types.Arc2d arc) =
}
-{-| Rotate an arc around a given point by a given angle.
-
- Arc2d.rotateAround Point2d.origin (degrees 90)
- --> Point2d.fromCoordinates ( -1, 3 )
- --> |> Arc2d.sweptAround
- --> (Point2d.fromCoordinates ( -1, 1 ))
- --> (degrees 90)
-
--}
+{-| -}
rotateAround : Point2d -> Float -> Arc2d -> Arc2d
rotateAround point angle =
let
@@ -936,18 +548,7 @@ rotateAround point angle =
}
-{-| Translate an arc by a given displacement.
-
- displacement =
- Vector2d.fromComponents ( 2, 3 )
-
- Arc2d.translateBy displacement exampleArc
- --> Point2d.fromCoordinates ( 5, 4 )
- --> |> Arc2d.sweptAround
- --> (Point2d.fromCoordinates ( 3, 4 ))
- --> (degrees 90)
-
--}
+{-| -}
translateBy : Vector2d -> Arc2d -> Arc2d
translateBy displacement (Types.Arc2d arc) =
Types.Arc2d
@@ -958,30 +559,13 @@ translateBy displacement (Types.Arc2d arc) =
}
-{-| Translate an arc in a given direction by a given distance;
-
- Arc2d.translateIn direction distance
-
-is equivalent to
-
- Arc2d.translateBy
- (Vector2d.withLength distance direction)
-
--}
+{-| -}
translateIn : Direction2d -> Float -> Arc2d -> Arc2d
translateIn direction distance arc =
translateBy (Vector2d.withLength distance direction) arc
-{-| Mirror an arc across a given axis.
-
- Arc2d.mirrorAcross Axis2d.y exampleArc
- --> Point2d.fromCoordinates ( -3, 1 )
- --> |> Arc2d.sweptAround
- --> (Point2d.fromCoordinates ( -1, 1 ))
- --> (degrees -90)
-
--}
+{-| -}
mirrorAcross : Axis2d -> Arc2d -> Arc2d
mirrorAcross axis =
let
@@ -1000,19 +584,7 @@ mirrorAcross axis =
}
-{-| Take an arc defined in global coordinates, and return it expressed in local
-coordinates relative to a given reference frame.
-
- localFrame =
- Frame2d.atPoint (Point2d.fromCoordinates ( 1, 2 ))
-
- Arc2d.relativeTo localFrame exampleArc
- --> Point2d.fromCoordinates ( 2, -1 )
- --> |> Arc2d.sweptAround
- --> (Point2d.fromCoordinates ( 0, -1 ))
- --> (degrees 90)
-
--}
+{-| -}
relativeTo : Frame2d -> Arc2d -> Arc2d
relativeTo frame (Types.Arc2d arc) =
if Frame2d.isRightHanded frame then
@@ -1033,19 +605,7 @@ relativeTo frame (Types.Arc2d arc) =
}
-{-| Take an arc considered to be defined in local coordinates relative to a
-given reference frame, and return that arc expressed in global coordinates.
-
- localFrame =
- Frame2d.atPoint (Point2d.fromCoordinates ( 1, 2 ))
-
- Arc2d.placeIn localFrame exampleArc
- --> Point2d.fromCoordinates ( 4, 3 )
- --> |> Arc2d.sweptAround
- --> (Point2d.fromCoordinates ( 2, 3 ))
- --> (degrees 90)
-
--}
+{-| -}
placeIn : Frame2d -> Arc2d -> Arc2d
placeIn frame (Types.Arc2d arc) =
if Frame2d.isRightHanded frame then
diff --git a/src/Arc3d.elm b/src/Arc3d.elm
index 503db608..56a8a864 100644
--- a/src/Arc3d.elm
+++ b/src/Arc3d.elm
@@ -108,30 +108,7 @@ type alias Arc3d =
Types.Arc3d
-{-| Construct a 3D arc lying _on_ a sketch plane by providing a 2D arc specified
-in XY coordinates _within_ the sketch plane.
-
- arc =
- Arc3d.on SketchPlane3d.xz
- (Point2d.fromCoordinates ( 3, 1 )
- |> Arc2d.sweptAround
- (Point2d.fromCoordinates ( 1, 1 )
- (degrees 90)
- )
-
- Arc3d.centerPoint arc
- --> Point3d.fromCoordinates ( 1, 0, 1 )
-
- Arc3d.radius arc
- --> 2
-
- Arc3d.startPoint arc
- --> Point3d.fromCoordinates ( 3, 0, 1 )
-
- Arc3d.endPoint arc
- --> Point3d.fromCoordinates ( 1, 0, 3 )
-
--}
+{-| -}
on : SketchPlane3d -> Arc2d -> Arc3d
on sketchPlane (Types.Arc2d arc2d) =
Types.Arc3d
@@ -145,24 +122,7 @@ on sketchPlane (Types.Arc2d arc2d) =
}
-{-| Construct an arc by sweeping the given point around the given axis by the
-given angle:
-
- exampleArc =
- Point3d.fromCoordinates ( 1, 1, 0 )
- |> Arc3d.sweptAround Axis3d.z (degrees 90)
-
- Arc3d.centerPoint exampleArc
- --> Point3d.origin
-
- Arc3d.endPoint exampleArc
- --> Point3d.fromCoordinates ( -1, 1, 0 )
-
-Positive swept angles result in a counterclockwise (right-handed) rotation
-around the given axis and vice versa for negative swept angles. The center point
-of the returned arc will lie on the given axis.
-
--}
+{-| -}
sweptAround : Axis3d -> Float -> Point3d -> Arc3d
sweptAround axis_ sweptAngle_ startPoint_ =
let
@@ -205,31 +165,7 @@ sweptAround axis_ sweptAngle_ startPoint_ =
}
-{-| Attempt to construct an arc that starts at the first given point, passes
-through the second given point and ends at the third given point. If the three
-points are collinear, returns `Nothing`.
-
- p1 =
- Point3d.fromCoordinates ( 0, 0, 1 )
-
- p2 =
- Point3d.origin
-
- p3 =
- Point3d.fromCoordinates ( 0, 1, 0 )
-
- Arc3d.throughPoints p1 p2 p3
- --> Just
- --> (Arc3d.on SketchPlane3d.yz
- --> Point2d.fromCoordinates ( 0, 1 )
- --> |> Arc2d.sweptAround
- --> (Point2d.fromCoordinates
- --> ( 0.5, 0.5 )
- --> )
- --> (degrees 180)
- --> )
-
--}
+{-| -}
throughPoints : Point3d -> Point3d -> Point3d -> Maybe Arc3d
throughPoints firstPoint secondPoint thirdPoint =
SketchPlane3d.throughPoints firstPoint secondPoint thirdPoint
@@ -243,12 +179,7 @@ throughPoints firstPoint secondPoint thirdPoint =
)
-{-| Get the axial direction of an arc.
-
- Arc3d.axialDirection exampleArc
- --> Direction3d.z
-
--}
+{-| -}
axialDirection : Arc3d -> Direction3d
axialDirection (Types.Arc3d arc) =
let
@@ -260,24 +191,13 @@ axialDirection (Types.Arc3d arc) =
Direction3d.unsafe (Vector3d.components axialDirectionVector)
-{-| Get the central axis of an arc. The origin point of the axis will be equal
-to the center point of the arc.
-
- Arc3d.axis exampleArc
- --> Axis3d.z
-
--}
+{-| -}
axis : Arc3d -> Axis3d
axis arc =
Axis3d.through (centerPoint arc) (axialDirection arc)
-{-| Get the center point of an arc.
-
- Arc3d.centerPoint exampleArc
- --> Point3d.origin
-
--}
+{-| -}
centerPoint : Arc3d -> Point3d
centerPoint (Types.Arc3d arc) =
let
@@ -287,45 +207,25 @@ centerPoint (Types.Arc3d arc) =
arc.startPoint |> Point3d.translateIn arc.yDirection radius_
-{-| Get the radius of an arc.
-
- Arc3d.radius exampleArc
- --> 1.4142
-
--}
+{-| -}
radius : Arc3d -> Float
radius (Types.Arc3d arc) =
arc.signedLength / arc.sweptAngle
-{-| Get the start point of an arc.
-
- Arc3d.startPoint exampleArc
- --> Point3d.fromCoordinates ( 1, 1, 0 )
-
--}
+{-| -}
startPoint : Arc3d -> Point3d
startPoint (Types.Arc3d arc) =
arc.startPoint
-{-| Get the end point of an arc.
-
- Arc3d.endPoint exampleArc
- --> Point3d.fromCoordinates ( -1, 1, 0 )
-
--}
+{-| -}
endPoint : Arc3d -> Point3d
endPoint arc =
pointOn arc ParameterValue.one
-{-| Get the point along an arc at a given parameter value:
-
- Arc3d.pointOn exampleArc ParameterValue.half
- --> Point3d.fromCoordinates ( 0, 1.4142, 0 )
-
--}
+{-| -}
pointOn : Arc3d -> ParameterValue -> Point3d
pointOn (Types.Arc3d arc) parameterValue =
let
@@ -381,29 +281,13 @@ pointOn (Types.Arc3d arc) parameterValue =
)
-{-| Get points along an arc at a given set of parameter values.
-
- exampleArc |> Arc3d.pointsAt (ParameterValue.steps 2)
- --> [ Point3d ( 1, 1, 0 )
- --> , Point3d ( 0, 1.4142, 0 )
- --> , Point3d ( -1, 1, 0 )
- --> ]
-
--}
+{-| -}
pointsAt : List ParameterValue -> Arc3d -> List Point3d
pointsAt parameterValues arc =
List.map (pointOn arc) parameterValues
-{-| Get the first derivative of an arc at a given parameter value.
-
- Arc3d.firstDerivative exampleArc ParameterValue.zero
- --> Vector3d.fromComponents ( -1.5708, 1.5708, 0 )
-
- Arc3d.firstDerivative exampleArc ParameterValue.one
- --> Vector3d.fromComponents ( -1.5708, -1.5708, 0 )
-
--}
+{-| -}
firstDerivative : Arc3d -> ParameterValue -> Vector3d
firstDerivative (Types.Arc3d arc) =
let
@@ -440,43 +324,18 @@ firstDerivative (Types.Arc3d arc) =
)
-{-| Evaluate the first derivative of an arc at a range of parameter values.
-
- exampleArc
- |> Arc3d.firstDerivativesAt
- (ParameterValue.steps 2)
- --> [ Vector3d ( -1.5708, 1.5708, 0 )
- --> , Vector3d ( -2.2214, 0, 0 )
- --> , Vector3d ( -1.5708, -1.5708, 0 )
- --> ]
-
--}
+{-| -}
firstDerivativesAt : List ParameterValue -> Arc3d -> List Vector3d
firstDerivativesAt parameterValues arc =
List.map (firstDerivative arc) parameterValues
-{-| If a curve has zero length (consists of just a single point), then we say
-that it is 'degenerate'. Some operations such as computing tangent directions
-are not defined on degenerate curves.
-
-A `Nondegenerate` value represents an arc that is definitely not degenerate. It
-is used as input to functions such as `Arc3d.tangentDirection` and can be
-constructed using `Arc3d.nondegenerate`.
-
--}
+{-| -}
type Nondegenerate
= Nondegenerate Arc3d
-{-| Attempt to construct a nondegenerate arc from a general `Arc3d`. If the arc
-is in fact degenerate (consists of a single point), returns an `Err` with that
-point.
-
- Arc3d.nondegenerate exampleArc
- --> Ok nondegenerateExampleArc
-
--}
+{-| -}
nondegenerate : Arc3d -> Result Point3d Nondegenerate
nondegenerate arc =
let
@@ -489,37 +348,13 @@ nondegenerate arc =
Ok (Nondegenerate arc)
-{-| Convert a nondegenerate arc back to a general `Arc3d`.
-
- Arc3d.fromNondegenerate nondegenerateExampleArc
- --> exampleArc
-
--}
+{-| -}
fromNondegenerate : Nondegenerate -> Arc3d
fromNondegenerate (Nondegenerate arc) =
arc
-{-| Get the tangent direction to a nondegenerate arc at a given parameter
-value:
-
- Arc3d.tangentDirection nondegenerateExampleArc
- ParameterValue.zero
- --> Direction3d.fromAzimuthAndElevation
- --> (degrees 135)
- --> (degrees 0)
-
- Arc3d.tangentDirection nondegenerateExampleArc
- ParameterValue.half
- --> Direction3d.negativeX
-
- Arc3d.tangentDirection nondegenerateExampleArc
- ParameterValue.zero
- --> Direction3d.fromAzimuthAndElevation
- --> (degrees 225)
- --> (degrees 0)
-
--}
+{-| -}
tangentDirection : Nondegenerate -> ParameterValue -> Direction3d
tangentDirection (Nondegenerate (Types.Arc3d arc)) parameterValue =
let
@@ -551,53 +386,13 @@ tangentDirection (Nondegenerate (Types.Arc3d arc)) parameterValue =
)
-{-| Get tangent directions to a nondegenerate arc at a given set of parameter
-values:
-
- nondegenerateExampleArc
- |> Arc3d.tangentDirectionsAt
- (ParameterValue.steps 2)
- --> [ Direction3d.fromAzimuthAndElevation
- --> (degrees 135)
- --> (degrees 0)
- --> , Direction3d.negativeX
- --> , Direction3d.fromAzimuthAndElevation
- --> (degrees 225)
- --> (degrees 0)
- --> ]
-
--}
+{-| -}
tangentDirectionsAt : List ParameterValue -> Nondegenerate -> List Direction3d
tangentDirectionsAt parameterValues nondegenerateArc =
List.map (tangentDirection nondegenerateArc) parameterValues
-{-| Get both the point and tangent direction of a nondegenerate arc at a given
-parameter value:
-
- Arc3d.sample nondegenerateExampleArc
- ParameterValue.zero
- --> ( Point3d.fromCoordinates ( 1, 1, 0 )
- --> , Direction3d.fromAzimuthAndElevation
- --> (degrees 135)
- --> (degrees 0)
- --> )
-
- Arc3d.sample nondegenerateExampleArc
- ParameterValue.half
- --> ( Point3d.fromCoordinates ( 0, 1.4142, 0 )
- --> , Direction3d.negativeX
- --> )
-
- Arc3d.sample nondegenerateExampleArc
- ParameterValue.one
- --> ( Point3d.fromCoordinates ( -1, 1, 0 )
- --> , Direction3d.fromAzimuthAndElevation
- --> (degrees 225)
- --> (degrees 0)
- --> )
-
--}
+{-| -}
sample : Nondegenerate -> ParameterValue -> ( Point3d, Direction3d )
sample nondegenerateArc parameterValue =
( pointOn (fromNondegenerate nondegenerateArc) parameterValue
@@ -605,30 +400,7 @@ sample nondegenerateArc parameterValue =
)
-{-| Get points and tangent directions of a nondegenerate arc at a given set of
-parameter values:
-
- nondegenerateExampleArc
- |> Arc3d.samplesAt (ParameterValue.steps 2)
- --> [ ( Point3d.fromCoordinates ( 1, 1, 0 )
- --> , Direction3d.fromAzimuthAndElevation
- --> (degrees 135)
- --> (degrees 0)
- --> )
- --> , ( Point3d.fromCoordinates ( 0, 1.4142, 0 )
- --> , Direction3d.negativeX
- --> )
- --> , ( Point3d.fromCoordinates ( -1, 1, 0 )
- --> , Direction3d.fromAzimuthAndElevation
- --> (degrees 225)
- --> (degrees 0)
- --> )
- --> ]
-
-If the arc is degenerate (start point and end point are equal), returns an
-empty list.
-
--}
+{-| -}
samplesAt : List ParameterValue -> Nondegenerate -> List ( Point3d, Direction3d )
samplesAt parameterValues nondegenerateArc =
List.map (sample nondegenerateArc) parameterValues
@@ -650,20 +422,7 @@ numApproximationSegments maxError arc =
ceiling (abs (sweptAngle arc) / maxSegmentAngle)
-{-| Approximate an arc as a polyline, within a given tolerance:
-
- exampleArc |> Arc3d.toPolyline { maxError = 0.1 }
- --> Polyline3d.fromVertices
- --> [ Point3d.fromCoordinates ( 1, 1, 0 )
- --> , Point3d.fromCoordinates ( 0.366, 1.366, 0 )
- --> , Point3d.fromCoordinates ( -0.366, 1.366, 0 )
- --> , Point3d.fromCoordinates ( -1, 1, 0 )
- --> ]
-
-In this example, every point on the returned polyline will be within 0.1 units
-of the original arc.
-
--}
+{-| -}
toPolyline : { maxError : Float } -> Arc3d -> Polyline3d
toPolyline { maxError } arc =
let
@@ -676,31 +435,13 @@ toPolyline { maxError } arc =
Polyline3d.fromVertices points
-{-| Get the swept angle of an arc in radians.
-
- Arc3d.sweptAngle exampleArc
- --> 1.5708
-
-A positive swept angle means that the arc is formed by rotating the given start
-point counterclockwise around the central axis, and vice versa for a negative
-angle.
-
--}
+{-| -}
sweptAngle : Arc3d -> Float
sweptAngle (Types.Arc3d properties) =
properties.sweptAngle
-{-| Reverse the direction of an arc, so that the start point becomes the end
-point and vice versa. The resulting arc will have the same axis as the original
-but a swept angle with the opposite sign.
-
- Arc3d.reverse exampleArc
- --> Arc3d.sweptAround Axis3d.z
- --> (degrees -90)
- --> (Point3d.fromCoordinates ( -1, 1, 0 ))
-
--}
+{-| -}
reverse : Arc3d -> Arc3d
reverse ((Types.Arc3d arc) as arc_) =
let
@@ -738,20 +479,7 @@ reverse ((Types.Arc3d arc) as arc_) =
}
-{-| Scale an arc about the given center point by the given scale.
-
- point =
- Point3d.fromCoordinates ( 0, -1, 0 )
-
- Arc3d.scaleAbout point 2 exampleArc
- --> Arc3d.sweptAround
- --> (Axis3d.withDirection Direction3d.z
- --> (Point3d.fromCoordinates ( 0, 1, 0 ))
- --> )
- --> (degrees 90)
- --> (Point3d.fromCoordinates ( 2, 3, 0 ))
-
--}
+{-| -}
scaleAbout : Point3d -> Float -> Arc3d -> Arc3d
scaleAbout point scale (Types.Arc3d arc) =
Types.Arc3d
@@ -771,14 +499,7 @@ scaleAbout point scale (Types.Arc3d arc) =
}
-{-| Rotate an arc around a given axis by a given angle (in radians).
-
- Arc3d.rotateAround Axis3d.x (degrees 90) exampleArc
- --> Arc3d.sweptAround (Axis3d.reverse Axis3d.y)
- --> (degrees 90)
- --> (Point3d.fromCoordinates ( 1, 0, 1 ))
-
--}
+{-| -}
rotateAround : Axis3d -> Float -> Arc3d -> Arc3d
rotateAround rotationAxis angle =
let
@@ -798,20 +519,7 @@ rotateAround rotationAxis angle =
}
-{-| Translate an arc by a given displacement.
-
- displacement =
- Vector3d.fromComponents ( 2, 1, 3 )
-
- Arc3d.translateBy displacement exampleArc
- --> Arc3d.sweptAround
- --> (Axis3d.withDirection Direction3d.z
- --> (Point3d ( 2, 1, 3 ))
- --> )
- --> (degrees 90)
- --> (Point3d.fromCoordinates ( 3, 2, 3 ))
-
--}
+{-| -}
translateBy : Vector3d -> Arc3d -> Arc3d
translateBy displacement (Types.Arc3d arc) =
Types.Arc3d
@@ -823,31 +531,13 @@ translateBy displacement (Types.Arc3d arc) =
}
-{-| Translate an arc in a given direction by a given distance;
-
- Arc3d.translateIn direction distance
-
-is equivalent to
-
- Arc3d.translateBy
- (Vector3d.withLength distance direction)
-
--}
+{-| -}
translateIn : Direction3d -> Float -> Arc3d -> Arc3d
translateIn direction distance arc =
translateBy (Vector3d.withLength distance direction) arc
-{-| Mirror an arc across a given plane.
-
- Arc3d.mirrorAcross Plane3d.xy exampleArc
- --> Arc3d.sweptAround (Axis3d.reverse Axis3d.z)
- --> (degrees -90)
- --> (Point3d.fromCoordinates ( 1, 1, 0 ))
-
-Note that this flips the sign of the arc's swept angle.
-
--}
+{-| -}
mirrorAcross : Plane3d -> Arc3d -> Arc3d
mirrorAcross plane =
let
@@ -867,35 +557,7 @@ mirrorAcross plane =
}
-{-| Project an arc into a sketch plane.
-
- axis : Axis3d
- axis =
- Axis3d.through
- (Point3d.fromCoordinates ( 1, 2, 3 ))
- (Direction3d.fromAzimuthAndElevation
- (degrees 0)
- (degrees 45)
- )
-
- arc : Arc3d
- arc =
- Arc3d.sweptAround axis
- (degrees 45)
- (Point3d.fromCoordinates ( 1, 4, 3 ))
-
- Arc3d.projectInto SketchPlane3d.xy arc
- --> EllipticalArc2d.with
- --> { centerPoint =
- --> Point2d.fromCoordinates ( 1, 2 )
- --> , xDirection = Direction2d.y
- --> , xRadius = 2
- --> , yRadius = 1.4142
- --> , startAngle = degrees 0
- --> , sweptAngle = degrees 45
- --> }
-
--}
+{-| -}
projectInto : SketchPlane3d -> Arc3d -> Types.EllipticalArc2d
projectInto sketchPlane arc =
let
@@ -977,22 +639,7 @@ projectInto sketchPlane arc =
}
-{-| Take an arc defined in global coordinates, and return it expressed in local
-coordinates relative to a given reference frame.
-
- localFrame =
- Frame3d.atPoint
- (Point3d.fromCoordinates ( 1, 2, 3 ))
-
- Arc3d.relativeTo localFrame exampleArc
- --> Arc3d.sweptAround
- --> (Axis3d.withDirection Direction3d.z
- --> (Point3d ( -1, -2, -3 ))
- --> )
- --> (degrees 90)
- --> (Point3d.fromCoordinates ( 0, -1, -3 ))
-
--}
+{-| -}
relativeTo : Frame3d -> Arc3d -> Arc3d
relativeTo frame (Types.Arc3d arc) =
if Frame3d.isRightHanded frame then
@@ -1015,22 +662,7 @@ relativeTo frame (Types.Arc3d arc) =
}
-{-| Take an arc considered to be defined in local coordinates relative to a
-given reference frame, and return that arc expressed in global coordinates.
-
- localFrame =
- Frame3d.atPoint
- (Point3d.fromCoordinates ( 1, 2, 3 ))
-
- Arc3d.placeIn localFrame exampleArc
- --> Arc3d.sweptAround
- --> (Axis3d.withDirection Direction3d.z
- --> (Point3d.fromCoordinates ( 1, 2, 3 ))
- --> )
- --> (degrees 90)
- --> (Point3d.fromCoordinates ( 2, 3, 3 ))
-
--}
+{-| -}
placeIn : Frame3d -> Arc3d -> Arc3d
placeIn frame (Types.Arc3d arc) =
if Frame3d.isRightHanded frame then
diff --git a/src/Axis2d.elm b/src/Axis2d.elm
index 61d37e84..a8fddc2f 100644
--- a/src/Axis2d.elm
+++ b/src/Axis2d.elm
@@ -63,9 +63,6 @@ an origin point and direction. Axes have several uses, such as:
# Coordinate conversions
-Functions for transforming axes between local and global coordinates in
-different coordinate frames.
-
@docs relativeTo, placeIn
-}
@@ -81,117 +78,55 @@ type alias Axis2d =
Types.Axis2d
-{-| The global X axis.
-
- Axis2d.x
- --> Axis2d.through Point2d.origin Direction2d.x
-
--}
+{-| -}
x : Axis2d
x =
through Point2d.origin Direction2d.x
-{-| The global Y axis.
-
- Axis2d.y
- --> Axis2d.through Point2d.origin Direction2d.y
-
--}
+{-| -}
y : Axis2d
y =
through Point2d.origin Direction2d.y
-{-| Construct an axis through the given origin point with the given direction.
-
- exampleAxis =
- Axis2d.through (Point2d.fromCoordinates ( 1, 3 ))
- (Direction2d.fromAngle (degrees 30))
-
--}
+{-| -}
through : Point2d -> Direction2d -> Axis2d
through point direction_ =
Types.Axis2d { originPoint = point, direction = direction_ }
-{-| Construct an axis with the given direction, through the given origin point.
-Flipped version of `through`. Having both versions allow you to do different
-things with partial application:
-
- -- A list of axes in different directions all passing
- -- through the same origin point
- List.map (Axis2d.through point) directions
-
- -- A list of parallel axes (all having the same
- -- direction) through different points
- List.map (Axis2d.withDirection direction) points
-
--}
+{-| -}
withDirection : Direction2d -> Point2d -> Axis2d
withDirection direction_ originPoint_ =
Types.Axis2d { originPoint = originPoint_, direction = direction_ }
-{-| Get the origin point of an axis.
-
- Axis2d.originPoint exampleAxis
- --> Point2d.fromCoordinates ( 1, 3 )
-
--}
+{-| -}
originPoint : Axis2d -> Point2d
originPoint (Types.Axis2d axis) =
axis.originPoint
-{-| Get the direction of an axis.
-
- Axis2d.direction exampleAxis
- --> Direction2d.fromAngle (degrees 30)
-
--}
+{-| -}
direction : Axis2d -> Direction2d
direction (Types.Axis2d axis) =
axis.direction
-{-| Reverse the direction of an axis while keeping the same origin point.
-
- Axis2d.reverse exampleAxis
- --> Axis2d.through (Point2d.fromCoordinates ( 1, 3 ))
- --> (Direction2d.fromAngle (degrees -150))
-
--}
+{-| -}
reverse : Axis2d -> Axis2d
reverse (Types.Axis2d axis) =
through axis.originPoint (Direction2d.reverse axis.direction)
-{-| Move an axis so that it has the given origin point but unchanged direction.
-
- newOrigin =
- Point2d.fromCoordinates ( 4, 5 )
-
- Axis2d.moveTo newOrigin exampleAxis
- --> Axis2d.through (Point2d.fromCoordinates ( 4, 5 ))
- --> (Direction2d.fromAngle (degrees 30))
-
--}
+{-| -}
moveTo : Point2d -> Axis2d -> Axis2d
moveTo newOrigin (Types.Axis2d axis) =
through newOrigin axis.direction
-{-| Rotate an axis around a given center point by a given angle. Rotates the
-axis' origin point around the given point by the given angle and the axis'
-direction by the given angle.
-
- exampleAxis
- |> Axis2d.rotateAround Point2d.origin (degrees 90)
- --> Axis2d.through (Point2d.fromCoordinates ( -3, 1 ))
- --> (Direction2d.fromAngle (degrees 120))
-
--}
+{-| -}
rotateAround : Point2d -> Float -> Axis2d -> Axis2d
rotateAround centerPoint angle =
let
@@ -205,79 +140,33 @@ rotateAround centerPoint angle =
through (rotatePoint axis.originPoint) (rotateDirection axis.direction)
-{-| Translate an axis by a given displacement. Applies the given displacement to
-the axis' origin point and leaves the direction unchanged.
-
- displacement =
- Vector2d.fromComponents ( 2, 3 )
-
- Axis2d.translateBy displacement exampleAxis
- --> Axis2d.through (Point2d.fromCoordinates ( 3, 6 ))
- --> (Direction2d.fromAngle (degrees 30))
-
--}
+{-| -}
translateBy : Vector2d -> Axis2d -> Axis2d
translateBy vector (Types.Axis2d axis) =
through (Point2d.translateBy vector axis.originPoint) axis.direction
-{-| Translate an axis in a given direction by a given distance;
-
- Axis2d.translateIn direction distance
-
-is equivalent to
-
- Axis2d.translateBy
- (Vector2d.withLength distance direction)
-
--}
+{-| -}
translateIn : Direction2d -> Float -> Axis2d -> Axis2d
translateIn translationDirection distance axis =
translateBy (Vector2d.withLength distance translationDirection) axis
-{-| Mirror one axis across another. The axis to mirror across is given first and
-the axis to mirror is given second.
-
- Axis2d.mirrorAcross Axis2d.x exampleAxis
- --> Axis2d.through (Point2d.fromCoordinates ( 1, -3 ))
- --> (Direction2d.fromAngle (degrees -30))
-
--}
+{-| -}
mirrorAcross : Axis2d -> Axis2d -> Axis2d
mirrorAcross otherAxis (Types.Axis2d axis) =
through (Point2d.mirrorAcross otherAxis axis.originPoint)
(Direction2d.mirrorAcross otherAxis axis.direction)
-{-| Take an axis defined in global coordinates, and return it expressed in local
-coordinates relative to a given reference frame.
-
- frame =
- Frame2d.atPoint (Point2d.fromCoordinates ( 2, 3 ))
-
- Axis2d.relativeTo frame exampleAxis
- --> Axis2d.through (Point2d.fromCoordinates ( -1, 0 ))
- --> (Direction2d.fromAngle (degrees 30))
-
--}
+{-| -}
relativeTo : Frame2d -> Axis2d -> Axis2d
relativeTo frame (Types.Axis2d axis) =
through (Point2d.relativeTo frame axis.originPoint)
(Direction2d.relativeTo frame axis.direction)
-{-| Take an axis defined in local coordinates relative to a given reference
-frame, and return that axis expressed in global coordinates.
-
- frame =
- Frame2d.atPoint (Point2d.fromCoordinates ( 2, 3 ))
-
- Axis2d.placeIn frame exampleAxis
- --> Axis2d.through (Point2d.fromCoordinates ( 3, 6 ))
- --> (Direction2d.fromAngle (degrees 30))
-
--}
+{-| -}
placeIn : Frame2d -> Axis2d -> Axis2d
placeIn frame (Types.Axis2d axis) =
through (Point2d.placeIn frame axis.originPoint)
diff --git a/src/Axis3d.elm b/src/Axis3d.elm
index 86757c37..e84f7853 100644
--- a/src/Axis3d.elm
+++ b/src/Axis3d.elm
@@ -67,9 +67,6 @@ an origin point and direction. Axes have several uses, such as:
# Coordinate conversions
-Functions for transforming axes between local and global coordinates in
-different coordinate frames.
-
@docs relativeTo, placeIn, projectInto
-}
@@ -86,157 +83,68 @@ type alias Axis3d =
Types.Axis3d
-{-| The global X axis.
-
- Axis3d.x
- --> Axis3d.through Point3d.origin Direction3d.x
-
--}
+{-| -}
x : Axis3d
x =
through Point3d.origin Direction3d.x
-{-| The global Y axis.
-
- Axis3d.y
- --> Axis3d.through Point3d.origin Direction3d.y
-
--}
+{-| -}
y : Axis3d
y =
through Point3d.origin Direction3d.y
-{-| The global Z axis.
-
- Axis3d.z
- --> Axis3d.through Point3d.origin Direction3d.z
-
--}
+{-| -}
z : Axis3d
z =
through Point3d.origin Direction3d.z
-{-| Construct an axis through the given point, with the given direction.
-
- exampleAxis =
- Axis3d.through
- (Point3d.fromCoordinates ( 1, 2, 3 ))
- Direction3d.y
-
--}
+{-| -}
through : Point3d -> Direction3d -> Axis3d
through point direction_ =
Types.Axis3d { originPoint = point, direction = direction_ }
-{-| Construct an axis with the given directoin, through the given point. Flipped
-version of `through`. Having both versions allow you to do different
-things with partial application:
-
- -- A list of axes in different directions all passing
- -- through the same origin point
- List.map (Axis3d.through point) directions
-
- -- A list of parallel axes (all having the same
- -- direction) through different points
- List.map (Axis3d.withDirection direction) points
-
--}
+{-| -}
withDirection : Direction3d -> Point3d -> Axis3d
withDirection direction_ originPoint_ =
Types.Axis3d { direction = direction_, originPoint = originPoint_ }
-{-| Construct a 3D axis lying _on_ a sketch plane by providing a 2D axis
-specified in XY coordinates _within_ the sketch plane.
-
- axis2d =
- Axis2d.through (Point2d.fromCoordinates ( 1, 3 ))
- (Direction2d.fromAngle (degrees 30))
-
- Axis3d.on SketchPlane3d.xy axis2d
- --> Axis3d.through
- --> (Point3d.fromCoordinates ( 1, 3, 0 ))
- --> (Direction3d.fromAzimuthAndElevation
- --> (degrees 30)
- --> (degrees 0)
- --> )
-
- Axis3d.on SketchPlane3d.zx axis2d
- --> Axis3d.through
- --> (Point3d.fromCoordinates ( 3, 0, 1 ))
- --> (Direction3d.fromAzimuthAndElevation
- --> (degrees 0)
- --> (degrees 60)
- --> )
-
--}
+{-| -}
on : SketchPlane3d -> Axis2d -> Axis3d
on sketchPlane (Types.Axis2d axis2d) =
through (Point3d.on sketchPlane axis2d.originPoint)
(Direction3d.on sketchPlane axis2d.direction)
-{-| Get the origin point of an axis.
-
- Axis3d.originPoint exampleAxis
- --> Point3d.fromCoordinates ( 1, 2, 3 )
-
--}
+{-| -}
originPoint : Axis3d -> Point3d
originPoint (Types.Axis3d axis) =
axis.originPoint
-{-| Get the direction of an axis.
-
- Axis3d.direction exampleAxis
- --> Direction3d.y
-
--}
+{-| -}
direction : Axis3d -> Direction3d
direction (Types.Axis3d axis) =
axis.direction
-{-| Reverse the direction of an axis while keeping the same origin point.
-
- Axis3d.reverse exampleAxis
- --> Axis3d.withDirection Direction3d.negativeY
- --> (Point3d.fromCoordinates ( 1, 2, 3 ))
-
--}
+{-| -}
reverse : Axis3d -> Axis3d
reverse (Types.Axis3d axis) =
through axis.originPoint (Direction3d.reverse axis.direction)
-{-| Move an axis so that it has the given origin point but unchanged direction.
-
- newOrigin =
- Point3d.fromCoordinates ( 3, 4, 5 )
-
- Axis3d.moveTo newOrigin exampleAxis
- --> Axis3d.withDirection Direction3d.y
- --> (Point3d.fromCoordinates ( 3, 4, 5 ))
-
--}
+{-| -}
moveTo : Point3d -> Axis3d -> Axis3d
moveTo newOrigin (Types.Axis3d axis) =
through newOrigin axis.direction
-{-| Rotate an axis around another axis by a given angle. The axis to rotate
-around is given first and the axis to rotate is given last.
-
- Axis3d.rotateAround Axis3d.z (degrees 90) exampleAxis
- --> Axis3d.withDirection Direction3d.negativeX
- --> (Point3d.fromCoordinates ( -2, 1, 3 ))
-
--}
+{-| -}
rotateAround : Axis3d -> Float -> Axis3d -> Axis3d
rotateAround otherAxis angle =
let
@@ -250,64 +158,26 @@ rotateAround otherAxis angle =
through (rotatePoint axis.originPoint) (rotateDirection axis.direction)
-{-| Translate an axis by a given displacement. Applies the given displacement to
-the axis' origin point and leaves the direction unchanged.
-
- displacement =
- Vector3d.fromComponents ( 3, 3, 3 )
-
- Axis3d.translateBy displacement exampleAxis
- --> Axis3d.withDirection Direction3d.y
- --> (Point3d.fromCoordinates ( 4, 5, 6 ))
-
--}
+{-| -}
translateBy : Vector3d -> Axis3d -> Axis3d
translateBy vector (Types.Axis3d axis) =
through (Point3d.translateBy vector axis.originPoint) axis.direction
-{-| Translate an axis in a given direction by a given distance;
-
- Axis3d.translateIn direction distance
-
-is equivalent to
-
- Axis3d.translateBy
- (Vector3d.withLength distance direction)
-
--}
+{-| -}
translateIn : Direction3d -> Float -> Axis3d -> Axis3d
translateIn translationDirection distance axis =
translateBy (Vector3d.withLength distance translationDirection) axis
-{-| Mirror an axis across a plane.
-
- Axis3d.mirrorAcross Plane3d.xy exampleAxis
- --> Axis3d.withDirection Direction3d.y
- --> (Point3d.fromCoordinates ( 1, 2, -3 ))
-
--}
+{-| -}
mirrorAcross : Plane3d -> Axis3d -> Axis3d
mirrorAcross plane (Types.Axis3d axis) =
through (Point3d.mirrorAcross plane axis.originPoint)
(Direction3d.mirrorAcross plane axis.direction)
-{-| Find the [orthographic projection](https://en.wikipedia.org/wiki/Orthographic_projection)
-of an axis onto a plane. If the given axis is exactly perpendicular to the given
-plane, returns `Nothing`.
-
- Axis3d.projectOnto Plane3d.xy exampleAxis
- --> Just
- --> (Axis3d.withDirection Direction3d.y
- --> (Point3d.fromCoordinates ( 1, 2, 0 ))
- --> )
-
- Axis3d.projectOnto Plane3d.xy Axis3d.z
- --> Nothing
-
--}
+{-| -}
projectOnto : Plane3d -> Axis3d -> Maybe Axis3d
projectOnto plane (Types.Axis3d axis) =
let
@@ -318,68 +188,21 @@ projectOnto plane (Types.Axis3d axis) =
|> Maybe.map (through projectedOrigin)
-{-| Take an axis defined in global coordinates, and return it expressed in local
-coordinates relative to a given reference frame.
-
- localFrame =
- Frame3d.atPoint
- (Point3d.fromCoordinates ( 3, 3, 3 ))
-
- Axis3d.relativeTo localFrame exampleAxis
- --> Axis3d.withDirection Direction3d.y
- --> (Point3d.fromCoordinates ( -2, -1, 0 ))
-
--}
+{-| -}
relativeTo : Frame3d -> Axis3d -> Axis3d
relativeTo frame (Types.Axis3d axis) =
through (Point3d.relativeTo frame axis.originPoint)
(Direction3d.relativeTo frame axis.direction)
-{-| Take an axis defined in local coordinates relative to a given reference
-frame, and return that axis expressed in global coordinates.
-
- localFrame =
- Frame3d.atPoint
- (Point3d.fromCoordinates ( 3, 3, 3 ))
-
- Axis3d.placeIn localFrame exampleAxis
- --> Axis3d.withDirection Direction3d.y
- --> (Point3d.fromCoordinates ( 4, 5, 6 ))
-
--}
+{-| -}
placeIn : Frame3d -> Axis3d -> Axis3d
placeIn frame (Types.Axis3d axis) =
through (Point3d.placeIn frame axis.originPoint)
(Direction3d.placeIn frame axis.direction)
-{-| Project an axis into a given sketch plane. Conceptually, this finds the
-[orthographic projection](https://en.wikipedia.org/wiki/Orthographic_projection)
-of the axis onto the plane and then expresses the projected axis in 2D sketch
-coordinates.
-
-This is only possible if the axis is not perpendicular to the sketch
-plane; if it is perpendicular, `Nothing` is returned.
-
- Axis3d.projectInto SketchPlane3d.xy exampleAxis
- --> Just
- --> (Axis2d.withDirection Direction2d.y
- --> (Point2d.fromCoordinates ( 1, 2 ))
- --> )
-
- -- The global Y direction is the X direction of the
- -- YZ plane:
- Axis3d.projectInto SketchPlane3d.yz exampleAxis
- --> Just
- --> (Axis2d.withDirection Direction2d.x
- --> (Point2d.fromCoordinates ( 2, 3 ))
- --> )
-
- Axis3d.projectInto SketchPlane3d.xz exampleAxis
- --> Nothing
-
--}
+{-| -}
projectInto : SketchPlane3d -> Axis3d -> Maybe Axis2d
projectInto sketchPlane (Types.Axis3d axis) =
let
diff --git a/src/BoundingBox2d.elm b/src/BoundingBox2d.elm
index 90a496c4..d43b1fe0 100644
--- a/src/BoundingBox2d.elm
+++ b/src/BoundingBox2d.elm
@@ -93,21 +93,7 @@ type alias BoundingBox2d =
Types.BoundingBox2d
-{-| Construct a bounding box from its minimum and maximum X and Y values:
-
- exampleBox =
- BoundingBox2d.fromExtrema
- { minX = 3
- , maxX = 8
- , minY = 2
- , maxY = 6
- }
-
-If the minimum and maximum values are provided in the wrong order (for example
-if minX > maxX
), then they will be swapped so that the
-resulting bounding box is valid.
-
--}
+{-| -}
fromExtrema : { minX : Float, maxX : Float, minY : Float, maxY : Float } -> BoundingBox2d
fromExtrema extrema_ =
if extrema_.minX <= extrema_.maxX && extrema_.minY <= extrema_.maxY then
@@ -121,20 +107,7 @@ fromExtrema extrema_ =
}
-{-| Construct a zero-width bounding box containing a single point.
-
- point =
- Point2d.fromCoordinates ( 2, 3 )
-
- BoundingBox2d.singleton point
- --> BoundingBox2d.fromExtrema
- --> { minX = 2
- --> , maxX = 2
- --> , minY = 3
- --> , maxY = 3
- --> }
-
--}
+{-| -}
singleton : Point2d -> BoundingBox2d
singleton point =
let
@@ -144,25 +117,7 @@ singleton point =
fromExtrema { minX = x, maxX = x, minY = y, maxY = y }
-{-| Construct a bounding box with the two given points as two of its corners.
-The points can be given in any order and don't have to represent the 'primary'
-diagonal of the bounding box.
-
- firstPoint =
- Point2d.fromCoordinates ( 2, 3 )
-
- secondPoint =
- Point2d.fromCoordinates ( -1, 5 )
-
- BoundingBox2d.from firstPoint secondPoint
- --> BoundingBox2d.fromExtrema
- --> { minX = -1
- --> , maxX = 2
- --> , minY = 3
- --> , maxY = 5
- --> }
-
--}
+{-| -}
from : Point2d -> Point2d -> BoundingBox2d
from firstPoint secondPoint =
let
@@ -180,33 +135,7 @@ from firstPoint secondPoint =
}
-{-| Construct a bounding box containing all bounding boxes in the given list. If
-the list is empty, returns `Nothing`.
-
- singletonBox =
- BoundingBox2d.singleton
- (Point2d.fromCoordinates ( 1, 3 ))
-
- BoundingBox2d.aggregate [ exampleBox, singletonBox ]
- --> Just
- --> (BoundingBox2d.fromExtrema
- --> { minX = 1,
- --> , maxX = 8
- --> , minY = 2
- --> , maxY = 6
- --> }
- --> )
-
- BoundingBox2d.aggregate [ exampleBox ]
- --> Just exampleBox
-
- BoundingBox2d.aggregate []
- --> Nothing
-
-If you have exactly two bounding boxes, you can use [`BoundingBox2d.hull`](#hull)
-instead (which returns a `BoundingBox2d` instead of a `Maybe BoundingBox2d`).
-
--}
+{-| -}
aggregate : List BoundingBox2d -> Maybe BoundingBox2d
aggregate boundingBoxes =
case boundingBoxes of
@@ -217,112 +146,43 @@ aggregate boundingBoxes =
Nothing
-{-| Construct a bounding box containing all points in the given list. If the
-list is empty, returns `Nothing`.
-
- BoundingBox2d.containingPoints
- [ Point2d.fromCoordinates ( 2, 3 )
- , Point2d.fromCoordinates ( -1, 5 )
- , Point2d.fromCoordinates ( 6, 4 )
- ]
- --> Just <|
- --> BoundingBox2d.fromExtrema
- --> { minX = -1
- --> , maxX = 6
- --> , minY = 3
- --> , maxY = 5
- --> }
-
- BoundingBox2d.containingPoints []
- --> Nothing
-
--}
+{-| -}
containingPoints : List Point2d -> Maybe BoundingBox2d
containingPoints points =
aggregate (List.map singleton points)
-{-| Get the minimum and maximum X and Y values of a bounding box in a single
-record.
-
- BoundingBox2d.extrema exampleBox
- --> { minX = 3
- --> , maxX = 8
- --> , minY = 2
- --> , maxY = 6
- --> }
-
-Can be useful when combined with record destructuring, for example
-
- { minX, maxX, minY, maxY } =
- BoundingBox2d.extrema exampleBox
-
-
- --> minX = 3
- --> maxX = 8
- --> minY = 2
- --> maxY = 6
-
--}
+{-| -}
extrema : BoundingBox2d -> { minX : Float, maxX : Float, minY : Float, maxY : Float }
extrema (Types.BoundingBox2d extrema_) =
extrema_
-{-| Get the minimum X value of a bounding box.
-
- BoundingBox2d.minX exampleBox
- --> 3
-
--}
+{-| -}
minX : BoundingBox2d -> Float
minX (Types.BoundingBox2d boundingBox) =
boundingBox.minX
-{-| Get the maximum X value of a bounding box.
-
- BoundingBox2d.maxX exampleBox
- --> 8
-
--}
+{-| -}
maxX : BoundingBox2d -> Float
maxX (Types.BoundingBox2d boundingBox) =
boundingBox.maxX
-{-| Get the minimum Y value of a bounding box.
-
- BoundingBox2d.minY exampleBox
- --> 2
-
--}
+{-| -}
minY : BoundingBox2d -> Float
minY (Types.BoundingBox2d boundingBox) =
boundingBox.minY
-{-| Get the maximum Y value of a bounding box.
-
- BoundingBox2d.maxY exampleBox
- --> 6
-
--}
+{-| -}
maxY : BoundingBox2d -> Float
maxY (Types.BoundingBox2d boundingBox) =
boundingBox.maxY
-{-| Get the X and Y dimensions (width and height) of a bounding box.
-
- ( width, height ) =
- BoundingBox2d.dimensions exampleBox
-
-
- --> width = 5
- --> height = 4
-
--}
+{-| -}
dimensions : BoundingBox2d -> ( Float, Float )
dimensions boundingBox =
( maxX boundingBox - minX boundingBox
@@ -330,51 +190,25 @@ dimensions boundingBox =
)
-{-| Get the median X value of a bounding box.
-
- BoundingBox2d.midX exampleBox
- --> 5.5
-
--}
+{-| -}
midX : BoundingBox2d -> Float
midX (Types.BoundingBox2d boundingBox) =
boundingBox.minX + 0.5 * (boundingBox.maxX - boundingBox.minX)
-{-| Get the median Y value of a bounding box.
-
- BoundingBox2d.midY exampleBox
- --> 4
-
--}
+{-| -}
midY : BoundingBox2d -> Float
midY (Types.BoundingBox2d boundingBox) =
boundingBox.minY + 0.5 * (boundingBox.maxY - boundingBox.minY)
-{-| Get the point at the center of a bounding box.
-
- BoundingBox2d.centroid exampleBox
- --> Point2d.fromCoordinates ( 5.5, 4 )
-
--}
+{-| -}
centroid : BoundingBox2d -> Point2d
centroid boundingBox =
Point2d.fromCoordinates ( midX boundingBox, midY boundingBox )
-{-| Check if a bounding box contains a particular point.
-
- point =
- Point2d.fromCoordinates ( 4, 3 )
-
- BoundingBox2d.contains point exampleBox
- --> True
-
- BoundingBox2d.contains Point2d.origin exampleBox
- --> False
-
--}
+{-| -}
contains : Point2d -> BoundingBox2d -> Bool
contains point boundingBox =
let
@@ -385,48 +219,7 @@ contains point boundingBox =
&& (minY boundingBox <= y && y <= maxY boundingBox)
-{-| Test if two boxes touch or overlap at all (have any points in common);
-
- BoundingBox2d.intersects firstBox secondBox
-
-is equivalent to
-
- BoundingBox2d.intersection firstBox secondBox
- /= Nothing
-
-but is more efficient.
-
- firstBox =
- BoundingBox2d.fromExtrema
- { minX = 0
- , maxX = 3
- , minY = 0
- , maxY = 2
- }
-
- secondBox =
- BoundingBox2d.fromExtrema
- { minX = 0
- , maxX = 3
- , minY = 1
- , maxY = 4
- }
-
- thirdBox =
- BoundingBox2d.fromExtrema
- { minX = 0
- , maxX = 3
- , minY = 4
- , maxY = 5
- }
-
- BoundingBox2d.intersects firstBox secondBox
- --> True
-
- BoundingBox2d.intersects firstBox thirdBox
- --> False
-
--}
+{-| -}
intersects : BoundingBox2d -> BoundingBox2d -> Bool
intersects other boundingBox =
(minX boundingBox <= maxX other)
@@ -480,65 +273,7 @@ alwaysFalse firstBox secondBox =
False
-{-| Check if one box overlaps another by less than, greater than or equal to a
-given amount. For example, you could implement a tolerant collision check (one
-that only returns true if the boxes overlap by at least some small finite
-amount, and ignores boxes that just barely touch each other) as
-
- boxesCollide box1 box2 =
- BoundingBox2d.overlappingBy GT 0.001 box1 box2
-
-This can be read as "`box1` and `box2` are overlapping by greater than 0.001
-units". (The [`Order`](http://package.elm-lang.org/packages/elm-lang/core/latest/Basics#Order)
-type and its three values `LT`, `GT` and `EQ` are defined in Elm's `Basics`
-module so are available by default in any Elm program.)
-
-Overlap is defined as the _minimum_ distance one box would have to move so that
-it did not touch the other, and is always positive for any two overlapping
-boxes.
-
-Boxes that just touch are considered to have an overlap of zero, which is
-distinct from 'no overlap'. Boxes that do not touch or overlap at all are
-considered to have an overlap which is less than zero but not comparable to any
-negative number.
-
-
-### Less than
-
- - `overlappingBy LT 1e-3` will return true if the two boxes overlap by less
- than 0.001 units or if they do not overlap at all (false if they overlap by
- more than 0.001 units).
- - `overlappingBy LT 0` will return true only if the two boxes don't touch or
- overlap at all.
- - `overlappingBy LT -1e-3` will always return false! If you care about _how
- much_ two boxes are separated by, use `separatedBy` instead.
-
-
-### Greater than
-
- - `overlappingBy GT 1e-3` will return true if the two boxes overlap by at
- least 0.001 units (false if they overlap by less than that or do not overlap
- at all).
- - `overlappingBy GT 0` will return true if the two boxes overlap by any
- non-zero amount (false if they just touch or do not overlap at all).
- - `overlappingBy GT -1e-3` doesn't make a lot of sense but will return true if
- the boxes touch or overlap at all (false if they don't overlap, regardless
- of how close they are to overlapping). In this case, though, it would make
- more sense to just user `intersects` instead.
-
-
-### Equal to
-
-Checking whether two boxes overlap by exactly a given amount is pretty weird and
-vulnerable to floating-point roundoff, but is defined as follows:
-
- - `overlappingBy EQ 1e-3` will return true if the two boxes overlap by exactly
- 0.001 units.
- - `overlappingBy EQ 0` will return true if and only if the boxes just touch
- each other.
- - `overlappingBy EQ -1e-3` will always return false.
-
--}
+{-| -}
overlappingBy : Order -> Float -> BoundingBox2d -> BoundingBox2d -> Bool
overlappingBy order tolerance =
case order of
@@ -582,63 +317,7 @@ overlappingBy order tolerance =
alwaysFalse
-{-| Check if one box is separated from another by less than, greater than or
-equal to a given amount. For example, to perform clash detection between some
-objects, you could use `separatedBy` on those objects' bounding boxes as a quick
-check to see if the objects had a gap of at least 1 cm between them:
-
- safelySeparated box1 box2 =
- BoundingBox2d.separatedBy GT 0.01 box1 box2
-
-This can be read as "`box1` and `box2` are separated by greater than 0.01
-units". (The [`Order`](http://package.elm-lang.org/packages/elm-lang/core/latest/Basics#Order)
-type and its three values `LT`, `GT` and `EQ` are defined in Elm's `Basics`
-module so are available by default in any Elm program.)
-
-Separation is defined as the _minimum_ distance one box would have to move
-so that it touched the other, and is always positive for any two boxes that do
-not touch.
-
-Boxes that just touch are considered to have a separation of zero, which is
-distinct from 'no separation'. 'No separation' (overlap) is considered to be
-less than zero but not comparable to any negative number.
-
-
-### Less than
-
- - `separatedBy LT 1e-3` will return true if the two boxes are separated by
- less than 0.001 units or if they touch or overlap (false if they are
- separated by at least 0.001 units).
- - `separatedBy LT 0` will return true only if the boxes overlap by some
- non-zero amount.
- - `separatedBy LT -1e-3` will always return false! If you care about _how
- much_ two boxes overlap by, use `overlappingBy` instead.
-
-
-### Greater than
-
- - `separatedBy GT 1e-3` will return true if the two boxes are separated by at
- least 0.001 units (false if they are separated by less than that or if they
- touch or overlap).
- - `separatedBy GT 0` will return true if the two boxes are separated by any
- non-zero amount (false if they touch or overlap).
- - `separatedBy GT -1e-3` doesn't make a lot of sense but will return true if
- the boxes just touch or are separated by any amount (false if they overlap
- by any non-zero amount).
-
-
-### Equal to
-
-Checking whether two boxes are separated by exactly a given amount is pretty
-weird and vulnerable to floating-point roundoff, but is defined as follows:
-
- - `separatedBy EQ 1e-3` will return true if the two boxes are separated by
- exactly 0.001 units.
- - `separatedBy EQ 0` will return true if and only if the boxes just touch each
- other.
- - `separatedBy EQ -3` will always return false.
-
--}
+{-| -}
separatedBy : Order -> Float -> BoundingBox2d -> BoundingBox2d -> Bool
separatedBy order tolerance =
case order of
@@ -682,73 +361,14 @@ separatedBy order tolerance =
alwaysFalse
-{-| Test if the second given bounding box is fully contained within the first
-(is a subset of it).
-
- outerBox =
- BoundingBox2d.fromExtrema
- { minX = 0
- , maxX = 10
- , minY = 0
- , maxY = 10
- }
-
- innerBox =
- BoundingBox2d.fromExtrema
- { minX = 1
- , maxX = 5
- , minY = 3
- , maxY = 9
- }
-
- overlappingBox =
- BoundingBox2d.fromExtrema
- { minX = 1
- , maxX = 5
- , minY = 3
- , maxY = 12
- }
-
- BoundingBox2d.isContainedIn outerBox innerBox
- --> True
-
- BoundingBox2d.isContainedIn outerBox overlappingBox
- --> False
-
--}
+{-| -}
isContainedIn : BoundingBox2d -> BoundingBox2d -> Bool
isContainedIn other boundingBox =
(minX other <= minX boundingBox && maxX boundingBox <= maxX other)
&& (minY other <= minY boundingBox && maxY boundingBox <= maxY other)
-{-| Build a bounding box that contains both given bounding boxes.
-
- firstBox =
- BoundingBox2d.fromExtrema
- { minX = 1
- , maxX = 4
- , minY = 2
- , maxY = 3
- }
-
- secondBox =
- BoundingBox2d.fromExtrema
- { minX = -2
- , maxX = 2
- , minY = 4
- , maxY = 5
- }
-
- BoundingBox2d.hull firstBox secondBox
- --> BoundingBox2d.fromExtrema
- --> { minX = -2
- --> , maxX = 4
- --> , minY = 2
- --> , maxY = 5
- --> }
-
--}
+{-| -}
hull : BoundingBox2d -> BoundingBox2d -> BoundingBox2d
hull firstBox secondBox =
fromExtrema
@@ -759,77 +379,7 @@ hull firstBox secondBox =
}
-{-| Attempt to build a bounding box that contains all points common to both
-given bounding boxes. If the given boxes do not intersect, returns `Nothing`.
-
- firstBox =
- BoundingBox2d.fromExtrema
- { minX = 1
- , maxX = 4
- , minY = 2
- , maxY = 3
- }
-
- secondBox =
- BoundingBox2d.fromExtrema
- { minX = 2
- , maxX = 5
- , minY = 1
- , maxY = 4
- }
-
- thirdBox =
- BoundingBox2d.fromExtrema
- { minX = 1
- , maxX = 4
- , minY = 4
- , maxY = 5
- }
-
- BoundingBox2d.intersection firstBox secondBox
- --> Just
- --> (BoundingBox2d.fromExtrema
- --> { minX = 2
- --> , maxX = 4
- --> , minY = 2
- --> , maxY = 3
- --> }
- --> )
-
- BoundingBox2d.intersection firstBox thirdBox
- --> Nothing
-
-If two boxes just touch along an edge or at a corner, they are still considered
-to have an intersection, even though that intersection will have zero area (at
-least one of its dimensions will be zero):
-
- firstBox =
- BoundingBox2d.fromExtrema
- { minX = 0
- , maxX = 1
- , minY = 0
- , maxY = 2
- }
-
- secondBox =
- BoundingBox2d.fromExtrema
- { minX = 1
- , maxX = 2
- , minY = 1
- , maxY = 3
- }
-
- BoundingBox2d.intersection firstBox secondBox
- --> Just
- --> (BoundingBox2d.fromExtrema
- --> { minX = 1
- --> , maxX = 1
- --> , minY = 1
- --> , maxY = 2
- --> }
- --> )
-
--}
+{-| -}
intersection : BoundingBox2d -> BoundingBox2d -> Maybe BoundingBox2d
intersection firstBox secondBox =
if intersects firstBox secondBox then
@@ -845,20 +395,7 @@ intersection firstBox secondBox =
Nothing
-{-| Scale a bounding box about a given point by a given scale.
-
- point =
- Point2d.fromCoordinates ( 4, 4 )
-
- BoundingBox2d.scaleAbout point 2 exampleBox
- --> BoundingBox2d.fromExtrema
- --> { minX = 2
- --> , maxX = 12
- --> , minY = 0
- --> , maxY = 8
- --> }
-
--}
+{-| -}
scaleAbout : Point2d -> Float -> BoundingBox2d -> BoundingBox2d
scaleAbout point scale boundingBox =
let
@@ -881,20 +418,7 @@ scaleAbout point scale boundingBox =
}
-{-| Translate a bounding box by a given displacement.
-
- displacement =
- Vector2d.fromComponents ( 2, -3 )
-
- BoundingBox2d.translateBy displacement exampleBox
- --> BoundingBox2d.fromExtrema
- --> { minX = 5
- --> , maxX = 10
- --> , minY = -1
- --> , maxY = 3
- --> }
-
--}
+{-| -}
translateBy : Vector2d -> BoundingBox2d -> BoundingBox2d
translateBy displacement boundingBox =
let
@@ -909,16 +433,7 @@ translateBy displacement boundingBox =
}
-{-| Translate a bounding box in a given direction by a given distance;
-
- BoundingBox2d.translateIn direction distance
-
-is equivalent to
-
- BoundingBox2d.translateBy
- (Vector2d.withLength distance direction)
-
--}
+{-| -}
translateIn : Direction2d -> Float -> BoundingBox2d -> BoundingBox2d
translateIn direction distance boundingBox =
translateBy (Vector2d.withLength distance direction) boundingBox
diff --git a/src/BoundingBox3d.elm b/src/BoundingBox3d.elm
index 89854345..a924fe61 100644
--- a/src/BoundingBox3d.elm
+++ b/src/BoundingBox3d.elm
@@ -95,23 +95,7 @@ type alias BoundingBox3d =
Types.BoundingBox3d
-{-| Construct a bounding box from its minimum and maximum X, Y and Z values:
-
- exampleBox =
- BoundingBox3d.fromExtrema
- { minX = -2
- , maxX = 2
- , minY = 2
- , maxY = 5
- , minZ = 3
- , maxZ = 4
- }
-
-If the minimum and maximum values are provided in the wrong order (for example
-if minX > maxX
), then they will be swapped so that the
-resulting bounding box is valid.
-
--}
+{-| -}
fromExtrema : { minX : Float, maxX : Float, minY : Float, maxY : Float, minZ : Float, maxZ : Float } -> BoundingBox3d
fromExtrema extrema_ =
if
@@ -131,22 +115,7 @@ fromExtrema extrema_ =
}
-{-| Construct a zero-width bounding box containing a single point.
-
- point =
- Point3d.fromCoordinates ( 2, 1, 3 )
-
- BoundingBox3d.singleton point
- --> BoundingBox3d.fromExtrema
- --> { minX = 2
- --> , maxX = 2
- --> , minY = 1
- --> , maxY = 1
- --> , minZ = 3
- --> , maxZ = 3
- --> }
-
--}
+{-| -}
singleton : Point3d -> BoundingBox3d
singleton point =
let
@@ -163,27 +132,7 @@ singleton point =
}
-{-| Construct a bounding box with the two given points as two of its corners.
-The points can be given in any order and don't have to represent the 'primary'
-diagonal of the bounding box.
-
- firstPoint =
- Point3d.fromCoordinates ( 2, 1, 3 )
-
- secondPoint =
- Point3d.fromCoordinates ( -1, 5, -2 )
-
- BoundingBox3d.from firstPoint secondPoint
- --> BoundingBox3d.fromExtrema
- --> { minX = -1
- --> , maxX = 2
- --> , minY = 1
- --> , maxY = 5
- --> , minZ = -2
- --> , maxZ = 3
- --> }
-
--}
+{-| -}
from : Point3d -> Point3d -> BoundingBox3d
from firstPoint secondPoint =
let
@@ -203,35 +152,7 @@ from firstPoint secondPoint =
}
-{-| Construct a bounding box containing all bounding boxes in the given list. If
-the list is empty, returns `Nothing`.
-
- singletonBox =
- BoundingBox3d.singleton
- (Point3d.fromCoordinates ( 2, 1, 0 ))
-
- BoundingBox3d.aggregate [ exampleBox, singletonBox ]
- --> Just
- --> (BoundingBox3d.fromExtrema
- --> { minX = -2,
- --> , maxX = 2
- --> , minY = 1
- --> , maxY = 5
- --> , minZ = 0
- --> , maxZ = 4
- --> }
- --> )
-
- BoundingBox3d.aggregate [ exampleBox ]
- --> Just exampleBox
-
- BoundingBox3d.aggregate []
- --> Nothing
-
-If you have exactly two bounding boxes, you can use [`BoundingBox3d.hull`](#hull)
-instead (which returns a `BoundingBox3d` instead of a `Maybe BoundingBox3d`).
-
--}
+{-| -}
aggregate : List BoundingBox3d -> Maybe BoundingBox3d
aggregate boundingBoxes =
case boundingBoxes of
@@ -242,136 +163,55 @@ aggregate boundingBoxes =
Nothing
-{-| Construct a bounding box containing all points in the given list. If the
-list is empty, returns `Nothing`.
-
- BoundingBox3d.containingPoints
- [ Point3d.fromCoordinates ( 2, 1, 3 )
- , Point3d.fromCoordinates ( -1, 5, -2 )
- , Point3d.fromCoordinates ( 6, 4, 2 )
- ]
- --> Just <|
- --> BoundingBox3d.fromExtrema
- --> { minX = -1
- --> , maxX = 6
- --> , minY = 1
- --> , maxY = 5
- --> , minZ = -2
- --> , maxZ = 3
- --> }
-
- BoundingBox3d.containingPoints []
- --> Nothing
-
--}
+{-| -}
containingPoints : List Point3d -> Maybe BoundingBox3d
containingPoints points =
aggregate (List.map singleton points)
-{-| Get the minimum and maximum X, Y and Z values of a bounding box in a single
-record.
-
- BoundingBox3d.extrema exampleBox
- --> { minX = -2
- --> , maxX = 2
- --> , minY = 2
- --> , maxY = 5
- --> , minZ = 3
- --> , maxZ = 4
- --> }
-
-Can be useful when combined with record destructuring, for example
-
- { minX, maxX, minY, maxY, minZ, maxZ } =
- BoundingBox3d.extrema exampleBox
-
-
- --> minX = -2
- --> maxX = 2
- --> minY = 2
- --> maxY = 5
- --> minZ = 3
- --> maxZ = 4
-
--}
+{-| -}
extrema : BoundingBox3d -> { minX : Float, maxX : Float, minY : Float, maxY : Float, minZ : Float, maxZ : Float }
extrema (Types.BoundingBox3d extrema_) =
extrema_
-{-| Get the minimum X value of a bounding box.
-
- BoundingBox3d.minX exampleBox
- --> -2
-
--}
+{-| -}
minX : BoundingBox3d -> Float
minX (Types.BoundingBox3d boundingBox) =
boundingBox.minX
-{-| Get the maximum X value of a bounding box.
-
- BoundingBox3d.maxX exampleBox
- --> 2
-
--}
+{-| -}
maxX : BoundingBox3d -> Float
maxX (Types.BoundingBox3d boundingBox) =
boundingBox.maxX
-{-| Get the minimum Y value of a bounding box.
-
- BoundingBox3d.minY exampleBox
- --> 2
-
--}
+{-| -}
minY : BoundingBox3d -> Float
minY (Types.BoundingBox3d boundingBox) =
boundingBox.minY
-{-| Get the maximum Y value of a bounding box.
-
- BoundingBox3d.maxY exampleBox
- --> 5
-
--}
+{-| -}
maxY : BoundingBox3d -> Float
maxY (Types.BoundingBox3d boundingBox) =
boundingBox.maxY
-{-| Get the minimum Z value of a bounding box.
-
- BoundingBox3d.minZ exampleBox
- --> 3
-
--}
+{-| -}
minZ : BoundingBox3d -> Float
minZ (Types.BoundingBox3d boundingBox) =
boundingBox.minZ
-{-| Get the maximum Z value of a bounding box.
-
- BoundingBox3d.maxZ exampleBox
- --> 4
-
--}
+{-| -}
maxZ : BoundingBox3d -> Float
maxZ (Types.BoundingBox3d boundingBox) =
boundingBox.maxZ
-{-| Get the X, Y and Z dimensions (widths) of a bounding box.
-
- BoundingBox3d.dimensions exampleBox
- --> ( 4, 3, 1 )
-
--}
+{-| -}
dimensions : BoundingBox3d -> ( Float, Float, Float )
dimensions boundingBox =
( maxX boundingBox - minX boundingBox
@@ -380,45 +220,25 @@ dimensions boundingBox =
)
-{-| Get the median X value of a bounding box.
-
- BoundingBox3d.midX exampleBox
- --> 0
-
--}
+{-| -}
midX : BoundingBox3d -> Float
midX (Types.BoundingBox3d boundingBox) =
boundingBox.minX + 0.5 * (boundingBox.maxX - boundingBox.minX)
-{-| Get the median Y value of a bounding box.
-
- BoundingBox3d.midY exampleBox
- --> 3.5
-
--}
+{-| -}
midY : BoundingBox3d -> Float
midY (Types.BoundingBox3d boundingBox) =
boundingBox.minY + 0.5 * (boundingBox.maxY - boundingBox.minY)
-{-| Get the median Z value of a bounding box.
-
- BoundingBox3d.midZ exampleBox
- --> 3.5
-
--}
+{-| -}
midZ : BoundingBox3d -> Float
midZ (Types.BoundingBox3d boundingBox) =
boundingBox.minZ + 0.5 * (boundingBox.maxZ - boundingBox.minZ)
-{-| Get the point at the center of a bounding box.
-
- BoundingBox3d.centroid exampleBox
- --> Point3d.fromCoordinates ( 0, 3.5, 3.5 )
-
--}
+{-| -}
centroid : BoundingBox3d -> Point3d
centroid boundingBox =
Point3d.fromCoordinates
@@ -428,21 +248,7 @@ centroid boundingBox =
)
-{-| Check if a bounding box contains a particular point.
-
- firstPoint =
- Point3d.fromCoordinates ( 1, 4, 3 )
-
- secondPoint =
- Point3d.fromCoordinates ( 3, 4, 5 )
-
- BoundingBox3d.contains firstPoint exampleBox
- --> True
-
- BoundingBox3d.contains secondPoint exampleBox
- --> False
-
--}
+{-| -}
contains : Point3d -> BoundingBox3d -> Bool
contains point boundingBox =
let
@@ -454,54 +260,7 @@ contains point boundingBox =
&& (minZ boundingBox <= z && z <= maxZ boundingBox)
-{-| Test if two boxes touch or overlap at all (have any points in common);
-
- BoundingBox3d.intersects firstBox secondBox
-
-is equivalent to
-
- BoundingBox3d.intersection firstBox secondBox
- /= Nothing
-
-but is more efficient.
-
- firstBox =
- BoundingBox3d.fromExtrema
- { minX = 0
- , maxX = 3
- , minY = 0
- , maxY = 2
- , minZ = 0
- , maxZ = 1
- }
-
- secondBox =
- BoundingBox3d.fromExtrema
- { minX = 0
- , maxX = 3
- , minY = 1
- , maxY = 4
- , minZ = -1
- , maxZ = 2
- }
-
- thirdBox =
- BoundingBox3d.fromExtrema
- { minX = 0
- , maxX = 3
- , minY = 4
- , maxY = 5
- , minZ = -1
- , maxZ = 2
- }
-
- BoundingBox3d.intersects firstBox secondBox
- --> True
-
- BoundingBox3d.intersects firstBox thirdBox
- --> False
-
--}
+{-| -}
intersects : BoundingBox3d -> BoundingBox3d -> Bool
intersects other boundingBox =
(minX boundingBox <= maxX other)
@@ -569,65 +328,7 @@ alwaysFalse firstBox secondBox =
False
-{-| Check if one box overlaps another by less than, greater than or equal to a
-given amount. For example, you could implement a tolerant collision check (one
-that only returns true if the boxes overlap by at least some small finite
-amount, and ignores boxes that just barely touch each other) as
-
- boxesCollide box1 box2 =
- BoundingBox3d.overlappingBy GT 0.001 box1 box2
-
-This can be read as "`box1` and `box2` are overlapping by greater than 0.001
-units". (The [`Order`](http://package.elm-lang.org/packages/elm-lang/core/latest/Basics#Order)
-type and its three values `LT`, `GT` and `EQ` are defined in Elm's `Basics`
-module so are available by default in any Elm program.)
-
-Overlap is defined as the _minimum_ distance one box would have to move so that
-it did not touch the other, and is always positive for any two overlapping
-boxes.
-
-Boxes that just touch are considered to have an overlap of zero, which is
-distinct from 'no overlap'. Boxes that do not touch or overlap at all are
-considered to have an overlap which is less than zero but not comparable to any
-negative number.
-
-
-### Less than
-
- - `overlappingBy LT 1e-3` will return true if the two boxes overlap by less
- than 0.001 units or if they do not overlap at all (false if they overlap by
- more than 0.001 units).
- - `overlappingBy LT 0` will return true only if the two boxes don't touch or
- overlap at all.
- - `overlappingBy LT -1e-3` will always return false! If you care about _how
- much_ two boxes are separated by, use `separatedBy` instead.
-
-
-### Greater than
-
- - `overlappingBy GT 1e-3` will return true if the two boxes overlap by at
- least 0.001 units (false if they overlap by less than that or do not overlap
- at all).
- - `overlappingBy GT 0` will return true if the two boxes overlap by any
- non-zero amount (false if they just touch or do not overlap at all).
- - `overlappingBy GT -1e-3` doesn't make a lot of sense but will return true if
- the boxes touch or overlap at all (false if they don't overlap, regardless
- of how close they are to overlapping). In this case, though, it would make
- more sense to just user `intersects` instead.
-
-
-### Equal to
-
-Checking whether two boxes overlap by exactly a given amount is pretty weird and
-vulnerable to floating-point roundoff, but is defined as follows:
-
- - `overlappingBy EQ 1e-3` will return true if the two boxes overlap by exactly
- 0.001 units.
- - `overlappingBy EQ 0` will return true if and only if the boxes just touch
- each other.
- - `overlappingBy EQ -1e-3` will always return false.
-
--}
+{-| -}
overlappingBy : Order -> Float -> BoundingBox3d -> BoundingBox3d -> Bool
overlappingBy order tolerance =
case order of
@@ -671,63 +372,7 @@ overlappingBy order tolerance =
alwaysFalse
-{-| Check if one box is separated from another by less than, greater than or
-equal to a given amount. For example, to perform clash detection between some
-objects, you could use `separatedBy` on those objects' bounding boxes as a quick
-check to see if the objects had a gap of at least 1 cm between them:
-
- safelySeparated box1 box2 =
- BoundingBox3d.separatedBy GT 0.01 box1 box2
-
-This can be read as "`box1` and `box2` are separated by greater than 0.01
-units". (The [`Order`](http://package.elm-lang.org/packages/elm-lang/core/latest/Basics#Order)
-type and its three values `LT`, `GT` and `EQ` are defined in Elm's `Basics`
-module so are available by default in any Elm program.)
-
-Separation is defined as the _minimum_ distance one box would have to move
-so that it touched the other, and is always positive for any two boxes that do
-not touch.
-
-Boxes that just touch are considered to have a separation of zero, which is
-distinct from 'no separation'. 'No separation' (overlap) is considered to be
-less than zero but not comparable to any negative number.
-
-
-### Less than
-
- - `separatedBy LT 1e-3` will return true if the two boxes are separated by
- less than 0.001 units or if they touch or overlap (false if they are
- separated by at least 0.001 units).
- - `separatedBy LT 0` will return true only if the boxes overlap by some
- non-zero amount.
- - `separatedBy LT -1e-3` will always return false! If you care about _how
- much_ two boxes overlap by, use `overlappingBy` instead.
-
-
-### Greater than
-
- - `separatedBy GT 1e-3` will return true if the two boxes are separated by at
- least 0.001 units (false if they are separated by less than that or if they
- touch or overlap).
- - `separatedBy GT 0` will return true if the two boxes are separated by any
- non-zero amount (false if they touch or overlap).
- - `separatedBy GT -1e-3` doesn't make a lot of sense but will return true if
- the boxes just touch or are separated by any amount (false if they overlap
- by any non-zero amount).
-
-
-### Equal to
-
-Checking whether two boxes are separated by exactly a given amount is pretty
-weird and vulnerable to floating-point roundoff, but is defined as follows:
-
- - `separatedBy EQ 1e-3` will return true if the two boxes are separated by
- exactly 0.001 units.
- - `separatedBy EQ 0` will return true if and only if the boxes just touch each
- other.
- - `separatedBy EQ -3` will always return false.
-
--}
+{-| -}
separatedBy : Order -> Float -> BoundingBox3d -> BoundingBox3d -> Bool
separatedBy order tolerance =
case order of
@@ -771,46 +416,7 @@ separatedBy order tolerance =
alwaysFalse
-{-| Test if the second given bounding box is fully contained within the first
-(is a subset of it).
-
- outerBox =
- BoundingBox3d.fromExtrema
- { minX = 0
- , maxX = 10
- , minY = 0
- , maxY = 10
- , minZ = 0
- , maxZ = 10
- }
-
- innerBox =
- BoundingBox3d.fromExtrema
- { minX = 1
- , maxX = 5
- , minY = 3
- , maxY = 9
- , minZ = 7
- , maxZ = 8
- }
-
- overlappingBox =
- BoundingBox3d.fromExtrema
- { minX = 1
- , maxX = 5
- , minY = 3
- , maxY = 12
- , minZ = 7
- , maxZ = 8
- }
-
- BoundingBox3d.isContainedIn outerBox innerBox
- --> True
-
- BoundingBox3d.isContainedIn outerBox overlappingBox
- --> False
-
--}
+{-| -}
isContainedIn : BoundingBox3d -> BoundingBox3d -> Bool
isContainedIn other boundingBox =
(minX other <= minX boundingBox && maxX boundingBox <= maxX other)
@@ -818,39 +424,7 @@ isContainedIn other boundingBox =
&& (minZ other <= minZ boundingBox && maxZ boundingBox <= maxZ other)
-{-| Build a bounding box that contains both given bounding boxes.
-
- firstBox =
- BoundingBox3d.fromExtrema
- { minX = 1
- , maxX = 4
- , minY = 2
- , maxY = 3
- , minZ = 0
- , maxZ = 5
- }
-
- secondBox =
- BoundingBox3d.fromExtrema
- { minX = -2
- , maxX = 2
- , minY = 4
- , maxY = 5
- , minZ = -1
- , maxZ = 0
- }
-
- BoundingBox3d.hull firstBox secondBox
- --> BoundingBox3d.fromExtrema
- --> { minX = -2
- --> , maxX = 4
- --> , minY = 2
- --> , maxY = 5
- --> , minZ = -1
- --> , maxZ = 5
- --> }
-
--}
+{-| -}
hull : BoundingBox3d -> BoundingBox3d -> BoundingBox3d
hull firstBox secondBox =
fromExtrema
@@ -863,91 +437,7 @@ hull firstBox secondBox =
}
-{-| Attempt to build a bounding box that contains all points common to both
-given bounding boxes. If the given boxes do not overlap, returns `Nothing`.
-
- firstBox =
- BoundingBox3d.fromExtrema
- { minX = 1
- , maxX = 4
- , minY = 2
- , maxY = 3
- , minZ = 5
- , maxZ = 8
- }
-
- secondBox =
- BoundingBox3d.fromExtrema
- { minX = 2
- , maxX = 5
- , minY = 1
- , maxY = 4
- , minZ = 6
- , maxZ = 7
- }
-
- thirdBox =
- BoundingBox3d.fromExtrema
- { minX = 1
- , maxX = 4
- , minY = 4
- , maxY = 5
- , minZ = 5
- , maxZ = 8
- }
-
- BoundingBox3d.intersection firstBox secondBox
- --> Just
- --> (BoundingBox3d.fromExtrema
- --> { minX = 2
- --> , maxX = 4
- --> , minY = 2
- --> , maxY = 3
- --> , minZ = 6
- --> , maxZ = 7
- --> }
- --> )
-
- BoundingBox3d.intersection firstBox thirdBox
- --> Nothing
-
-If two boxes just touch along an edge or at a corner, they are still considered
-to have an intersection, even though that intersection will have zero area (at
-least one of its dimensions will be zero):
-
- firstBox =
- BoundingBox3d.fromExtrema
- { minX = 0
- , maxX = 1
- , minY = 0
- , maxY = 2
- , minZ = 0
- , maxZ = 3
- }
-
- secondBox =
- BoundingBox3d.fromExtrema
- { minX = 1
- , maxX = 2
- , minY = 1
- , maxY = 3
- , minZ = 1
- , maxZ = 4
- }
-
- BoundingBox3d.intersection firstBox secondBox
- --> Just
- --> (BoundingBox3d.fromExtrema
- --> { minX = 1
- --> , maxX = 1
- --> , minY = 1
- --> , maxY = 2
- --> , minZ = 1
- --> , maxZ = 3
- --> }
- --> )
-
--}
+{-| -}
intersection : BoundingBox3d -> BoundingBox3d -> Maybe BoundingBox3d
intersection firstBox secondBox =
if intersects firstBox secondBox then
@@ -965,22 +455,7 @@ intersection firstBox secondBox =
Nothing
-{-| Scale a bounding box about a given point by a given scale.
-
- point =
- Point3d.fromCoordinates ( 2, 2, 2 )
-
- BoundingBox3d.scaleAbout point 2 exampleBox
- --> BoundingBox3d.fromExtrema
- --> { minX = -6
- --> , maxX = 2
- --> , minY = 2
- --> , maxY = 8
- --> , minZ = 4
- --> , maxZ = 6
- --> }
-
--}
+{-| -}
scaleAbout : Point3d -> Float -> BoundingBox3d -> BoundingBox3d
scaleAbout point scale boundingBox =
let
@@ -1007,22 +482,7 @@ scaleAbout point scale boundingBox =
}
-{-| Translate a bounding box by a given displacement.
-
- displacement =
- Vector3d.fromComponents ( 2, -3, 1 )
-
- BoundingBox3d.translateBy displacement exampleBox
- --> BoundingBox3d.fromExtrema
- --> { minX = 0
- --> , maxX = 4
- --> , minY = -1
- --> , maxY = 2
- --> , minZ = 4
- --> , maxZ = 5
- --> }
-
--}
+{-| -}
translateBy : Vector3d -> BoundingBox3d -> BoundingBox3d
translateBy displacement boundingBox =
let
@@ -1039,16 +499,7 @@ translateBy displacement boundingBox =
}
-{-| Translate a bounding box in a given direction by a given distance;
-
- BoundingBox3d.translateIn direction distance
-
-is equivalent to
-
- BoundingBox3d.translateBy
- (Vector3d.withLength distance direction)
-
--}
+{-| -}
translateIn : Direction3d -> Float -> BoundingBox3d -> BoundingBox3d
translateIn direction distance boundingBox =
translateBy (Vector3d.withLength distance direction) boundingBox
diff --git a/src/Circle2d.elm b/src/Circle2d.elm
index a85ba1cb..d765feec 100644
--- a/src/Circle2d.elm
+++ b/src/Circle2d.elm
@@ -84,65 +84,19 @@ type alias Circle2d =
Types.Circle2d
-{-| Construct a circle from its radius and center point:
-
- exampleCircle =
- Circle2d.withRadius 3
- (Point2d.fromCoordinates ( 1, 2 ))
-
-If you pass a negative radius, the absolute value will be used.
-
--}
+{-| -}
withRadius : Float -> Point2d -> Circle2d
withRadius radius_ centerPoint_ =
Types.Circle2d { radius = abs radius_, centerPoint = centerPoint_ }
-{-| The unit circle, centered on the origin with a radius of 1.
-
- Circle2d.unit
- --> Circle2d.withRadius 1 Point2d.origin
-
--}
+{-| -}
unit : Circle2d
unit =
withRadius 1 Point2d.origin
-{-| Attempt to construct a circle that passes through the three given points. If
-the three given points are collinear, returns `Nothing`.
-
- Circle2d.throughPoints
- Point2d.origin
- (Point2d.fromCoordinates ( 1, 0 ))
- (Point2d.fromCoordinates ( 0, 1 ))
- --> Just
- --> (Circle2d.withRadius 0.7071
- --> (Point2d.fromCoordinates ( 0.5, 0.5 ))
- --> )
-
- Circle2d.throughPoints
- Point2d.origin
- (Point2d.fromCoordinates ( 2, 1 ))
- (Point2d.fromCoordinates ( 4, 0 ))
- --> Just
- --> (Circle2d.withRadius 2.5
- --> (Point2d.fromCoordinates ( 2, -1.5 ))
- --> )
-
- Circle2d.throughPoints
- Point2d.origin
- (Point2d.fromCoordinates ( 2, 0 ))
- (Point2d.fromCoordinates ( 4, 0 ))
- --> Nothing
-
- Circle2d.throughPoints
- Point2d.origin
- Point2d.origin
- (Point2d.fromCoordinates ( 1, 0 ))
- --> Nothing
-
--}
+{-| -}
throughPoints : Point2d -> Point2d -> Point2d -> Maybe Circle2d
throughPoints p1 p2 p3 =
Point2d.circumcenter p1 p2 p3
@@ -165,72 +119,31 @@ throughPoints p1 p2 p3 =
)
-{-| Construct a circle by rotating a point on the circle around a given center
-point. The center point is given first and the point on the circle is given
-second.
-
- Circle2d.sweptAround Point2d.origin
- (Point2d.fromCoordinates ( 2, 0 ))
- --> Circle2d.withRadius 2 Point2d.origin
-
-The above example could be rewritten as
-
- Point2d.fromCoordinates ( 2, 0 )
- |> Circle2d.sweptAround Point2d.origin
-
-and if you wanted to create many concentric circles all centered on the origin
-but passing through several other different points, you could use something like
-
- concentricCircles =
- points
- |> List.map
- (Circle2d.sweptAround Point2d.origin)
-
--}
+{-| -}
sweptAround : Point2d -> Point2d -> Circle2d
sweptAround centerPoint_ point =
withRadius (Point2d.distanceFrom centerPoint_ point) centerPoint_
-{-| Get the center point of a circle.
-
- Circle2d.centerPoint exampleCircle
- --> Point2d.fromCoordinates ( 1, 2 )
-
--}
+{-| -}
centerPoint : Circle2d -> Point2d
centerPoint (Types.Circle2d properties) =
properties.centerPoint
-{-| Get the radius of a circle.
-
- Circle2d.radius exampleCircle
- --> 3
-
--}
+{-| -}
radius : Circle2d -> Float
radius (Types.Circle2d properties) =
properties.radius
-{-| Get the diameter of a circle.
-
- Circle2d.diameter exampleCircle
- --> 6
-
--}
+{-| -}
diameter : Circle2d -> Float
diameter circle =
2 * radius circle
-{-| Get the area of a circle.
-
- Circle2d.area exampleCircle
- --> 28.2743
-
--}
+{-| -}
area : Circle2d -> Float
area circle =
let
@@ -240,26 +153,13 @@ area circle =
pi * r * r
-{-| Get the circumference of a circle.
-
- Circle2d.circumference exampleCircle
- --> 18.8496
-
--}
+{-| -}
circumference : Circle2d -> Float
circumference circle =
2 * pi * radius circle
-{-| Convert a circle to a 360 degree arc.
-
- Circle2d.toArc exampleCircle
- --> Point2d.fromCoordinates ( 4, 2 )
- --> |> Arc2d.sweptAround
- --> (Point2d.fromCoordinates ( 1, 2 ))
- --> (degrees 360)
-
--}
+{-| -}
toArc : Circle2d -> Arc2d
toArc (Types.Circle2d circle) =
let
@@ -274,17 +174,7 @@ toArc (Types.Circle2d circle) =
}
-{-| Check if a circle contains a given point.
-
- Circle2d.contains Point2d.origin exampleCircle
- --> True
-
- exampleCircle
- |> Circle2d.contains
- (Point2d.fromCoordinates ( 10, 10 ))
- --> False
-
--}
+{-| -}
contains : Point2d -> Circle2d -> Bool
contains point circle =
let
@@ -294,35 +184,14 @@ contains point circle =
Point2d.squaredDistanceFrom (centerPoint circle) point <= r * r
-{-| Scale a circle about a given point by a given scale.
-
- Circle2d.scaleAbout Point2d.origin 2 exampleCircle
- --> Circle2d.withRadius 6
- --> (Point2d.fromCoordinates ( 2, 4 ))
-
- exampleCircle
- |> Circle2d.scaleAbout
- (Point2d.fromCoordinates ( 1, 2 ))
- 0.5
- --> Circle2d.withRadius 1.5
- --> (Point2d.fromCoordinates ( 1, 2 ))
-
--}
+{-| -}
scaleAbout : Point2d -> Float -> Circle2d -> Circle2d
scaleAbout point scale (Types.Circle2d circle) =
withRadius (abs scale * circle.radius)
(Point2d.scaleAbout point scale circle.centerPoint)
-{-| Rotate a circle around a given point by a given angle (in radians).
-
- exampleCircle
- |> Circle2d.rotateAround Point2d.origin
- (degrees 90)
- --> Circle2d.withRadius 3
- --> (Point2d.fromCoordinates ( -2, 1 ))
-
--}
+{-| -}
rotateAround : Point2d -> Float -> Circle2d -> Circle2d
rotateAround point angle =
let
@@ -333,91 +202,38 @@ rotateAround point angle =
withRadius circle.radius (rotatePoint circle.centerPoint)
-{-| Translate a circle by a given displacement.
-
- exampleCircle
- |> Circle2d.translateBy
- (Vector2d.fromComponents ( 2, 2 ))
- --> Circle2d.withRadius 3
- --> (Point2d.fromCoordinates ( 3, 4 ))
-
--}
+{-| -}
translateBy : Vector2d -> Circle2d -> Circle2d
translateBy displacement (Types.Circle2d circle) =
withRadius circle.radius
(Point2d.translateBy displacement circle.centerPoint)
-{-| Translate a circle in a given direction by a given distance;
-
- Circle2d.translateIn direction distance
-
-is equivalent to
-
- Circle2d.translateBy
- (Vector2d.withLength distance direction)
-
--}
+{-| -}
translateIn : Direction2d -> Float -> Circle2d -> Circle2d
translateIn direction distance circle =
translateBy (Vector2d.withLength distance direction) circle
-{-| Mirror a circle across a given axis.
-
- Circle2d.mirrorAcross Axis2d.x exampleCircle
- --> Circle2d.withRadius 3
- --> (Point2d.fromCoordinates ( 1, -2 ))
-
--}
+{-| -}
mirrorAcross : Axis2d -> Circle2d -> Circle2d
mirrorAcross axis (Types.Circle2d circle) =
withRadius circle.radius (Point2d.mirrorAcross axis circle.centerPoint)
-{-| Take a circle defined in global coordinates, and return it expressed in
-local coordinates relative to a given reference frame.
-
- localFrame =
- Frame2d.atPoint (Point2d.fromCoordinates ( 2, 3 ))
-
- Circle2d.relativeTo localFrame exampleCircle
- --> Circle2d.withRadius 3
- --> (Point2d.fromCoordinates ( -1, -1 ))
-
--}
+{-| -}
relativeTo : Frame2d -> Circle2d -> Circle2d
relativeTo frame (Types.Circle2d circle) =
withRadius circle.radius (Point2d.relativeTo frame circle.centerPoint)
-{-| Take a circle considered to be defined in local coordinates relative to a
-given reference frame, and return that circle expressed in global coordinates.
-
- localFrame =
- Frame2d.atPoint (Point2d.fromCoordinates ( 2, 3 ))
-
- Circle2d.placeIn localFrame exampleCircle
- --> Circle2d.withRadius 3
- --> (Point2d.fromCoordinates ( 3, 5 ))
-
--}
+{-| -}
placeIn : Frame2d -> Circle2d -> Circle2d
placeIn frame (Types.Circle2d circle) =
withRadius circle.radius (Point2d.placeIn frame circle.centerPoint)
-{-| Get the minimal bounding box containing a given circle.
-
- Circle2d.boundingBox exampleCircle
- --> BoundingBox2d.fromExtrema
- --> { minX = -2
- --> , maxX = 4
- --> , minY = -1
- --> , maxY = 5
- --> }
-
--}
+{-| -}
boundingBox : Circle2d -> BoundingBox2d
boundingBox circle =
let
diff --git a/src/Circle3d.elm b/src/Circle3d.elm
index 40ca43c5..170d7088 100644
--- a/src/Circle3d.elm
+++ b/src/Circle3d.elm
@@ -79,16 +79,7 @@ type alias Circle3d =
Types.Circle3d
-{-| Construct a circle from its radius, axial direction and center point:
-
- exampleCircle =
- Circle3d.withRadius 3
- Direction3d.z
- (Point3d.fromCoordinates ( 2, 0, 1 ))
-
-If you pass a negative radius, the absolute value will be used.
-
--}
+{-| -}
withRadius : Float -> Direction3d -> Point3d -> Circle3d
withRadius radius_ axialDirection_ centerPoint_ =
Types.Circle3d
@@ -98,15 +89,7 @@ withRadius radius_ axialDirection_ centerPoint_ =
}
-{-| Construct a circle by sweeping the given point around the given axis.
-
- Circle3d.sweptAround Axis3d.z
- (Point3d.fromCoordinates ( 3, 0, 2 ))
- --> Circle3d.withRadius 3
- --> Direction3d.z
- --> (Point3d.fromCoordinates ( 0, 0, 2 ))
-
--}
+{-| -}
sweptAround : Axis3d -> Point3d -> Circle3d
sweptAround axis_ point =
let
@@ -118,18 +101,7 @@ sweptAround axis_ point =
centerPoint_
-{-| Construct a 3D circle lying _on_ a sketch plane by providing a 2D circle
-specified in XY coordinates _within_ the sketch plane.
-
- Circle3d.on SketchPlane3d.yz <|
- Circle2d.withRadius 3
- (Point2d.fromCoordinates ( 1, 2 ))
-
- --> Circle3d.withRadius 3
- --> Direction3d.x
- --> (Point3d.fromCoordinates ( 0, 1, 2 ))
-
--}
+{-| -}
on : SketchPlane3d -> Circle2d -> Circle3d
on sketchPlane circle =
withRadius (Circle2d.radius circle)
@@ -137,27 +109,7 @@ on sketchPlane circle =
(Point3d.on sketchPlane (Circle2d.centerPoint circle))
-{-| Attempt to construct a circle that passes through the three given points.
-The axial direction of the returned circle will be such that the three points
-are in counterclockwise order around it, according to the right-hand rule. If
-the three given points are collinear, returns `Nothing`.
-
- Circle3d.throughPoints
- (Point3d.fromCoordinates ( 1, 0, 0 ))
- (Point3d.fromCoordinates ( 0, 1, 0 ))
- (Point3d.fromCoordinates ( 0, 0, 1 ))
- --> Just
- --> (Circle3d.withRadius 0.8165
- --> (Direction3d.fromAzimuthAndElevation
- --> (degrees 45)
- --> (degrees 35.26)
- --> )
- --> (Point3d.fromCoordinates
- --> ( 0.333, 0.333, 0.333 )
- --> )
- --> )
-
--}
+{-| -}
throughPoints : Point3d -> Point3d -> Point3d -> Maybe Circle3d
throughPoints p1 p2 p3 =
Maybe.map2
@@ -181,83 +133,43 @@ throughPoints p1 p2 p3 =
(Plane3d.throughPoints p1 p2 p3)
-{-| Get the center point of a circle.
-
- Circle3d.centerPoint exampleCircle
- --> Point3d.fromCoordinates ( 2, 0, 1 )
-
--}
+{-| -}
centerPoint : Circle3d -> Point3d
centerPoint (Types.Circle3d circle) =
circle.centerPoint
-{-| Get the axial direction of a circle.
-
- Circle3d.axialDirection exampleCircle
- --> Direction3d.z
-
--}
+{-| -}
axialDirection : Circle3d -> Direction3d
axialDirection (Types.Circle3d circle) =
circle.axialDirection
-{-| Get the central axis of a circle, perpendicular to its [`plane`](#plane).
-The origin point of the returned axis will be the center point of the circle.
-
- Circle3d.axis exampleCircle
- --> Axis3d.withDirection Direction3d.z
- --> (Point3d.fromCoordinates ( 2, 0, 1 ))
-
--}
+{-| -}
axis : Circle3d -> Axis3d
axis (Types.Circle3d circle) =
Axis3d.through circle.centerPoint circle.axialDirection
-{-| Get the plane that a circle lies in. The origin point of the returned plane
-will be the center point of the circle, and its normal direction will be the
-axial direction of the circle.
-
- Circle3d.plane exampleCircle
- --> Plane3d.withNormalDirection Direction3d.z
- --> (Point3d.fromCoordinates ( 2, 0, 1 ))
-
--}
+{-| -}
plane : Circle3d -> Plane3d
plane circle =
Plane3d.through (centerPoint circle) (axialDirection circle)
-{-| Get the radius of a circle.
-
- Circle3d.radius exampleCircle
- --> 3
-
--}
+{-| -}
radius : Circle3d -> Float
radius (Types.Circle3d properties) =
properties.radius
-{-| Get the diameter of a circle.
-
- Circl3d.diameter exampleCircle
- --> 6
-
--}
+{-| -}
diameter : Circle3d -> Float
diameter circle =
2 * radius circle
-{-| Get the area of a circle.
-
- Circle3d.area exampleCircle
- --> 28.2743
-
--}
+{-| -}
area : Circle3d -> Float
area circle =
let
@@ -267,25 +179,13 @@ area circle =
pi * r * r
-{-| Get the circumference of a circle.
-
- Circle3d.circumference exampleCircle
- --> 18.8496
-
--}
+{-| -}
circumference : Circle3d -> Float
circumference circle =
2 * pi * radius circle
-{-| Scale a circle around a given point by a given scale.
-
- Circle3d.scaleAbout Point3d.origin 3 exampleCircle
- --> Circle3d.withRadius 3
- --> Direction3d.z
- --> (Point3d.fromCoordinates ( 6, 0, 3 ))
-
--}
+{-| -}
scaleAbout : Point3d -> Float -> Circle3d -> Circle3d
scaleAbout point scale circle =
withRadius (abs scale * radius circle)
@@ -297,15 +197,7 @@ scaleAbout point scale circle =
(Point3d.scaleAbout point scale (centerPoint circle))
-{-| Rotate a circle around a given axis by a given angle (in radians).
-
- exampleCircle
- |> Circle3d.rotateAround Axis3d.y (degrees 90)
- --> Circle3d.withRadius 3
- --> Direction3d.x
- --> (Point3d.fromCoordinates ( 1, 0, -2 ))
-
--}
+{-| -}
rotateAround : Axis3d -> Float -> Circle3d -> Circle3d
rotateAround axis_ angle =
let
@@ -321,17 +213,7 @@ rotateAround axis_ angle =
(rotatePoint (centerPoint circle))
-{-| Translate a circle by a given displacement.
-
- displacement =
- Vector3d.fromComponents ( 2, 1, 3 )
-
- Circle3d.translateBy displacement exampleCircle
- --> Circle3d.withRadius 3
- --> Direction3d.z
- --> (Point3d.fromCoordinates ( 4, 1, 4 ))
-
--}
+{-| -}
translateBy : Vector3d -> Circle3d -> Circle3d
translateBy displacement circle =
withRadius (radius circle)
@@ -339,29 +221,13 @@ translateBy displacement circle =
(Point3d.translateBy displacement (centerPoint circle))
-{-| Translate a circle in a given direction by a given distance;
-
- Circle3d.translateIn direction distance
-
-is equivalent to
-
- Circle3d.translateBy
- (Vector3d.withLength distance direction)
-
--}
+{-| -}
translateIn : Direction3d -> Float -> Circle3d -> Circle3d
translateIn direction distance circle =
translateBy (Vector3d.withLength distance direction) circle
-{-| Mirror a circle across a given plane.
-
- Circle3d.mirrorAcross Plane3d.xy exampleCircle
- --> Circle3d.withRadius 3
- --> Direction3d.negativeZ
- --> (Point3d.fromCoordinates ( 2, 0, -1 ))
-
--}
+{-| -}
mirrorAcross : Plane3d -> Circle3d -> Circle3d
mirrorAcross plane_ circle =
withRadius (radius circle)
@@ -369,27 +235,7 @@ mirrorAcross plane_ circle =
(Point3d.mirrorAcross plane_ (centerPoint circle))
-{-| Project a circle into a sketch plane.
-
- inclinedCircle : Circle3d
- inclinedCircle =
- Circle3d.withRadius 1
- (Direction3d.fromAzimuthAndElevation
- (degrees 0)
- (degrees 45)
- )
- (Point3d.fromCoordinates ( 1, 2, 3 ))
-
- Circle3d.projectInto SketchPlane3d.xy inclinedCircle
- --> Ellipse2d.with
- --> { centerPoint =
- --> Point2d.fromCoordinates ( 1, 2 )
- --> , xDirection = Direction2d.negativeY
- --> , xRadius = 1
- --> , yRadius = 0.7071
- --> }
-
--}
+{-| -}
projectInto : SketchPlane3d -> Circle3d -> Types.Ellipse2d
projectInto sketchPlane circle =
let
@@ -435,19 +281,7 @@ projectInto sketchPlane circle =
}
-{-| Take a circle defined in global coordinates, and return it expressed in
-local coordinates relative to a given reference frame.
-
- localFrame =
- Frame3d.atPoint
- (Point3d.fromCoordinates ( 1, 2, 3 ))
-
- Circle3d.relativeTo localFrame exampleCircle
- --> Circle3d.withRadius 3
- --> Direction3d.z
- --> (Point3d.fromCoordinates ( 1, -2, -2 ))
-
--}
+{-| -}
relativeTo : Frame3d -> Circle3d -> Circle3d
relativeTo frame circle =
withRadius (radius circle)
@@ -455,19 +289,7 @@ relativeTo frame circle =
(Point3d.relativeTo frame (centerPoint circle))
-{-| Take a circle considered to be defined in local coordinates relative to a
-given reference frame, and return that circle expressed in global coordinates.
-
- localFrame =
- Frame3d.atPoint
- (Point3d.fromCoordinates ( 1, 2, 3 ))
-
- Circle3d.placeIn localFrame exampleCircle
- --> Circle3d.withRadius 3
- --> Direction3d.z
- --> (Point3d.fromCoordinates ( 3, 2, 4 ))
-
--}
+{-| -}
placeIn : Frame3d -> Circle3d -> Circle3d
placeIn frame circle =
withRadius (radius circle)
@@ -475,19 +297,7 @@ placeIn frame circle =
(Point3d.placeIn frame (centerPoint circle))
-{-| Get the minimal bounding box containing a given circle.
-
- Circle3d.boundingBox exampleCircle
- --> BoundingBox3d.fromExtrema
- --> { minX = -1
- --> , maxX = 5
- --> , minY = -3
- --> , maxY = 3
- --> , minZ = 1
- --> , maxZ = 1
- --> }
-
--}
+{-| -}
boundingBox : Circle3d -> BoundingBox3d
boundingBox circle =
let
diff --git a/src/CubicSpline2d.elm b/src/CubicSpline2d.elm
index 74aa7a8d..babd1602 100644
--- a/src/CubicSpline2d.elm
+++ b/src/CubicSpline2d.elm
@@ -134,36 +134,13 @@ type alias CubicSpline2d =
Types.CubicSpline2d
-{-| Construct a spline from its endpoints and control points:
-
- exampleSpline =
- CubicSpline2d.with
- { startPoint =
- Point2d.fromCoordinates ( 1, 1 )
- , startControlPoint =
- Point2d.fromCoordinates ( 3, 4 )
- , endControlPoint =
- Point2d.fromCoordinates ( 5, 1 )
- , endPoint =
- Point2d.fromCoordinates ( 7, 4 )
- }
-
--}
+{-| -}
with : { startPoint : Point2d, startControlPoint : Point2d, endControlPoint : Point2d, endPoint : Point2d } -> CubicSpline2d
with =
Types.CubicSpline2d
-{-| Construct a spline from a given start point with a given start derivative,
-to a given end point with a given end derivative, like so:
-
-
-
-The spline is based on a parameter that ranges from 0 to 1; as a result, in most
-cases the length of each derivative vector should be roughly equal to the length
-of the resulting spline.
-
--}
+{-| -}
fromEndpoints : { startPoint : Point2d, startDerivative : Vector2d, endPoint : Point2d, endDerivative : Vector2d } -> CubicSpline2d
fromEndpoints arguments =
let
@@ -185,32 +162,7 @@ fromEndpoints arguments =
}
-{-| Convert a quadratic spline into the equivalent cubic spline (every quadratic
-spline can be represented exactly as a cubic spline).
-
- quadraticSpline =
- QuadraticSpline2d.with
- { startPoint =
- Point2d.fromCoordinates ( 0, 0 )
- , controlPoint =
- Point2d.fromCoordinates ( 3, 0 )
- , endPoint =
- Point2d.fromCoordinates ( 3, 3 )
- }
-
- CubicSpline2d.fromQuadraticSpline quadraticSpline
- --> CubicSpline2d.with
- --> { startPoint =
- --> Point2d.fromCoordinates ( 0, 0 )
- --> , startControlPoint =
- --> Point2d.fromCoordinates ( 2, 0 )
- --> , endControlPoint =
- --> Point2d.fromCoordinates ( 3, 1 )
- --> , endPoint =
- --> Point2d.fromCoordinates ( 3, 3 )
- --> }
-
--}
+{-| -}
fromQuadraticSpline : QuadraticSpline2d -> CubicSpline2d
fromQuadraticSpline quadraticSpline =
let
@@ -237,92 +189,45 @@ fromQuadraticSpline quadraticSpline =
}
-{-| Get the start point of a spline.
-
- CubicSpline2d.startPoint exampleSpline
- --> Point2d.fromCoordinates ( 1, 1 )
-
--}
+{-| -}
startPoint : CubicSpline2d -> Point2d
startPoint (Types.CubicSpline2d spline) =
spline.startPoint
-{-| Get the end point of a spline.
-
- CubicSpline2d.endPoint exampleSpline
- --> Point2d.fromCoordinates ( 7, 4 )
-
--}
+{-| -}
endPoint : CubicSpline2d -> Point2d
endPoint (Types.CubicSpline2d spline) =
spline.endPoint
-{-| Get the start control point of a spline (the control point next to the
-start point).
-
- CubicSpline2d.startControlPoint exampleSpline
- --> Point2d.fromCoordinates ( 3, 4 )
-
--}
+{-| -}
startControlPoint : CubicSpline2d -> Point2d
startControlPoint (Types.CubicSpline2d spline) =
spline.startControlPoint
-{-| Get the end control point of a spline (the control point next to the
-end point).
-
- CubicSpline2d.endControlPoint exampleSpline
- --> Point2d.fromCoordinates ( 5, 1 )
-
--}
+{-| -}
endControlPoint : CubicSpline2d -> Point2d
endControlPoint (Types.CubicSpline2d spline) =
spline.endControlPoint
-{-| Get the start derivative of a spline. This is equal to three times the
-vector from the spline's start point to its start control point.
-
- CubicSpline2d.startDerivative exampleSpline
- --> Vector2d.fromComponents ( 6, 9 )
-
--}
+{-| -}
startDerivative : CubicSpline2d -> Vector2d
startDerivative spline =
Vector2d.from (startPoint spline) (startControlPoint spline)
|> Vector2d.scaleBy 3
-{-| Get the end derivative of a spline. This is equal to three times the vector
-from the spline's end control point to its end point.
-
- CubicSpline2d.endDerivative exampleSpline
- --> Vector2d.fromComponents ( 6, 9 )
-
--}
+{-| -}
endDerivative : CubicSpline2d -> Vector2d
endDerivative spline =
Vector2d.from (endControlPoint spline) (endPoint spline)
|> Vector2d.scaleBy 3
-{-| Compute a bounding box for a given spline. It is not guaranteed that the
-result will be the _smallest_ possible bounding box, since for efficiency the
-bounding box is computed from the spline's control points (which cover a larger
-area than the spline itself).
-
- CubicSpline2d.boundingBox exampleSpline
- --> BoundingBox2d.fromExtrema
- --> { minX = 1
- --> , maxX = 7
- --> , minY = 1
- --> , maxY = 4
- --> }
-
--}
+{-| -}
boundingBox : CubicSpline2d -> BoundingBox2d
boundingBox spline =
let
@@ -346,18 +251,7 @@ boundingBox spline =
}
-{-| Get the point along a spline at a given parameter value:
-
- CubicSpline2d.pointOn exampleSpline ParameterValue.zero
- --> Point2d.fromCoordinates ( 1, 1 )
-
- CubicSpline2d.pointOn exampleSpline ParameterValue.half
- --> Point2d.fromCoordinates ( 4, 2.5 )
-
- CubicSpline2d.pointOn exampleSpline ParameterValue.one
- --> Point2d.fromCoordinates ( 7, 4 )
-
--}
+{-| -}
pointOn : CubicSpline2d -> ParameterValue -> Point2d
pointOn spline parameterValue =
let
@@ -394,45 +288,20 @@ pointOn spline parameterValue =
Point2d.interpolateFrom r1 r2 t
-{-| Get points along a spline at a given set of parameter values:
-
- exampleSpline
- |> CubicSpline2d.pointsAt
- (ParameterValue.steps 2)
- --> [ Point2d.fromCoordinates ( 1, 1 )
- --> , Point2d.fromCoordinates ( 4, 2.5 )
- --> , Point2d.fromCoordinates ( 7, 4 )
- --> ]
-
--}
+{-| -}
pointsAt : List ParameterValue -> CubicSpline2d -> List Point2d
pointsAt parameterValues spline =
List.map (pointOn spline) parameterValues
-{-| If a curve has zero length (consists of just a single point), then we say
-that it is 'degenerate'. Some operations such as computing tangent directions
-are not defined on degenerate curves.
-
-A `Nondegenerate` value represents a spline that is definitely not degenerate.
-It is used as input to functions such as `CubicSpline2d.tangentDirection` and
-can be constructed using `CubicSpline2d.nondegenerate`.
-
--}
+{-| -}
type Nondegenerate
= NonZeroThirdDerivative CubicSpline2d Direction2d
| NonZeroSecondDerivative CubicSpline2d Direction2d
| NonZeroFirstDerivative CubicSpline2d Direction2d
-{-| Attempt to construct a nondegenerate spline from a general `CubicSpline2d`.
-If the spline is in fact degenerate (consists of a single point), returns an
-`Err` with that point.
-
- CubicSpline2d.nondegenerate exampleSpline
- --> Ok nondegenerateExampleSpline
-
--}
+{-| -}
nondegenerate : CubicSpline2d -> Result Point2d Nondegenerate
nondegenerate spline =
case Vector2d.direction (thirdDerivative spline) of
@@ -473,13 +342,7 @@ nondegenerate spline =
Err (startPoint spline)
-{-| Convert a nondegenerate spline back to a general `CubicSpline2d`.
-
- CubicSpline2d.fromNondegenerate
- nondegenerateExampleSpline
- --> exampleSpline
-
--}
+{-| -}
fromNondegenerate : Nondegenerate -> CubicSpline2d
fromNondegenerate nondegenerateSpline =
case nondegenerateSpline of
@@ -493,25 +356,7 @@ fromNondegenerate nondegenerateSpline =
spline
-{-| Get the tangent direction to a nondegenerate spline at a given parameter
-value:
-
- CubicSpline2d.tangentDirection
- nondegenerateExampleSpline
- ParameterValue.zero
- --> Direction2d.fromAngle (degrees 56.31)
-
- CubicSpline2d.tangentDirection
- nondegenerateExampleSpline
- ParameterValue.half
- --> Direction2d.fromAngle (degrees 0)
-
- CubicSpline2d.tangentDirection
- nondegenerateExampleSpline
- ParameterValue.one
- --> Direction2d.fromAngle (degrees 56.31)
-
--}
+{-| -}
tangentDirection : Nondegenerate -> ParameterValue -> Direction2d
tangentDirection nondegenerateSpline parameterValue =
case nondegenerateSpline of
@@ -579,33 +424,13 @@ tangentDirection nondegenerateSpline parameterValue =
thirdDerivativeDirection
-{-| Get tangent directions to a nondegenerate spline at a given set of parameter
-values:
-
- nondegenerateExampleSpline
- |> CubicSpline2d.tangentDirectionsAt
- (ParameterValue.steps 2)
- --> [ Direction2d.fromAngle (degrees 56.31)
- --> , Direction2d.fromAngle (degrees 0)
- --> , Direction2d.fromAngle (degrees 56.31)
- --> ]
-
--}
+{-| -}
tangentDirectionsAt : List ParameterValue -> Nondegenerate -> List Direction2d
tangentDirectionsAt parameterValues nondegenerateSpline =
List.map (tangentDirection nondegenerateSpline) parameterValues
-{-| Get both the point and tangent direction of a nondegenerate spline at a
-given parameter value:
-
- CubicSpline2d.sample nondegenerateExampleSpline
- ParameterValue.half
- --> ( Point2d.fromCoordinates ( 4, 2.5 )
- --> , Direction2d.fromAngle (degrees 0)
- --> )
-
--}
+{-| -}
sample : Nondegenerate -> ParameterValue -> ( Point2d, Direction2d )
sample nondegenerateSpline parameterValue =
( pointOn (fromNondegenerate nondegenerateSpline) parameterValue
@@ -613,45 +438,13 @@ sample nondegenerateSpline parameterValue =
)
-{-| Get points and tangent directions of a nondegenerate spline at a given set
-of parameter values:
-
- nondegenerateExampleSpline
- |> CubicSpline2d.samplesAt
- (ParameterValue.steps 2)
- --> [ ( Point2d.fromCoordinates ( 1, 1 )
- --> , Direction2d.fromAngle (degrees 56.31)
- --> )
- --> , ( Point2d.fromCoordinates ( 4, 2.5 )
- --> , Direction2d.fromAngle (degrees 0)
- --> )
- --> , ( Point2d.fromCoordinates ( 7, 4 )
- --> , Direction2d.fromAngle (degrees 56.31)
- --> )
- --> ]
-
--}
+{-| -}
samplesAt : List ParameterValue -> Nondegenerate -> List ( Point2d, Direction2d )
samplesAt parameterValues nondegenerateSpline =
List.map (sample nondegenerateSpline) parameterValues
-{-| Reverse a spline so that the start point becomes the end point, and vice
-versa.
-
- CubicSpline2d.reverse exampleSpline
- --> CubicSpline2d.with
- --> { startPoint =
- --> Point2d.fromCoordinates ( 7, 4 )
- --> , startControlPoint =
- --> Point2d.fromCoordinates ( 5, 1 )
- --> , endControlPoint =
- --> Point2d.fromCoordinates ( 3, 4 )
- --> , endPoint =
- --> Point2d.fromCoordinates ( 1, 1 )
- --> }
-
--}
+{-| -}
reverse : CubicSpline2d -> CubicSpline2d
reverse spline =
with
@@ -662,150 +455,43 @@ reverse spline =
}
-{-| Scale a spline about the given center point by the given scale.
-
- CubicSpline2d.scaleAbout Point2d.origin 2 exampleSpline
- --> CubicSpline2d.with
- --> { startPoint =
- --> Point2d.fromCoordinates ( 2, 2 )
- --> , startControlPoint =
- --> Point2d.fromCoordinates ( 6, 8 )
- --> , endControlPoint =
- --> Point2d.fromCoordinates ( 10, 2 )
- --> , endPoint =
- --> Point2d.fromCoordinates ( 14, 8 )
- --> }
-
--}
+{-| -}
scaleAbout : Point2d -> Float -> CubicSpline2d -> CubicSpline2d
scaleAbout point scale =
mapControlPoints (Point2d.scaleAbout point scale)
-{-| Rotate a spline counterclockwise around a given center point by a given
-angle (in radians).
-
- exampleSpline
- |> CubicSpline2d.rotateAround Point2d.origin
- (degrees 90)
- --> CubicSpline2d.with
- --> { startPoint =
- --> Point2d.fromCoordinates ( -1, 1 )
- --> , startControlPoint =
- --> Point2d.fromCoordinates ( -4, 3 )
- --> , endControlPoint =
- --> Point2d.fromCoordinates ( -1, 5 )
- --> , endPoint =
- --> Point2d.fromCoordinates ( -4, 7 )
- --> }
-
--}
+{-| -}
rotateAround : Point2d -> Float -> CubicSpline2d -> CubicSpline2d
rotateAround point angle =
mapControlPoints (Point2d.rotateAround point angle)
-{-| Translate a spline by a given displacement.
-
- displacement =
- Vector2d.fromComponents ( 2, 3 )
-
- CubicSpline2d.translateBy displacement exampleSpline
- --> CubicSpline2d.with
- --> { startPoint =
- --> Point2d.fromCoordinates ( 3, 4 )
- --> , startControlPoint =
- --> Point2d.fromCoordinates ( 5, 7 )
- --> , endControlPoint =
- --> Point2d.fromCoordinates ( 7, 4 )
- --> , endPoint =
- --> Point2d.fromCoordinates ( 9, 7 )
- --> }
-
--}
+{-| -}
translateBy : Vector2d -> CubicSpline2d -> CubicSpline2d
translateBy displacement =
mapControlPoints (Point2d.translateBy displacement)
-{-| Translate a spline in a given direction by a given distance;
-
- CubicSpline2d.translateIn direction distance
-
-is equivalent to
-
- CubicSpline2d.translateBy
- (Vector2d.withLength distance direction)
-
--}
+{-| -}
translateIn : Direction2d -> Float -> CubicSpline2d -> CubicSpline2d
translateIn direction distance spline =
translateBy (Vector2d.withLength distance direction) spline
-{-| Mirror a spline across an axis.
-
- CubicSpline2d.mirrorAcross Axis2d.x exampleSpline
- --> CubicSpline2d.with
- --> { startPoint =
- --> Point2d.fromCoordinates ( 1, -1 )
- --> , startControlPoint =
- --> Point2d.fromCoordinates ( 3, -4 )
- --> , endControlPoint =
- --> Point2d.fromCoordinates ( 5, -1 )
- --> , endPoint =
- --> Point2d.fromCoordinates ( 7, -4 )
- --> }
-
--}
+{-| -}
mirrorAcross : Axis2d -> CubicSpline2d -> CubicSpline2d
mirrorAcross axis =
mapControlPoints (Point2d.mirrorAcross axis)
-{-| Take a spline defined in global coordinates, and return it expressed in
-local coordinates relative to a given reference frame.
-
- localFrame =
- Frame2d.atPoint (Point2d.fromCoordinates ( 1, 2 ))
-
- CubicSpline2d.relativeTo localFrame exampleSpline
- --> CubicSpline2d.with
- --> { startPoint =
- --> Point2d.fromCoordinates ( 0, -1 )
- --> , startControlPoint =
- --> Point2d.fromCoordinates ( 2, 2 )
- --> , endControlPoint =
- --> Point2d.fromCoordinates ( 4, -1 )
- --> , endPoint =
- --> Point2d.fromCoordinates ( 6, 2 )
- --> }
-
--}
+{-| -}
relativeTo : Frame2d -> CubicSpline2d -> CubicSpline2d
relativeTo frame =
mapControlPoints (Point2d.relativeTo frame)
-{-| Take a spline considered to be defined in local coordinates relative to a
-given reference frame, and return that spline expressed in global coordinates.
-
- localFrame =
- Frame2d.atPoint (Point2d.fromCoordinates ( 1, 2 ))
-
- CubicSpline2d.placeIn localFrame exampleSpline
- --> CubicSpline2d.with
- --> { startPoint =
- --> Point2d.fromCoordinates ( 2, 3 )
- --> , startControlPoint =
- --> Point2d.fromCoordinates ( 4, 6 )
- --> , endControlPoint =
- --> Point2d.fromCoordinates ( 6, 3 )
- --> , endPoint =
- --> Point2d.fromCoordinates ( 8, 6 )
- --> }
-
--}
+{-| -}
placeIn : Frame2d -> CubicSpline2d -> CubicSpline2d
placeIn frame =
mapControlPoints (Point2d.placeIn frame)
@@ -821,69 +507,13 @@ mapControlPoints function spline =
}
-{-| Split a spline into two roughly equal halves.
-
- CubicSpline2d.bisect exampleSpline
- --> ( CubicSpline2d.with
- --> { startPoint =
- --> Point2d.fromCoordinates ( 1, 1 )
- --> , startControlPoint =
- --> Point2d.fromCoordinates ( 2, 2.5 )
- --> , endControlPoint =
- --> Point2d.fromCoordinates ( 3, 2.5 )
- --> , endPoint =
- --> Point2d.fromCoordinates ( 4, 2.5 )
- --> }
- --> , CubicSpline2d.with
- --> { startPoint =
- --> Point2d.fromCoordinates ( 4, 2.5 )
- --> , startControlPoint =
- --> Point2d.fromCoordinates ( 5, 2.5 )
- --> , endControlPoint =
- --> Point2d.fromCoordinates ( 6, 2.5 )
- --> , endPoint =
- --> Point2d.fromCoordinates ( 7, 4 )
- --> }
- --> )
-
-Equivalent to `CubicSpline2d.splitAt ParameterValue.half`.
-
--}
+{-| -}
bisect : CubicSpline2d -> ( CubicSpline2d, CubicSpline2d )
bisect =
splitAt ParameterValue.half
-{-| Split a spline at a particular parameter value, resulting in two smaller
-splines.
-
- parameterValue =
- ParameterValue.clamped 0.75
-
- CubicSpline2d.splitAt parameterValue exampleSpline
- --> ( CubicSpline2d.with
- --> { startPoint =
- --> Point2d.fromCoordinates ( 1, 1 )
- --> , startControlPoint =
- --> Point2d.fromCoordinates ( 2.5, 3.25 )
- --> , endControlPoint =
- --> Point2d.fromCoordinates ( 4, 2.125 )
- --> , endPoint =
- --> Point2d.fromCoordinates ( 5.5, 2.6875 )
- --> }
- --> , CubicSpline2d.with
- --> { startPoint =
- --> Point2d.fromCoordinates ( 5.5, 2.6875 )
- --> , startControlPoint =
- --> Point2d.fromCoordinates ( 6, 2.875 )
- --> , endControlPoint =
- --> Point2d.fromCoordinates ( 6.5, 3.25 )
- --> , endPoint =
- --> Point2d.fromCoordinates ( 7, 4 )
- --> }
- --> )
-
--}
+{-| -}
splitAt : ParameterValue -> CubicSpline2d -> ( CubicSpline2d, CubicSpline2d )
splitAt parameterValue spline =
let
@@ -935,8 +565,7 @@ splitAt parameterValue spline =
)
-{-| A spline that has been parameterized by arc length.
--}
+{-| -}
type ArcLengthParameterized
= ArcLengthParameterized
{ underlyingSpline : CubicSpline2d
@@ -945,20 +574,7 @@ type ArcLengthParameterized
}
-{-| Build an arc length parameterization of the given spline, with a given
-accuracy. Generally speaking, all operations on the resulting
-`ArcLengthParameterized` value will be accurate to within the specified maximum
-error.
-
- parameterizedSpline =
- exampleSpline
- |> CubicSpline2d.arcLengthParameterized
- { maxError = 1.0e-4 }
-
-The accuracy of the parameterization affects the accuracy of results returned
-from functions such as `arcLength` and `pointAlong`.
-
--}
+{-| -}
arcLengthParameterized : { maxError : Float } -> CubicSpline2d -> ArcLengthParameterized
arcLengthParameterized { maxError } spline =
let
@@ -977,42 +593,14 @@ arcLengthParameterized { maxError } spline =
}
-{-| Find the total arc length of a spline:
-
- arcLength =
- CubicSpline2d.arcLength parameterizedSpline
-
- arcLength
- --> 7.0952
-
-In this example, the result will be accurate to within `1.0e-4` since that was
-the tolerance used when constructing `parameterizedSpline`.
-
--}
+{-| -}
arcLength : ArcLengthParameterized -> Float
arcLength parameterizedSpline =
arcLengthParameterization parameterizedSpline
|> ArcLengthParameterization.totalArcLength
-{-| Try to get the point along a spline at a given arc length. For example, to
-get the point a quarter of the way along `exampleSpline`, using `arcLength` as
-computed above:
-
- CubicSpline2d.pointAlong parameterizedSpline
- (0.25 * arcLength)
- --> Just (Point2d.fromCoordinates ( 2.2681, 2.2114 ))
-
-Note that this is not the same as evaulating at a parameter value of 0.25:
-
- CubicSpline2d.pointOn exampleSpline
- (ParameterValue.clamped 0.25)
- --> Point2d.fromCoordinates ( 2.5, 2.3125 )
-
-If the given arc length is less than zero or greater than the arc length of the
-spline, returns `Nothing`.
-
--}
+{-| -}
pointAlong : ArcLengthParameterized -> Float -> Maybe Point2d
pointAlong (ArcLengthParameterized parameterized) distance =
parameterized.parameterization
@@ -1020,17 +608,7 @@ pointAlong (ArcLengthParameterized parameterized) distance =
|> Maybe.map (pointOn parameterized.underlyingSpline)
-{-| Try to get the tangent direction along a spline at a given arc length. To
-get the tangent direction a quarter of the way along `exampleSpline`:
-
- CubicSpline2d.tangentDirectionAlong parameterizedSpline
- (0.25 * arcLength)
- --> Just (Direction2d.fromAngle (degrees 26.5611))
-
-If the given arc length is less than zero or greater than the arc length of the
-spline (or if the spline is degenerate), returns `Nothing`.
-
--}
+{-| -}
tangentDirectionAlong : ArcLengthParameterized -> Float -> Maybe Direction2d
tangentDirectionAlong (ArcLengthParameterized parameterized) distance =
case parameterized.nondegenerateSpline of
@@ -1043,21 +621,7 @@ tangentDirectionAlong (ArcLengthParameterized parameterized) distance =
Nothing
-{-| Try to get the point and tangent direction along a spline at a given arc
-length. To get the point and tangent direction a quarter of the way along
-`exampleSpline`:
-
- CubicSpline2d.sampleAlong parameterizedSpline
- (0.25 * arcLength)
- --> Just
- --> ( Point2d.fromCoordinates ( 2.2681, 2.2114 )
- --> , Direction2d.fromAngle (degrees 26.5611)
- --> )
-
-If the given arc length is less than zero or greater than the arc length of the
-spline (or if the spline is degenerate), returns `Nothing`.
-
--}
+{-| -}
sampleAlong : ArcLengthParameterized -> Float -> Maybe ( Point2d, Direction2d )
sampleAlong (ArcLengthParameterized parameterized) distance =
case parameterized.nondegenerateSpline of
@@ -1082,21 +646,7 @@ fromArcLengthParameterized (ArcLengthParameterized parameterized) =
parameterized.underlyingSpline
-{-| Get the first derivative of a spline at a given parameter value:
-
- CubicSpline2d.firstDerivative exampleSpline
- ParameterValue.zero
- --> Vector2d.fromComponents ( 6, 9 )
-
- CubicSpline2d.firstDerivative exampleSpline
- ParameterValue.half
- --> Vector2d.fromComponents ( 6, 0 )
-
- CubicSpline2d.firstDerivative exampleSpline
- ParameterValue.one
- --> Vector2d.fromComponents ( 6, 9 )
-
--}
+{-| -}
firstDerivative : CubicSpline2d -> ParameterValue -> Vector2d
firstDerivative spline parameterValue =
let
@@ -1186,35 +736,13 @@ firstDerivative spline parameterValue =
)
-{-| Evaluate the first derivative of a spline at a given set of parameter
-values:
-
- exampleSpline
- |> CubicSpline2d.firstDerivativesAt
- (ParameterValue.steps 2)
- --> [ Vector2d.fromComponents ( 6, 9 )
- --> , Vector2d.fromComponents ( 6, 0 )
- --> , Vector2d.fromComponents ( 6, 9 )
- --> ]
-
--}
+{-| -}
firstDerivativesAt : List ParameterValue -> CubicSpline2d -> List Vector2d
firstDerivativesAt parameterValues spline =
List.map (firstDerivative spline) parameterValues
-{-| Evaluate the second derivative of a spline at a given parameter value:
-
- CubicSpline2d.secondDerivativeAt 0 exampleSpline
- --> Just (Vector2d.fromComponents ( 0, -36 ))
-
- CubicSpline2d.secondDerivativeAt 0.5 exampleSpline
- --> Just (Vector2d.fromComponents ( 0, 0 ))
-
- CubicSpline2d.secondDerivativeAt 1 exampleSpline
- --> Just (Vector2d.fromComponents ( 0, 36 ))
-
--}
+{-| -}
secondDerivative : CubicSpline2d -> ParameterValue -> Vector2d
secondDerivative spline parameterValue =
let
@@ -1251,30 +779,13 @@ secondDerivative spline parameterValue =
Vector2d.scaleBy 6 (Vector2d.interpolateFrom v1 v2 t)
-{-| Evaluate the second derivative of a spline at a given set of parameter
-values:
-
- exampleSpline
- |> CubicSpline2d.secondDerivativesAt
- (ParameterValue.steps 2)
- --> [ Vector2d.fromComponents ( 0, -36 )
- --> , Vector2d.fromComponents ( 0, 0 )
- --> , Vector2d.fromComponents ( 0, 36 )
- --> ]
-
--}
+{-| -}
secondDerivativesAt : List ParameterValue -> CubicSpline2d -> List Vector2d
secondDerivativesAt parameterValues spline =
List.map (secondDerivative spline) parameterValues
-{-| Get the third derivative of a spline (for a cubic spline, this is a
-constant):
-
- CubicSpline2d.thirdDerivative exampleSpline
- --> Vector2d.fromComponents ( 0, 72 )
-
--}
+{-| -}
thirdDerivative : CubicSpline2d -> Vector2d
thirdDerivative spline =
let
@@ -1308,15 +819,7 @@ thirdDerivative spline =
Vector2d.scaleBy 6 (Vector2d.difference v2 v1)
-{-| Find a conservative upper bound on the magnitude of the second derivative of
-a spline. This can be useful when determining error bounds for various kinds of
-linear approximations.
-
- exampleSpline
- |> CubicSpline2d.maxSecondDerivativeMagnitude
- --> 36
-
--}
+{-| -}
maxSecondDerivativeMagnitude : CubicSpline2d -> Float
maxSecondDerivativeMagnitude spline =
let
diff --git a/src/CubicSpline3d.elm b/src/CubicSpline3d.elm
index 90493af3..d7c7597e 100644
--- a/src/CubicSpline3d.elm
+++ b/src/CubicSpline3d.elm
@@ -114,9 +114,7 @@ these two values separately.
# Differentiation
You are unlikely to need to use these functions directly, but they are useful if
-you are writing low-level geometric algorithms. As with the other curve
-evaluation functions, passing a parameter value outside the range 0 to 1 will
-result in `Nothing`.
+you are writing low-level geometric algorithms.
@docs firstDerivative, firstDerivativesAt, secondDerivative, secondDerivativesAt, thirdDerivative, maxSecondDerivativeMagnitude
@@ -142,36 +140,13 @@ type alias CubicSpline3d =
Types.CubicSpline3d
-{-| Construct a spline from its four control points:
-
- exampleSpline =
- CubicSpline3d.with
- { startPoint =
- Point3d.fromCoordinates ( 1, 1, 1 )
- , startControlPoint =
- Point3d.fromCoordinates ( 3, 1, 1 )
- , endControlPoint =
- Point3d.fromCoordinates ( 3, 3, 1 )
- , endPoint =
- Point3d.fromCoordinates ( 3, 3, 3 )
- }
-
--}
+{-| -}
with : { startPoint : Point3d, startControlPoint : Point3d, endControlPoint : Point3d, endPoint : Point3d } -> CubicSpline3d
with =
Types.CubicSpline3d
-{-| Construct a spline from a given start point with a given start derivative,
-to a given end point with a given end derivative, like so:
-
-
-
-The spline is based on a parameter that ranges from 0 to 1; as a result, in most
-cases the length of each derivative vector should be roughly equal to the length
-of the resulting spline.
-
--}
+{-| -}
fromEndpoints : { startPoint : Point3d, startDerivative : Vector3d, endPoint : Point3d, endDerivative : Vector3d } -> CubicSpline3d
fromEndpoints arguments =
let
@@ -193,32 +168,7 @@ fromEndpoints arguments =
}
-{-| Construct a 3D spline lying _on_ a sketch plane by providing a 2D spline
-specified in XY coordinates _within_ the sketch plane.
-
- CubicSpline3d.on SketchPlane3d.xz <|
- CubicSpline2d.with
- { startPoint =
- Point2d.fromCoordinates ( 1, 1 )
- , startControlPoint =
- Point2d.fromCoordinates ( 3, 4 )
- , endControlPoint =
- Point2d.fromCoordinates ( 5, 1 )
- , endPoint =
- Point2d.fromCoordinates ( 7, 4 )
- }
- --> CubicSpline3d.with
- --> { startPoint =
- --> Point3d.fromCoordinates ( 1, 0, 1 )
- --> , startControlPoint =
- --> Point3d.fromCoordinates ( 3, 0, 4 )
- --> , endControlPoint =
- --> Point3d.fromCoordinates ( 5, 0, 1 )
- --> , endPoint =
- --> Point3d.fromCoordinates ( 7, 0, 4 )
- --> }
-
--}
+{-| -}
on : SketchPlane3d -> CubicSpline2d -> CubicSpline3d
on sketchPlane spline2d =
with
@@ -233,32 +183,7 @@ on sketchPlane spline2d =
}
-{-| Convert a quadratic spline into the equivalent cubic spline (every quadratic
-spline can be represented exactly as a cubic spline).
-
- quadraticSpline =
- QuadraticSpline3d.with
- { startPoint =
- Point3d.fromCoordinates ( 0, 0, 0 )
- , controlPoint =
- Point3d.fromCoordinates ( 3, 0, 0 )
- , endPoint =
- Point3d.fromCoordinates ( 3, 3, 0 )
- }
-
- CubicSpline3d.fromQuadraticSpline quadraticSpline
- --> CubicSpline3d.with
- --> { startPoint =
- --> Point3d.fromCoordinates ( 0, 0, 0 )
- --> , startControlPoint =
- --> Point3d.fromCoordinates ( 2, 0, 0 )
- --> , endControlPoint =
- --> Point3d.fromCoordinates ( 3, 1, 0 )
- --> , endPoint =
- --> Point3d.fromCoordinates ( 3, 3, 0 )
- --> )
-
--}
+{-| -}
fromQuadraticSpline : QuadraticSpline3d -> CubicSpline3d
fromQuadraticSpline quadraticSpline =
let
@@ -285,86 +210,45 @@ fromQuadraticSpline quadraticSpline =
}
-{-| Get the start point of a spline.
-
- CubicSpline3d.startPoint exampleSpline
- --> Point3d.fromCoordinates ( 1, 1, 1 )
-
--}
+{-| -}
startPoint : CubicSpline3d -> Point3d
startPoint (Types.CubicSpline3d spline) =
spline.startPoint
-{-| Get the end point of a spline.
-
- CubicSpline3d.endPoint exampleSpline
- --> Point3d.fromCoordinates ( 3, 3, 3 )
-
--}
+{-| -}
endPoint : CubicSpline3d -> Point3d
endPoint (Types.CubicSpline3d spline) =
spline.endPoint
-{-| Get the start control point of a spline (the control point next to the
-start point).
--}
+{-| -}
startControlPoint : CubicSpline3d -> Point3d
startControlPoint (Types.CubicSpline3d spline) =
spline.startControlPoint
-{-| Get the end control point of a spline (the control point next to the
-end point).
--}
+{-| -}
endControlPoint : CubicSpline3d -> Point3d
endControlPoint (Types.CubicSpline3d spline) =
spline.endControlPoint
-{-| Get the start derivative of a spline. This is equal to three times the
-vector from the spline's start point to its start control point.
-
- CubicSpline3d.startDerivative exampleSpline
- --> Vector3d.fromComponents ( 6, 0, 0 )
-
--}
+{-| -}
startDerivative : CubicSpline3d -> Vector3d
startDerivative spline =
Vector3d.from (startPoint spline) (startControlPoint spline)
|> Vector3d.scaleBy 3
-{-| Get the end derivative of a spline. This is equal to three times the vector
-from the spline's end control point to its end point.
-
- CubicSpline3d.endDerivative exampleSpline
- --> Vector3d.fromComponents ( 0, 0, 6 )
-
--}
+{-| -}
endDerivative : CubicSpline3d -> Vector3d
endDerivative spline =
Vector3d.from (endControlPoint spline) (endPoint spline)
|> Vector3d.scaleBy 3
-{-| Compute a bounding box for a given spline. It is not guaranteed that the
-result will be the _smallest_ possible bounding box, since for efficiency the
-bounding box is computed from the spline's control points (which cover a larger
-volume than the spline itself).
-
- CubicSpline3d.boundingBox exampleSpline
- --> BoundingBox3d.fromExtrema
- --> { minX = 1
- --> , maxX = 3
- --> , minY = 1
- --> , maxY = 3
- --> , minZ = 1
- --> , maxZ = 3
- --> }
-
--}
+{-| -}
boundingBox : CubicSpline3d -> BoundingBox3d
boundingBox spline =
let
@@ -390,18 +274,7 @@ boundingBox spline =
}
-{-| Get a point at a given parameter value.
-
- CubicSpline3d.pointOn exampleSpline ParameterValue.zero
- --> Point3d.fromCoordinates ( 1, 1, 1 )
-
- CubicSpline3d.pointOn exampleSpline ParameterValue.half
- --> Point3d.fromCoordinates ( 2.75, 2, 1.25 )
-
- CubicSpline3d.pointOn exampleSpline ParameterValue.one
- --> Point3d.fromCoordinates ( 3, 3, 3 )
-
--}
+{-| -}
pointOn : CubicSpline3d -> ParameterValue -> Point3d
pointOn spline parameterValue =
let
@@ -438,45 +311,20 @@ pointOn spline parameterValue =
Point3d.interpolateFrom r1 r2 t
-{-| Get points along a spline at a given set of parameter values.
-
- exampleSpline
- |> CubicSpline3d.pointsAt
- (ParameterValue.steps 2)
- --> [ Point3d.fromCoordinates ( 1, 1, 1 )
- --> , Point3d.fromCoordinates ( 2.75, 2, 1.25 )
- --> , Point3d.fromCoordinates ( 3, 3, 3 )
- --> ]
-
--}
+{-| -}
pointsAt : List ParameterValue -> CubicSpline3d -> List Point3d
pointsAt parameterValues spline =
List.map (pointOn spline) parameterValues
-{-| If a curve has zero length (consists of just a single point), then we say
-that it is 'degenerate'. Some operations such as computing tangent directions
-are not defined on degenerate curves.
-
-A `Nondegenerate` value represents a spline that is definitely not degenerate.
-It is used as input to functions such as `CubicSpline3d.tangentDirection` and
-can be constructed using `CubicSpline3d.nondegenerate`.
-
--}
+{-| -}
type Nondegenerate
= NonZeroThirdDerivative CubicSpline3d Direction3d
| NonZeroSecondDerivative CubicSpline3d Direction3d
| NonZeroFirstDerivative CubicSpline3d Direction3d
-{-| Attempt to construct a nondegenerate spline from a general `CubicSpline3d`.
-If the spline is in fact degenerate (consists of a single point), returns an
-`Err` with that point.
-
- CubicSpline3d.nondegenerate exampleSpline
- --> Ok nondegenerateExampleSpline
-
--}
+{-| -}
nondegenerate : CubicSpline3d -> Result Point3d Nondegenerate
nondegenerate spline =
case Vector3d.direction (thirdDerivative spline) of
@@ -517,13 +365,7 @@ nondegenerate spline =
Err (startPoint spline)
-{-| Convert a nondegenerate spline back to a general `CubicSpline3d`.
-
- CubicSpline3d.fromNondegenerate
- nondegenerateExampleSpline
- --> exampleSpline
-
--}
+{-| -}
fromNondegenerate : Nondegenerate -> CubicSpline3d
fromNondegenerate nondegenerateSpline =
case nondegenerateSpline of
@@ -537,27 +379,7 @@ fromNondegenerate nondegenerateSpline =
spline
-{-| Get the tangent direction to a nondegenerate spline at a given parameter
-value:
-
- CubicSpline3d.tangentDirection
- nondegenerateExampleSpline
- ParameterValue.zero
- --> Direction3d.x
-
- CubicSpline3d.tangentDirection
- nondegenerateExampleSpline
- ParameterValue.half
- --> Direction3d.fromAzimuthAndElevation
- --> (degrees 63.43)
- --> (degrees 24.09)
-
- CubicSpline3d.tangentDirection
- nondegenerateExampleSpline
- ParameterValue.one
- --> Direction3d.z
-
--}
+{-| -}
tangentDirection : Nondegenerate -> ParameterValue -> Direction3d
tangentDirection nondegenerateSpline parameterValue =
case nondegenerateSpline of
@@ -625,37 +447,13 @@ tangentDirection nondegenerateSpline parameterValue =
thirdDerivativeDirection
-{-| Get tangent directions to a nondegenerate spline at a given set of parameter
-values:
-
- nondegenerateExampleSpline
- |> CubicSpline3d.tangentDirectionsAt
- (ParameterValue.steps 2)
- --> [ Direction3d.x
- --> , Direction3d.fromAzimuthAndElevation
- --> (degrees 63.43)
- --> (degrees 24.09)
- --> , Direction3d.z
- --> ]
-
--}
+{-| -}
tangentDirectionsAt : List ParameterValue -> Nondegenerate -> List Direction3d
tangentDirectionsAt parameterValues nondegenerateSpline =
List.map (tangentDirection nondegenerateSpline) parameterValues
-{-| Get both the point and tangent direction of a nondegenerate spline at a
-given parameter value:
-
- CubicSpline3d.sample nondegenerateExampleSpline
- ParameterValue.half
- --> ( Point3d.fromCoordinates ( 2.75, 2, 1.25 )
- --> , Direction3d.fromAzimuthAndElevation
- --> (degrees 63.43)
- --> (degrees 24.09)
- --> )
-
--}
+{-| -}
sample : Nondegenerate -> ParameterValue -> ( Point3d, Direction3d )
sample nondegenerateSpline parameterValue =
( pointOn (fromNondegenerate nondegenerateSpline) parameterValue
@@ -663,47 +461,13 @@ sample nondegenerateSpline parameterValue =
)
-{-| Get points and tangent directions of a nondegenerate spline at a given set
-of parameter values:
-
- nondegenerateExampleSpline
- |> CubicSpline3d.samplesAt
- (ParameterValue.steps 2)
- --> [ ( Point3d.fromCoordinates ( 1, 1, 1 )
- --> , Direction3d.x
- --> )
- --> , ( Point3d.fromCoordinates ( 2.75, 2, 1.25 )
- --> , Direction3d.fromAzimuthAndElevation
- --> (degrees 63.43)
- --> (degrees 24.09)
- --> )
- --> , ( Point3d.fromCoordinates ( 3, 3, 3 )
- --> , Direction3d.z
- --> )
- --> ]
-
--}
+{-| -}
samplesAt : List ParameterValue -> Nondegenerate -> List ( Point3d, Direction3d )
samplesAt parameterValues nondegenerateSpline =
List.map (sample nondegenerateSpline) parameterValues
-{-| Reverse a spline so that the start point becomes the end point, and vice
-versa.
-
- CubicSpline3d.reverse exampleSpline
- --> CubicSpline3d.with
- --> { startPoint =
- --> Point3d.fromCoordinates ( 3, 3, 3 )
- --> , startControlPoint =
- --> Point3d.fromCoordinates ( 3, 3, 1 )
- --> , endControlPoint =
- --> Point3d.fromCoordinates ( 3, 1, 1 )
- --> , endPoint =
- --> Point3d.fromCoordinates ( 1, 1, 1 )
- --> }
-
--}
+{-| -}
reverse : CubicSpline3d -> CubicSpline3d
reverse spline =
with
@@ -714,196 +478,55 @@ reverse spline =
}
-{-| Scale a spline about the given center point by the given scale.
-
- CubicSpline3d.scaleAbout Point3d.origin 2 exampleSpline
- --> CubicSpline3d.with
- --> { startPoint =
- --> Point3d.fromCoordinates ( 2, 2, 2 )
- --> , startControlPoint =
- --> Point3d.fromCoordinates ( 6, 2, 2 )
- --> , endControlPoint =
- --> Point3d.fromCoordinates ( 6, 6, 2 )
- --> , endPoint =
- --> Point3d.fromCoordinates ( 6, 6, 6 )
- --> }
-
--}
+{-| -}
scaleAbout : Point3d -> Float -> CubicSpline3d -> CubicSpline3d
scaleAbout point scale =
mapControlPoints (Point3d.scaleAbout point scale)
-{-| Rotate a spline counterclockwise around a given axis by a given angle (in
-radians).
-
- exampleSpline
- |> CubicSpline3d.rotateAround Axis3d.z (degrees 90)
- --> CubicSpline3d.with
- --> { startPoint =
- --> Point3d.fromCoordinates ( -1, 1, 1 )
- --> , startControlPoint =
- --> Point3d.fromCoordinates ( -1, 3, 1 )
- --> , endControlPoint =
- --> Point3d.fromCoordinates ( -3, 3, 1 )
- --> , endPoint =
- --> Point3d.fromCoordinates ( -3, 3, 3 )
- --> }
-
--}
+{-| -}
rotateAround : Axis3d -> Float -> CubicSpline3d -> CubicSpline3d
rotateAround axis angle =
mapControlPoints (Point3d.rotateAround axis angle)
-{-| Translate a spline by a given displacement.
-
- displacement =
- Vector3d.fromComponents ( 2, 3, 1 )
-
- CubicSpline3d.translateBy displacement exampleSpline
- --> CubicSpline3d.with
- --> { startPoint =
- --> Point3d.fromCoordinates ( 3, 4, 2 )
- --> , startControlPoint =
- --> Point3d.fromCoordinates ( 5, 4, 2 )
- --> , endControlPoint =
- --> Point3d.fromCoordinates ( 5, 6, 2 )
- --> , endPoint =
- --> Point3d.fromCoordinates ( 5, 6, 4 )
- --> }
-
--}
+{-| -}
translateBy : Vector3d -> CubicSpline3d -> CubicSpline3d
translateBy displacement =
mapControlPoints (Point3d.translateBy displacement)
-{-| Translate a spline in a given direction by a given distance;
-
- CubicSpline3d.translateIn direction distance
-
-is equivalent to
-
- CubicSpline3d.translateBy
- (Vector3d.withLength distance direction)
-
--}
+{-| -}
translateIn : Direction3d -> Float -> CubicSpline3d -> CubicSpline3d
translateIn direction distance spline =
translateBy (Vector3d.withLength distance direction) spline
-{-| Mirror a spline across a plane.
-
- CubicSpline3d.mirrorAcross Plane3d.xy exampleSpline
- --> CubicSpline3d.with
- --> { startPoint =
- --> Point3d.fromCoordinates ( 1, 1, -1 )
- --> , startControlPoint =
- --> Point3d.fromCoordinates ( 3, 1, -1 )
- --> , endControlPoint =
- --> Point3d.fromCoordinates ( 3, 3, -1 )
- --> , endPoint =
- --> Point3d.fromCoordinates ( 3, 3, -3 )
- --> }
-
--}
+{-| -}
mirrorAcross : Plane3d -> CubicSpline3d -> CubicSpline3d
mirrorAcross plane =
mapControlPoints (Point3d.mirrorAcross plane)
-{-| Find the [orthographic projection](https://en.wikipedia.org/wiki/Orthographic_projection)
-of a spline onto a plane.
-
- CubicSpline3d.projectOnto Plane3d.xy exampleSpline
- --> CubicSpline3d.with
- --> { startPoint =
- --> Point3d.fromCoordinates ( 1, 1, 0 )
- --> , startControlPoint =
- --> Point3d.fromCoordinates ( 3, 1, 0 )
- --> , endControlPoint =
- --> Point3d.fromCoordinates ( 3, 3, 0 )
- --> , endPoint =
- --> Point3d.fromCoordinates ( 3, 3, 0 )
- --> }
-
--}
+{-| -}
projectOnto : Plane3d -> CubicSpline3d -> CubicSpline3d
projectOnto plane =
mapControlPoints (Point3d.projectOnto plane)
-{-| Take a spline defined in global coordinates, and return it expressed in
-local coordinates relative to a given reference frame.
-
- localFrame =
- Frame3d.atPoint
- (Point3d.fromCoordinates ( 1, 2, 3 ))
-
- CubicSpline3d.relativeTo localFrame exampleSpline
- --> CubicSpline3d.with
- --> { startPoint =
- --> Point3d.fromCoordinates ( 0, -1, -2 )
- --> , startControlPoint =
- --> Point3d.fromCoordinates ( 2, -1, -2 )
- --> , endControlPoint =
- --> Point3d.fromCoordinates ( 2, 1, -2 )
- --> , endPoint =
- --> Point3d.fromCoordinates ( 2, 1, 0 )
- --> }
-
--}
+{-| -}
relativeTo : Frame3d -> CubicSpline3d -> CubicSpline3d
relativeTo frame =
mapControlPoints (Point3d.relativeTo frame)
-{-| Take a spline considered to be defined in local coordinates relative to a
-given reference frame, and return that spline expressed in global coordinates.
-
- localFrame =
- Frame3d.atPoint
- (Point3d.fromCoordinates ( 1, 2, 3 ))
-
- CubicSpline3d.placeIn localFrame exampleSpline
- --> CubicSpline3d.with
- --> { startPoint =
- --> Point3d.fromCoordinates ( 2, 3, 4 )
- --> , startControlPoint =
- --> Point3d.fromCoordinates ( 4, 3, 4 )
- --> , endControlPoint =
- --> Point3d.fromCoordinates ( 4, 5, 4 )
- --> , endPoint =
- --> Point3d.fromCoordinates ( 4, 5, 6 )
- --> }
-
--}
+{-| -}
placeIn : Frame3d -> CubicSpline3d -> CubicSpline3d
placeIn frame =
mapControlPoints (Point3d.placeIn frame)
-{-| Project a spline into a given sketch plane. Conceptually, this finds the
-[orthographic projection](https://en.wikipedia.org/wiki/Orthographic_projection)
-of the spline onto the plane and then expresses the projected spline in 2D
-sketch coordinates.
-
- exampleSpline
- |> CubicSpline3d.projectInto SketchPlane3d.yz
- --> CubicSpline2d.with
- --> { startPoint =
- --> Point2d.fromCoordinates ( 1, 1 )
- --> , startControlPoint =
- --> Point2d.fromCoordinates ( 1, 1 )
- --> , endControlPoint =
- --> Point2d.fromCoordinates ( 3, 1 )
- --> , endPoint =
- --> Point2d.fromCoordinates ( 3, 3 )
- --> }
-
--}
+{-| -}
projectInto : SketchPlane3d -> CubicSpline3d -> CubicSpline2d
projectInto sketchPlane spline =
CubicSpline2d.with
@@ -928,69 +551,13 @@ mapControlPoints function spline =
}
-{-| Split a spline into two roughly equal halves.
-
- CubicSpline3d.bisect exampleSpline
- --> ( CubicSpline3d.with
- --> { startPoint =
- --> Point3d.fromCoordinates ( 1, 1, 1 )
- --> , startControlPoint =
- --> Point3d.fromCoordinates ( 2, 1, 1 )
- --> , endControlPoint =
- --> Point3d.fromCoordinates ( 2.5, 1.5, 1 )
- --> , endPoint =
- --> Point3d.fromCoordinates ( 2.75, 2, 1.25 )
- --> }
- --> , CubicSpline3d.with
- --> { startPoint =
- --> Point3d.fromCoordinates ( 2.75, 2, 1.25 )
- --> , startControlPoint =
- --> Point3d.fromCoordinates ( 3, 2.5, 1.5 )
- --> , endControlPoint =
- --> Point3d.fromCoordinates ( 3, 3, 2 )
- --> , endPoint =
- --> Point3d.fromCoordinates ( 3, 3, 3 )
- --> }
- --> )
-
-Equivalent to `CubicSpline3d.splitAt ParameterValue.half`.
-
--}
+{-| -}
bisect : CubicSpline3d -> ( CubicSpline3d, CubicSpline3d )
bisect =
splitAt ParameterValue.half
-{-| Split a spline at a particular parameter value, resulting in two smaller
-splines.
-
- parameterValue =
- ParameterValue.clamped 0.75
-
- CubicSpline3d.splitAt parameterValue exampleSpline
- --> ( CubicSpline3d.with
- --> { startPoint =
- --> Point3d.fromCoordinates ( 1, 1, 1 )
- --> , startControlPoint =
- --> Point3d.fromCoordinates ( 2.5, 1, 1 )
- --> , endControlPoint =
- --> Point3d.fromCoordinates ( 2.88, 2.13, 1 )
- --> , endPoint =
- --> Point3d.fromCoordinates ( 2.97, 2.69, 1.84 )
- --> }
- --> , CubicSpline3d.with
- --> { startPoint =
- --> Point3d.fromCoordinates ( 2.97, 2.69, 1.84 )
- --> , startControlPoint =
- --> Point3d.fromCoordinates ( 3, 2.88, 2.13 )
- --> , endControlPoint =
- --> Point3d.fromCoordinates ( 3, 3, 2.5 )
- --> , endPoint =
- --> Point3d.fromCoordinates ( 3, 3, 3 )
- --> }
- --> )
-
--}
+{-| -}
splitAt : ParameterValue -> CubicSpline3d -> ( CubicSpline3d, CubicSpline3d )
splitAt parameterValue spline =
let
@@ -1042,8 +609,7 @@ splitAt parameterValue spline =
)
-{-| A spline that has been parameterized by arc length.
--}
+{-| -}
type ArcLengthParameterized
= ArcLengthParameterized
{ underlyingSpline : CubicSpline3d
@@ -1052,17 +618,7 @@ type ArcLengthParameterized
}
-{-| Build an arc length parameterization of the given spline, with a given
-accuracy. Generally speaking, all operations on the resulting
-`ArcLengthParameterized` value will be accurate to within the specified maximum
-error.
-
- parameterizedSpline =
- exampleSpline
- |> CubicSpline3d.arcLengthParameterized
- { maxError = 1.0e-4 }
-
--}
+{-| -}
arcLengthParameterized : { maxError : Float } -> CubicSpline3d -> ArcLengthParameterized
arcLengthParameterized { maxError } spline =
let
@@ -1081,43 +637,14 @@ arcLengthParameterized { maxError } spline =
}
-{-| Find the total arc length of a spline:
-
- arcLength =
- CubicSpline3d.arcLength parameterizedSpline
-
- arcLength
- --> 4.3303
-
-In this example, the result will be accurate to within `1.0e-4` since that was
-the tolerance used when constructing `parameterizedSpline`.
-
--}
+{-| -}
arcLength : ArcLengthParameterized -> Float
arcLength parameterizedSpline =
arcLengthParameterization parameterizedSpline
|> ArcLengthParameterization.totalArcLength
-{-| Try to get the point along a spline at a given arc length. For example, to
-get the point a quarter of the way along `exampleSpline`:
-
- CubicSpline3d.pointAlong parameterizedSpline
- (arcLength / 4)
- --> Just <|
- --> Point3d.fromCoordinates
- --> ( 2.0425, 1.2431, 1.0206 )
-
-Note that this is not the same as evaulating at a parameter value of 1/4:
-
- CubicSpline3d.pointOn exampleSpline
- (ParameterValue.clamped 0.25)
- --> Point3d.fromCoordinates ( 2.1563, 1.3125, 1.0313 )
-
-If the given arc length is less than zero or greater than the arc length of the
-spline, returns `Nothing`.
-
--}
+{-| -}
pointAlong : ArcLengthParameterized -> Float -> Maybe Point3d
pointAlong (ArcLengthParameterized parameterized) distance =
parameterized.parameterization
@@ -1125,21 +652,7 @@ pointAlong (ArcLengthParameterized parameterized) distance =
|> Maybe.map (pointOn parameterized.underlyingSpline)
-{-| Try to get the tangent direction along a spline at a given arc length. To
-get the tangent direction a quarter of the way along `exampleSpline`:
-
- CubicSpline3d.tangentDirectionAlong parameterizedSpline
- (0.25 * arcLength)
- --> Just
- --> (Direction3d.fromAzimuthAndElevation
- --> (degrees 29.1)
- --> (degrees 3.871)
- --> )
-
-If the given arc length is less than zero or greater than the arc length of the
-spline (or if the spline is degenerate), returns `Nothing`.
-
--}
+{-| -}
tangentDirectionAlong : ArcLengthParameterized -> Float -> Maybe Direction3d
tangentDirectionAlong (ArcLengthParameterized parameterized) distance =
case parameterized.nondegenerateSpline of
@@ -1152,24 +665,7 @@ tangentDirectionAlong (ArcLengthParameterized parameterized) distance =
Nothing
-{-| Try to get the point and tangent direction along a spline at a given arc
-length. To get the point and tangent direction a quarter of the way along
-`exampleSpline`:
-
- CubicSpline3d.sampleAlong parameterizedSpline
- (0.25 * arcLength)
- --> Just
- --> ( Point3d.fromCoordinates
- --> ( 2.0425, 1.2431, 1.0206 )
- --> , Direction3d.fromAzimuthAndElevation
- --> (degrees 29.1)
- --> (degrees 3.871)
- --> )
-
-If the given arc length is less than zero or greater than the arc length of the
-spline (or if the spline is degenerate), returns `Nothing`.
-
--}
+{-| -}
sampleAlong : ArcLengthParameterized -> Float -> Maybe ( Point3d, Direction3d )
sampleAlong (ArcLengthParameterized parameterized) distance =
case parameterized.nondegenerateSpline of
@@ -1194,21 +690,7 @@ fromArcLengthParameterized (ArcLengthParameterized parameterized) =
parameterized.underlyingSpline
-{-| Get the first derivative of a spline at a given parameter value.
-
- CubicSpline3d.derivative exampleSpline
- ParameterValue.zero
- --> Vector3d.fromComponents ( 6, 0, 0 )
-
- CubicSpline3d.derivative exampleSpline
- ParameterValue.half
- --> Vector3d.fromComponents ( 1.5, 3, 1.5 )
-
- CubicSpline3d.derivative exampleSpline
- ParameterValue.one
- --> Vector3d.fromComponents ( 0, 0, 6 )
-
--}
+{-| -}
firstDerivative : CubicSpline3d -> ParameterValue -> Vector3d
firstDerivative spline parameterValue =
let
@@ -1321,39 +803,13 @@ firstDerivative spline parameterValue =
)
-{-| Evaluate the first derivative of a spline at a range of parameter values.
-
- exampleSpline
- |> CubicSpline3d.firstDerivativesAt
- (ParameterValue.steps 2)
- --> [ Vector3d.fromComponents ( 6, 0, 0 )
- --> , Vector3d.fromComponents ( 1.5, 3, 1.5 )
- --> , Vector3d.fromComponents ( 0, 0, 6 )
- --> ]
-
--}
+{-| -}
firstDerivativesAt : List ParameterValue -> CubicSpline3d -> List Vector3d
firstDerivativesAt parameterValues spline =
List.map (firstDerivative spline) parameterValues
-{-| Get the second derivative value at a point along a spline, based on a
-parameter that ranges from 0 to 1. A parameter value of 0 corresponds to the
-start of the spline and a value of 1 corresponds to the end.
-
- CubicSpline3d.secondDerivative exampleSpline
- ParameterValue.zero
- --> Vector3d.fromComponents ( -12, 12, 0 )
-
- CubicSpline3d.secondDerivative exampleSpline
- ParameterValue.half
- --> Vector3d.fromComponents ( -6, 0, 6 )
-
- CubicSpline3d.secondDerivative exampleSpline
- ParameterValue.one
- --> Vector3d.fromComponents ( 0, -12, 12 )
-
--}
+{-| -}
secondDerivative : CubicSpline3d -> ParameterValue -> Vector3d
secondDerivative spline parameterValue =
let
@@ -1390,25 +846,13 @@ secondDerivative spline parameterValue =
Vector3d.scaleBy 6 (Vector3d.interpolateFrom v1 v2 t)
-{-| Evaluate the second derivative of a spline at a range of parameter values.
-
- exampleSpline
- |> CubicSpline3d.secondDerivativesAt
- (ParameterValue.steps 2)
- --> [ Vector3d.fromComponents ( -12, 12, 0 )
- --> , Vector3d.fromComponents ( -6, 0, 6 )
- --> , Vector3d.fromComponents ( 0, -12, 12 )
- --> ]
-
--}
+{-| -}
secondDerivativesAt : List ParameterValue -> CubicSpline3d -> List Vector3d
secondDerivativesAt parameterValues spline =
List.map (secondDerivative spline) parameterValues
-{-| Get the third derivative of a spline (for a cubic spline, this is a
-constant).
--}
+{-| -}
thirdDerivative : CubicSpline3d -> Vector3d
thirdDerivative spline =
let
@@ -1442,10 +886,7 @@ thirdDerivative spline =
Vector3d.scaleBy 6 (Vector3d.difference v2 v1)
-{-| Find a conservative upper bound on the magnitude of the second derivative of
-a spline. This can be useful when determining error bounds for various kinds of
-linear approximations.
--}
+{-| -}
maxSecondDerivativeMagnitude : CubicSpline3d -> Float
maxSecondDerivativeMagnitude spline =
let
diff --git a/src/Curve/ArcLengthParameterization.elm b/src/Curve/ArcLengthParameterization.elm
index b94033ff..6bdf64bf 100644
--- a/src/Curve/ArcLengthParameterization.elm
+++ b/src/Curve/ArcLengthParameterization.elm
@@ -33,8 +33,7 @@ import Curve.ParameterValue as ParameterValue exposing (ParameterValue)
import Float.Extra as Float
-{-| Contains a mapping from curve parameter value to arc length, and vice versa.
--}
+{-| -}
type ArcLengthParameterization
= ArcLengthParameterization SegmentTree
@@ -74,14 +73,7 @@ segmentsPerLeaf =
8
-{-| Build an arc length parameterization for some curve. You must supply:
-
- - A `derivativeMagnitude` function that returns the magnitude of the first
- derivative of the curve at a given parameter value
- - The maximum magnitude of the second derivative of the curve
- - A tolerance specifying the maximum error of the resulting parameterization
-
--}
+{-| -}
build : { maxError : Float, derivativeMagnitude : ParameterValue -> Float, maxSecondDerivativeMagnitude : Float } -> ArcLengthParameterization
build { maxError, derivativeMagnitude, maxSecondDerivativeMagnitude } =
let
@@ -247,10 +239,7 @@ buildTree derivativeMagnitude lengthAtStart_ paramAtStart_ paramAtEnd height =
}
-{-| Convert an arc length to the corresponding parameter value. If the given
-arc length is less than zero or greater than the total arc length of the curve
-(as reported by `totalArcLength`), returns `Nothing`.
--}
+{-| -}
arcLengthToParameterValue : Float -> ArcLengthParameterization -> Maybe ParameterValue
arcLengthToParameterValue s (ArcLengthParameterization tree) =
if s == 0 then
@@ -352,28 +341,13 @@ lengthAtEnd tree =
leaf.length8
-{-| Find the total arc length of some curve given its arc length
-parameterization;
-
- ArcLengthParameterization.totalArcLength
- parameterization
-
-is equivalent to
-
- ArcLengthParameterization.parameterValueToArcLength
- ParameterValue.one
- parameterization
-
-but is more efficient.
-
--}
+{-| -}
totalArcLength : ArcLengthParameterization -> Float
totalArcLength (ArcLengthParameterization tree) =
lengthAtEnd tree
-{-| Convert a parameter value to the corresponding arc length.
--}
+{-| -}
parameterValueToArcLength : ParameterValue -> ArcLengthParameterization -> Float
parameterValueToArcLength parameterValue (ArcLengthParameterization tree) =
if parameterValue == ParameterValue.zero then
diff --git a/src/Curve/ParameterValue.elm b/src/Curve/ParameterValue.elm
index df5983bd..6267b24e 100644
--- a/src/Curve/ParameterValue.elm
+++ b/src/Curve/ParameterValue.elm
@@ -50,61 +50,30 @@ functionality for:
-}
-{-| A parameter value between 0 and 1. Curve types such as [`Arc2d`](Arc2d) and
-[`CubicSpline3d`](CubicSpline3d) use `ParameterValue` arguments for curve
-evaluation functions such as [`Arc2d.pointOn`](Arc2d#pointOn) and
-[`CubicSpline3d.samplesAt`](CubicSpline3d#samplesAt).
--}
+{-| -}
type ParameterValue
= ParameterValue Float
-{-| The parameter value 0.
-
- ParameterValue.value ParameterValue.zero
- --> 0
-
--}
+{-| -}
zero : ParameterValue
zero =
ParameterValue 0
-{-| The parameter value 0.5.
-
- ParameterValue.value ParameterValue.half
- --> 0.5
-
--}
+{-| -}
half : ParameterValue
half =
ParameterValue 0.5
-{-| The parameter value 1.
-
- ParameterValue.value ParameterValue.one
- --> 1
-
--}
+{-| -}
one : ParameterValue
one =
ParameterValue 1
-{-| Construct a valid parameter value by clamping a plain `Float` value to
-between 0 and 1.
-
- ParameterValue.value (ParameterValue.clamped 0.75)
- --> 0.75
-
- ParameterValue.value (ParameterValue.clamped -0.25)
- --> 0
-
- ParameterValue.value (ParameterValue.clamped 1.25)
- --> 1
-
--}
+{-| -}
clamped : Float -> ParameterValue
clamped givenValue =
if isNaN givenValue then
@@ -113,20 +82,7 @@ clamped givenValue =
ParameterValue (clamp 0 1 givenValue)
-{-| If the given value is between 0 and 1, return `Just` that value as a
-`ParameterValue`. Otherwise, return `Nothing`.
-
- ParameterValue.checked 0.75
- |> Maybe.map ParameterValue.value
- --> Just 0.75
-
- ParameterValue.checked -0.25
- --> Nothing
-
- ParameterValue.checked 1.25
- --> Nothing
-
--}
+{-| -}
checked : Float -> Maybe ParameterValue
checked givenValue =
if isNaN givenValue then
@@ -137,73 +93,25 @@ checked givenValue =
Nothing
-{-| Directly construct a `ParameterValue` from a `Float` without checking
-whether it is valid. `ParameterValue.clamped` should generally be used instead,
-unless you are **very** sure you know what you are doing and
-profiling/benchmarking shows that `ParameterValue.clamped` is a performance
-bottleneck.
--}
+{-| -}
unsafe : Float -> ParameterValue
unsafe =
ParameterValue
-{-| Find the midpoint between two parameter values.
-
- ParameterValue.midpoint
- ParameterValue.zero
- ParameterValue.one
- --> ParameterValue.half
-
--}
+{-| -}
midpoint : ParameterValue -> ParameterValue -> ParameterValue
midpoint (ParameterValue firstValue) (ParameterValue secondValue) =
ParameterValue (firstValue + (secondValue - firstValue) / 2)
-{-| Subtract a parameter value from 1 to give a new parameter value.
-
- ParameterValue.oneMinus ParameterValue.one
- --> ParameterValue.zero
-
- ParameterValue.oneMinus ParameterValue.zero
- --> ParameterValue.one
-
- ParameterValue.oneMinus ParameterValue.half
- --> ParameterValue.half
-
-This can be thought of as the 'negation' or 'complement' of a parameter value.
-For example, evaluating a reversed curve at a parameter value `t` is generally
-equivalent to evaluating the original curve at a parameter value
-1 - t
, and vice versa.
-
--}
+{-| -}
oneMinus : ParameterValue -> ParameterValue
oneMinus (ParameterValue value_) =
ParameterValue (1 - value_)
-{-| Construct a list of parameter values by taking a given number of steps from
-0 to 1. Note that the number of returned values will in general be one greater
-than the number of steps!
-
- ParameterValue.steps 0
- --> []
-
- ParameterValue.steps 1
- --> [ ParameterValue.zero, ParameterValue.one ]
-
- Parametervalue.steps 2
- --> [ ParameterValue.zero
- --> , ParameterValue.half
- --> , ParameterValue.one
- --> ]
-
- ParameterValue.steps 5
- |> List.map ParameterValue.value
- --> [ 0, 0.2, 0.4, 0.6, 0.8, 1 ]
-
--}
+{-| -}
steps : Int -> List ParameterValue
steps n =
if n < 1 then
@@ -212,24 +120,7 @@ steps n =
endpointsHelp 0 n (toFloat n) []
-{-| Construct a list of parameter values by dividing the range [0,1] into a
-given number of steps and then returning the value at the beginning of each
-step.
-
- ParameterValue.leading 0
- --> []
-
- ParameterValue.leading 1
- --> [ ParameterValue.zero ]
-
- Parametervalue.leading 2
- --> [ ParameterValue.zero, ParameterValue.half ]
-
- ParameterValue.leading 5
- |> List.map ParameterValue.value
- --> [ 0, 0.2, 0.4, 0.6, 0.8 ]
-
--}
+{-| -}
leading : Int -> List ParameterValue
leading n =
if n < 1 then
@@ -238,23 +129,7 @@ leading n =
endpointsHelp 0 (n - 1) (toFloat n) []
-{-| Construct a list of parameter values by dividing the range [0,1] into a
-given number of steps and then returning the value at the end of each step.
-
- ParameterValue.trailing 0
- --> []
-
- ParameterValue.trailing 1
- --> [ ParameterValue.one ]
-
- Parametervalue.trailing 2
- --> [ ParameterValue.half, ParameterValue.one ]
-
- ParameterValue.trailing 5
- |> List.map ParameterValue.value
- --> [ 0.2, 0.4, 0.6, 0.8, 1 ]
-
--}
+{-| -}
trailing : Int -> List ParameterValue
trailing n =
if n < 1 then
@@ -278,24 +153,7 @@ endpointsHelp startIndex index divisor accumulated =
endpointsHelp startIndex (index - 1) divisor newAccumulated
-{-| Construct a list of parameter values by dividing the range [0,1] into a
-given number of steps and then returning the value at the midpoint of each step.
-
- ParameterValue.midpoints 0
- --> []
-
- ParameterValue.midpoints 1
- --> [ ParameterValue.half ]
-
- ParameterValue.midpoints 2
- |> List.map ParameterValue.value
- --> [ 0.25, 0.75 ]
-
- ParameterValue.midpoints 5
- |> List.map ParameterValue.value
- --> [ 0.1, 0.3, 0.5, 0.7, 0.9 ]
-
--}
+{-| -}
midpoints : Int -> List ParameterValue
midpoints n =
if n < 1 then
@@ -319,38 +177,7 @@ midpointsHelp index divisor accumulated =
midpointsHelp (index - 2) divisor newAccumulated
-{-| Construct a list of evenly-spaced parameter values between 0 and 1 by
-specifying:
-
- - the number of steps to take from 0 to 1
- - whether to include the start value (0)
- - whether to include the end value (1)
-
-This is a more general form of `steps`, `leading` and `trailing`; for example,
-
- ParameterValue.steps 10
-
-is equivalent to
-
- ParameterValue.range
- { numSteps = 10
- , includeStart = True
- , includeEnd = True
- }
-
-and
-
- ParameterValue.trailing 10
-
-is equivalent to
-
- ParameterValue.range
- { numSteps = 10
- , includeStart = False
- , includeEnd = True
- }
-
--}
+{-| -}
range : { numSteps : Int, includeStart : Bool, includeEnd : Bool } -> List ParameterValue
range { numSteps, includeStart, includeEnd } =
if numSteps < 1 then
@@ -375,12 +202,7 @@ range { numSteps, includeStart, includeEnd } =
[]
-{-| Convert a `ParameterValue` to a plain `Float` value between 0 and 1.
-
- ParameterValue.value ParameterValue.half
- --> 0.5
-
--}
+{-| -}
value : ParameterValue -> Float
value (ParameterValue value_) =
value_
diff --git a/src/Direction2d.elm b/src/Direction2d.elm
index b9fa31a9..30ff3842 100644
--- a/src/Direction2d.elm
+++ b/src/Direction2d.elm
@@ -101,22 +101,9 @@ several uses, such as:
# Coordinate conversions
-Functions 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 the positions of their origin points.
-
-For the examples, assume the following frames have been defined:
-
- upsideDownFrame =
- Frame2d
- { originPoint = Point2d.origin
- , xDirection = Direction2d.positiveX
- , yDirection = Direction2d.negativeY
- }
-
- rotatedFrame =
- Frame2d.rotateBy (degrees 30) Frame2d.xy
+Like other transformations, coordinate transformations of directions depend only
+on the orientations of the relevant frames, not the positions of their origin
+points.
@docs relativeTo, placeIn
@@ -137,149 +124,61 @@ type alias Direction2d =
Types.Direction2d
-{-| Synonym for `Direction2d.positiveX`.
--}
+{-| -}
x : Direction2d
x =
unsafe ( 1, 0 )
-{-| Synonym for `Direction2d.positiveY`.
--}
+{-| -}
y : Direction2d
y =
unsafe ( 0, 1 )
-{-| The positive X direction.
-
- Direction2d.components Direction2d.positiveX
- --> ( 1, 0 )
-
--}
+{-| -}
positiveX : Direction2d
positiveX =
unsafe ( 1, 0 )
-{-| The negative X direction.
-
- Direction2d.components Direction2d.negativeX
- --> ( -1, 0 )
-
--}
+{-| -}
negativeX : Direction2d
negativeX =
unsafe ( -1, 0 )
-{-| The positive Y direction.
-
- Direction2d.components Direction2d.positiveY
- --> ( 0, 1 )
-
--}
+{-| -}
positiveY : Direction2d
positiveY =
unsafe ( 0, 1 )
-{-| The negative Y direction.
-
- Direction2d.components Direction2d.negativeY
- --> ( 0, -1 )
-
--}
+{-| -}
negativeY : Direction2d
negativeY =
unsafe ( 0, -1 )
-{-| Construct a direction directly from its X and Y components. Note that **you
-must ensure that the sum of the squares of the given components is exactly
-one**:
-
- Direction2d.unsafe ( 1, 0 )
- Direction2d.unsafe ( 0, -1 )
- Direction2d.unsafe ( 0.6, 0.8 )
-
-are all valid but
-
- Direction2d.unsafe ( 2, 0 )
- Direction2d.unsafe ( 1, 1 )
-
-are not. Instead of using `Direction2d.unsafe`, it may be easier to use
-constructors like `Direction2d.fromAngle` (which will always result in a valid
-direction) or start with existing directions and transform them as necessary.
-
--}
+{-| -}
unsafe : ( Float, Float ) -> Direction2d
unsafe =
Types.Direction2d
-{-| Attempt to construct the direction from the first given point to the second.
-If the two points are coincident, returns `Nothing`.
-
- point =
- Point2d.fromCoordinates ( 1, 1 )
-
- Direction2d.from Point2d.origin point
- --> Just (Direction2d.fromAngle (degrees 45))
-
- Direction2d.from point Point2d.origin
- --> Just (Direction2d.fromAngle (degrees -135))
-
- Direction2d.from point point
- --> Nothing
-
--}
+{-| -}
from : Point2d -> Point2d -> Maybe Direction2d
from firstPoint secondPoint =
Vector2d.direction (Vector2d.from firstPoint secondPoint)
-{-| Construct a direction perpendicular to the given direction, by rotating the
-given direction 90 degrees counterclockwise. Synonym for
-`rotateCounterclockwise`.
-
- Direction2d.perpendicularTo Direction2d.x
- --> Direction2d.y
-
- Direction2d.perpendicularTo Direction2d.y
- --> Direction2d.negativeX
-
--}
+{-| -}
perpendicularTo : Direction2d -> Direction2d
perpendicularTo =
Bootstrap.perpendicularTo
-{-| Attempt to form a pair of perpendicular directions from the two given
-vectors by performing [Gram-Schmidt normalization](https://en.wikipedia.org/wiki/Gram%E2%80%93Schmidt_process):
-
- - The first returned direction will be equal to the direction of the first
- given vector
- - The second returned direction will be as close as possible to the second
- given vector while being perpendicular to the first returned direction
-
-If either of the given vectors are zero, or if the two vectors are parallel,
-returns `Nothing`.
-
- Direction2d.orthonormalize
- (Vector2d.fromComponents ( 3, 3 ))
- (Vector2d.fromComponents ( 0, -2 ))
- --> Just
- --> ( Direction2d.fromAngle (degrees 45)
- --> , Direction2d.fromAngle (degrees -45)
- --> )
-
- Direction2d.orthonormalize
- (Vector2d.fromComponents ( 3, 3 ))
- (Vector2d.fromComponents ( -2, -2 ))
- --> Nothing
-
--}
+{-| -}
orthonormalize : Vector2d -> Vector2d -> Maybe ( Direction2d, Direction2d )
orthonormalize xVector xyVector =
Vector2d.direction xVector
@@ -301,54 +200,19 @@ orthonormalize xVector xyVector =
)
-{-| Attempt to form a pair of perpendicular directions from the two given
-directions;
-
- Direction2d.orthogonalize xDirection yDirection
-
-is equivalent to
-
- Direction2d.orthonormalize
- (Direction2d.toVector xDirection)
- (Direction2d.toVector yDirection)
-
--}
+{-| -}
orthogonalize : Direction2d -> Direction2d -> Maybe ( Direction2d, Direction2d )
orthogonalize xDirection yDirection =
orthonormalize (toVector xDirection) (toVector yDirection)
-{-| Construct a direction from an angle in radians, given counterclockwise from
-the positive X direction.
-
- Direction2d.fromAngle 0
- --> Direction2d.x
-
- Direction2d.fromAngle (degrees 90)
- --> Direction2d.y
-
- Direction2d.fromAngle (degrees -90)
- --> Direction2d.negativeY
-
--}
+{-| -}
fromAngle : Float -> Direction2d
fromAngle angle =
unsafe ( cos angle, sin angle )
-{-| Convert a direction to a polar angle (the counterclockwise angle in radians
-from the positive X direction). The result will be in the range -π to π.
-
- Direction2d.toAngle Direction2d.x
- --> 0
-
- Direction2d.toAngle Direction2d.y
- --> degrees 90
-
- Direction2d.toAngle Direction2d.negativeY
- --> degrees -90
-
--}
+{-| -}
toAngle : Direction2d -> Float
toAngle direction =
let
@@ -358,19 +222,7 @@ toAngle direction =
atan2 yComponent_ xComponent_
-{-| Find the counterclockwise angle in radians from the first direction to the
-second. The result will be in the range -π to π.
-
- referenceDirection =
- Direction2d.fromAngle (degrees 30)
-
- Direction2d.angleFrom referenceDirection Direction2d.y
- --> degrees 60
-
- Direction2d.angleFrom referenceDirection Direction2d.x
- --> degrees -30
-
--}
+{-| -}
angleFrom : Direction2d -> Direction2d -> Float
angleFrom firstDirection secondDirection =
let
@@ -384,134 +236,49 @@ angleFrom firstDirection secondDirection =
(Vector2d.dotProduct firstVector secondVector)
-{-| 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 ) =
- Direction2d.components direction
-
--}
+{-| -}
components : Direction2d -> ( Float, Float )
components =
Bootstrap.components
-{-| Get the X component of a direction.
-
- Direction2d.xComponent Direction2d.x
- --> 1
-
- Direction2d.xComponent Direction2d.y
- --> 0
-
--}
+{-| -}
xComponent : Direction2d -> Float
xComponent (Types.Direction2d ( xComponent_, _ )) =
xComponent_
-{-| Get the Y component of a direction.
-
- Direction2d.yComponent Direction2d.x
- --> 0
-
- Direction2d.yComponent Direction2d.y
- --> 1
-
--}
+{-| -}
yComponent : Direction2d -> Float
yComponent (Types.Direction2d ( _, yComponent_ )) =
yComponent_
-{-| Find 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 =
- Direction2d.fromAngle (degrees 60)
-
- Direction2d.componentIn Direction2d.x direction
- --> 0.5
-
- Direction2d.componentIn direction direction
- --> 1
-
- Direction2d.componentIn Direction2d.x Direction2d.y
- --> 0
-
-This is more general and flexible than using `xComponent` or `yComponent`, both
-of which can be expressed in terms of `componentIn`; for example,
-
- Direction2d.xComponent direction
-
-is equivalent to
-
- Direction2d.componentIn Direction2d.x direction
-
--}
+{-| -}
componentIn : Direction2d -> Direction2d -> Float
componentIn firstDirection secondDirection =
Vector2d.componentIn firstDirection (toVector secondDirection)
-{-| Compare two directions within an angular tolerance. Returns true if the
-absolute value of the angle between the two given directions is less than the
-given tolerance.
-
- firstDirection =
- Direction2d.fromAngle (degrees 45)
-
- secondDirection =
- Direction2d.fromAngle (degrees 47)
-
- Direction2d.equalWithin (degrees 5)
- firstDirection
- secondDirection
- --> True
-
- Direction2d.equalWithin (degrees 1)
- firstDirection
- secondDirection
- --> False
-
--}
+{-| -}
equalWithin : Float -> Direction2d -> Direction2d -> Bool
equalWithin angle firstDirection secondDirection =
abs (angleFrom firstDirection secondDirection) <= angle
-{-| Convert a direction to a unit vector.
-
- Direction2d.toVector Direction2d.x
- --> Vector2d.fromComponents ( 1, 0 )
-
--}
+{-| -}
toVector : Direction2d -> Vector2d
toVector direction =
Vector2d.fromComponents (components direction)
-{-| Reverse a direction.
-
- Direction2d.reverse Direction2d.y
- --> Direction2d.negativeY
-
--}
+{-| -}
reverse : Direction2d -> Direction2d
reverse =
Bootstrap.reverse
-{-| Rotate a direction by 90 degrees clockwise.
-
- Direction2d.rotateClockwise Direction2d.y
- --> Direction2d.x
-
- Direction2d.rotateClockwise Direction2d.x
- --> Direction2d.negativeY
-
--}
+{-| -}
rotateClockwise : Direction2d -> Direction2d
rotateClockwise direction =
let
@@ -521,15 +288,7 @@ rotateClockwise direction =
unsafe ( yComponent_, -xComponent_ )
-{-| Rotate a direction by 90 degrees counterclockwise.
-
- Direction2d.rotateClockwise Direction2d.x
- --> Direction2d.y
-
- Direction2d.rotateClockwise Direction2d.y
- --> Direction2d.negativeX
-
--}
+{-| -}
rotateCounterclockwise : Direction2d -> Direction2d
rotateCounterclockwise direction =
let
@@ -539,71 +298,25 @@ rotateCounterclockwise direction =
unsafe ( -yComponent_, xComponent_ )
-{-| Rotate a direction counterclockwise by a given angle (in radians).
-
- Direction2d.rotateBy pi Direction2d.x
- --> Direction2d.negativeX
-
- Direction2d.rotateBy (degrees 45) Direction2d.y
- --> Direction2d.fromAngle (degrees 135)
-
--}
+{-| -}
rotateBy : Float -> Direction2d -> Direction2d
rotateBy angle direction =
toVector direction |> Vector2d.rotateBy angle |> toDirection
-{-| Mirror a direction across a particular axis. Note that only the direction of
-the axis affects the result, since directions are position-independent.
-
- slopedAxis =
- Axis2d.through
- (Point2d.fromCoordinates ( 100, 200 ))
- (Direction2d.fromAngle (degrees 45))
-
- Direction2d.mirrorAcross slopedAxis Direction2d.x
- --> Direction2d.y
-
- Direction2d.mirrorAcross slopedAxis Direction2d.y
- --> Direction2d.x
-
--}
+{-| -}
mirrorAcross : Axis2d -> Direction2d -> Direction2d
mirrorAcross axis direction =
toVector direction |> Vector2d.mirrorAcross axis |> toDirection
-{-| Take a direction defined in global coordinates, and return it expressed in
-local coordinates relative to a given reference frame.
-
- Direction2d.relativeTo upsideDownFrame Direction2d.y
- --> Direction2d.negativeY
-
- Direction2d.relativeTo rotatedFrame Direction2d.x
- --> Direction2d.fromAngle (degrees -30)
-
- Direction2d.relativeTo rotatedFrame Direction2d.y
- --> Direction2d.fromAngle (degrees 60)
-
--}
+{-| -}
relativeTo : Frame2d -> Direction2d -> Direction2d
relativeTo frame direction =
toVector direction |> Vector2d.relativeTo frame |> toDirection
-{-| Take a direction defined in local coordinates relative to a given reference
-frame, and return that direction expressed in global coordinates.
-
- Direction2d.placeIn upsideDownFrame Direction2d.y
- --> Direction2d.negativeY
-
- Direction2d.placeIn rotatedFrame Direction2d.x
- --> Direction2d.fromAngle (degrees 30)
-
- Direction2d.placeIn rotatedFrame Direction2d.y
- --> Direction2d.fromAngle (degrees 120)
-
--}
+{-| -}
placeIn : Frame2d -> Direction2d -> Direction2d
placeIn frame direction =
toVector direction |> Vector2d.placeIn frame |> toDirection
diff --git a/src/Direction3d.elm b/src/Direction3d.elm
index 8fd29867..6e956772 100644
--- a/src/Direction3d.elm
+++ b/src/Direction3d.elm
@@ -103,18 +103,8 @@ several uses, such as:
# Coordinate conversions
-Functions 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.xyz
- |> Frame3d.rotateAround Axis3d.z (degrees 30)
+Like other transformations, coordinate transformations of directions depend only
+on the orientations of the relevant frames, not their positions.
@docs relativeTo, placeIn, projectInto
@@ -137,135 +127,67 @@ type alias Direction3d =
Types.Direction3d
-{-| Synonym for `Direction3d.positiveX`.
--}
+{-| -}
x : Direction3d
x =
unsafe ( 1, 0, 0 )
-{-| Synonym for `Direction3d.positiveY`.
--}
+{-| -}
y : Direction3d
y =
unsafe ( 0, 1, 0 )
-{-| Synonym for `Direction3d.positiveZ`.
--}
+{-| -}
z : Direction3d
z =
unsafe ( 0, 0, 1 )
-{-| The positive X direction.
-
- Direction3d.components Direction3d.positiveX
- --> ( 1, 0, 0 )
-
--}
+{-| -}
positiveX : Direction3d
positiveX =
unsafe ( 1, 0, 0 )
-{-| The negative X direction.
-
- Direction3d.components Direction3d.negativeX
- --> ( -1, 0, 0 )
-
--}
+{-| -}
negativeX : Direction3d
negativeX =
unsafe ( -1, 0, 0 )
-{-| The positive Y direction.
-
- Direction3d.components Direction3d.positiveY
- --> ( 0, 1, 0 )
-
--}
+{-| -}
positiveY : Direction3d
positiveY =
unsafe ( 0, 1, 0 )
-{-| The negative Y direction.
-
- Direction3d.components Direction3d.negativeY
- --> ( 0, -1, 0 )
-
--}
+{-| -}
negativeY : Direction3d
negativeY =
unsafe ( 0, -1, 0 )
-{-| The positive Z direction.
-
- Direction3d.components Direction3d.positiveZ
- --> ( 0, 0, 1 )
-
--}
+{-| -}
positiveZ : Direction3d
positiveZ =
unsafe ( 0, 0, 1 )
-{-| The negative Z direction.
-
- Direction3d.components Direction3d.negativeZ
- --> ( 0, 0, -1 )
-
--}
+{-| -}
negativeZ : Direction3d
negativeZ =
unsafe ( 0, 0, -1 )
-{-| Construct 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 ( 1, 0, 0 )
- Direction3d.unsafe ( 0, -1, 0 )
- Direction3d.unsafe ( 0.6, 0, 0.8 )
-
-are all valid but
-
- Direction3d.unsafe ( 2, 0, 0 )
- Direction3d.unsafe ( 1, 1, 1 )
-
-are not. Instead of using `Direction3d.unsafe`, it may be easier to use
-constructors like `Direction3d.on` or `Direction3d.fromAzimuthAndElevation`
-(which will always result in a valid direction), or start with existing
-directions and transform them as necessary.
-
--}
+{-| -}
unsafe : ( Float, Float, Float ) -> Direction3d
unsafe =
Types.Direction3d
-{-| Construct a 3D direction lying _on_ a sketch plane by providing a 2D
-direction specified in XY coordinates _within_ the sketch plane.
-
- horizontalDirection =
- Direction3d.on SketchPlane3d.xy <|
- Direction2d.fromAngle (degrees 45)
-
- Direction3d.components horizontalDirection
- --> ( 0.7071, 0.7071, 0 )
-
- thirtyDegreesFromZ =
- Direction3d.on SketchPlane3d.zx <|
- Direction2d.fromAngle (degrees 30)
-
- Direction3d.components thirtyDegreesFromZ
- --> ( 0.5, 0, 0.866 )
-
--}
+{-| -}
on : SketchPlane3d -> Direction2d -> Direction3d
on sketchPlane direction2d =
let
@@ -285,19 +207,7 @@ on sketchPlane direction2d =
)
-{-| Construct a direction using azimuthal and elevation angles relative to the
-global XYZ frame. The azimuth defines the direction's polar angle on the global
-XY plane (from X towards Y) and the elevation defines its angle out of the XY
-plane towards positive Z.
-
- Direction3d.components
- (Direction3d.fromAzimuthAndElevation
- (degrees 45)
- (degrees 45)
- )
- --> ( 0.5, 0.5, 0.7071 )
-
--}
+{-| -}
fromAzimuthAndElevation : Float -> Float -> Direction3d
fromAzimuthAndElevation azimuth_ elevation_ =
let
@@ -311,56 +221,13 @@ fromAzimuthAndElevation azimuth_ elevation_ =
)
-{-| Attempt to construct the direction from the first given point to the second.
-If the two points are coincident, returns `Nothing`.
-
- point =
- Point3d.fromCoordinates ( 1, 0, 1 )
-
- Direction3d.from Point3d.origin point
- --> Just
- --> (Direction3d.fromAzimuthAndElevation
- --> (degrees 0)
- --> (degrees 45)
- --> )
-
- Direction3d.from point Point3d.origin
- --> Just
- --> (Direction3d.fromAzimuthAndElevation
- --> (degrees 180)
- --> (degrees -45)
- --> )
-
- Direction3d.from point point
- --> Nothing
-
--}
+{-| -}
from : Point3d -> Point3d -> Maybe Direction3d
from firstPoint secondPoint =
Vector3d.direction (Vector3d.from firstPoint secondPoint)
-{-| 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.negativeZ
-
- Direction3d.perpendicularTo Direction3d.y
- --> Direction3d.positiveZ
-
- direction =
- Direction3d.fromAzimuthAndElevation
- (degrees 0)
- (degrees 60)
-
- Direction3d.perpendicularTo direction
- --> Direction3d.fromAzimuthAndElevation
- --> (degrees 0)
- --> (degrees -30)
-
--}
+{-| -}
perpendicularTo : Direction3d -> Direction3d
perpendicularTo direction =
let
@@ -376,27 +243,7 @@ perpendicularTo direction =
toDirection normalizedVector
-{-| 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](https://en.wikipedia.org/wiki/Cartesian_coordinate_system#Orientation_and_handedness)
-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
- --> )
-
--}
+{-| -}
perpendicularBasis : Direction3d -> ( Direction3d, Direction3d )
perpendicularBasis direction =
let
@@ -410,41 +257,7 @@ perpendicularBasis direction =
( xDirection, yDirection )
-{-| Attempt to form a set of three mutually perpendicular directions from the
-three given vectors by performing [Gram-Schmidt normalization](https://en.wikipedia.org/wiki/Gram%E2%80%93Schmidt_process):
-
- - The first returned direction will be equal to the direction of the first
- given vector
- - The second returned direction will be as close as possible to the second
- given vector while being perpendicular to the first returned direction
- - The third returned direction will be as close as possible to the third given
- vector while being perpendicular to the first and second returned directions
-
-If any of the given vectors are zero, any two of them are parallel, or the three
-are coplanar, returns `Nothing`.
-
- Direction3d.orthonormalize
- (Vector3d.fromComponents ( 3, 3, 0 ))
- (Vector3d.fromComponents ( 0, 2, 0 ))
- (Vector3d.fromComponents ( 1, 2, 3 ))
- --> Just
- --> ( Direction3d.fromAzimuthAndElevation
- --> (degrees 45)
- --> (degrees 0)
- --> , Direction3d.fromAzimuthAndElevation
- --> (degrees 135)
- --> (degrees 0)
- --> , Direction3d.positiveZ
- --> )
-
- -- Three vectors in the XY plane:
- Direction3d.orthonormalize
- (Vector3d.fromComponents ( 2, 0, 0 ))
- (Vector3d.fromComponents ( 3, 1, 0 ))
- (Vector3d.fromComponents ( 4, 2, 0 ))
- --> Nothing
-
--}
+{-| -}
orthonormalize : Vector3d -> Vector3d -> Vector3d -> Maybe ( Direction3d, Direction3d, Direction3d )
orthonormalize xVector xyVector xyzVector =
Vector3d.direction xVector
@@ -488,22 +301,7 @@ orthonormalize xVector xyVector xyzVector =
)
-{-| Attempt to form a set of three mutually perpendicular directions from the
-three given directions;
-
- Direction3d.orthogonalize
- xDirection
- yDirection
- zDirection
-
-is equivalent to
-
- Direction3d.orthonormalize
- (Direction3d.toVector xDirection)
- (Direction3d.toVector yDirection)
- (Direction3d.toVector zDirection)
-
--}
+{-| -}
orthogonalize : Direction3d -> Direction3d -> Direction3d -> Maybe ( Direction3d, Direction3d, Direction3d )
orthogonalize xDirection yDirection zDirection =
orthonormalize
@@ -512,197 +310,61 @@ orthogonalize xDirection yDirection zDirection =
(toVector zDirection)
-{-| 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 direction
-
--}
+{-| -}
components : Direction3d -> ( Float, Float, Float )
components (Types.Direction3d components_) =
components_
-{-| Get the X component of a direction.
-
- Direction3d.xComponent Direction3d.x
- --> 1
-
- Direction3d.xComponent Direction3d.y
- --> 0
-
--}
+{-| -}
xComponent : Direction3d -> Float
xComponent (Types.Direction3d ( xComponent_, _, _ )) =
xComponent_
-{-| Get the Y component of a direction.
-
- Direction3d.yComponent Direction3d.y
- --> 1
-
- Direction3d.yComponent Direction3d.z
- --> 0
-
--}
+{-| -}
yComponent : Direction3d -> Float
yComponent (Types.Direction3d ( _, yComponent_, _ )) =
yComponent_
-{-| Get the Z component of a direction.
-
- Direction3d.zComponent Direction3d.z
- --> 1
-
- Direction3d.zComponent Direction3d.x
- --> 0
-
--}
+{-| -}
zComponent : Direction3d -> Float
zComponent (Types.Direction3d ( _, _, zComponent_ )) =
zComponent_
-{-| Find 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.fromAzimuthAndElevation
- (degrees 0)
- (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)
- --> -1
-
-This 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 direction
-
-is equivalent to
-
- Direction3d.componentIn Direction3d.z direction
-
--}
+{-| -}
componentIn : Direction3d -> Direction3d -> Float
componentIn firstDirection secondDirection =
Vector3d.componentIn firstDirection (toVector secondDirection)
-{-| Get the angle of a direction in the XY plane, measured from the X axis
-towards the Y axis (counterclockwise around the Z axis). The result will be in
-the range -π to π.
-
- Direction3d.azimuth Direction3d.x
- --> 0
-
- Direction3d.azimuth Direction3d.y
- --> degrees 90
-
- Direction3d.azimuth Direction3d.negativeY
- --> degrees -90
-
- Direction3d.azimuth Direction3d.negativeX
- --> degrees 180
-
-Vertical directions are considered to have an azimuth of zero:
-
- Direction3d.azimuth Direction3d.z
- --> 0
-
--}
+{-| -}
azimuth : Direction3d -> Float
azimuth direction =
atan2 (yComponent direction) (xComponent direction)
-{-| Get the angle of a direction from the XY plane towards positive Z. The
-result will be in the range -π/2 to π/2.
-
- Direction3d.elevation Direction3d.x
- --> 0
-
- Direction3d.elevation Direction3d.negativeY
- --> 0
-
- Direction3d.elevation Direction3d.z
- --> degrees 90
-
- Direction3d.elevation Direction3d.negativeZ
- --> degrees -90
-
--}
+{-| -}
elevation : Direction3d -> Float
elevation direction =
asin (zComponent direction)
-{-| Compare 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
- (degrees 2)
-
- Direction3d.equalWithin (degrees 5)
- Direction3d.x
- rotatedDirection
- --> True
-
- Direction3d.equalWithin (degrees 1)
- Direction3d.x
- rotatedDirection
- --> False
-
--}
+{-| -}
equalWithin : Float -> Direction3d -> Direction3d -> Bool
equalWithin angle firstDirection secondDirection =
angleFrom firstDirection secondDirection <= angle
-{-| Convert a direction to a unit vector.
-
- Direction3d.toVector Direction3d.y
- --> Vector3d.fromComponents ( 0, 1, 0 )
-
--}
+{-| -}
toVector : Direction3d -> Vector3d
toVector direction =
Vector3d.fromComponents (components direction)
-{-| 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.negativeY
- --> degrees 180
-
--}
+{-| -}
angleFrom : Direction3d -> Direction3d -> Float
angleFrom firstDirection secondDirection =
let
@@ -730,12 +392,7 @@ angleFrom firstDirection secondDirection =
atan2 relativeY relativeX
-{-| Reverse a direction.
-
- Direction3d.reverse Direction3d.y
- --> Direction3d.negativeY
-
--}
+{-| -}
reverse : Direction3d -> Direction3d
reverse direction =
let
@@ -745,160 +402,37 @@ reverse direction =
unsafe ( -dx, -dy, -dz )
-{-| Rotate a direction around an axis by a given angle.
-
- Direction3d.y
- |> Direction3d.rotateAround Axis3d.x (degrees 90)
- --> Direction3d.z
-
-Note 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.fromCoordinates ( 100, 200, 300 ))
-
- Direction3d.x
- |> Direction3d.rotateAround offsetAxis (degrees 90)
- --> Direction3d.y
-
--}
+{-| -}
rotateAround : Axis3d -> Float -> Direction3d -> Direction3d
rotateAround axis angle direction =
toVector direction |> Vector3d.rotateAround axis angle |> toDirection
-{-| Mirror a direction across a plane.
-
- direction =
- Direction3d.fromAzimuthAndElevation
- (degrees 30)
- (degrees 60)
-
- Direction3d.mirrorAcross Plane3d.xy direction
- --> Direction3d.fromAzimuthAndElevation
- --> (degrees 30)
- --> (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.fromAzimuthAndElevation
- --> (degrees 150)
- --> (degrees 60)
-
- offsetPlane =
- Plane3d.offsetBy 10 Plane3d.yz
-
- Direction3d.mirrorAcross offsetPlane direction
- --> Direction3d.fromAzimuthAndElevation
- --> (degrees 150)
- --> (degrees 60)
-
--}
+{-| -}
mirrorAcross : Plane3d -> Direction3d -> Direction3d
mirrorAcross plane direction =
toVector direction |> Vector3d.mirrorAcross plane |> toDirection
-{-| Find the [orthographic projection](https://en.wikipedia.org/wiki/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.fromAzimuthAndElevation
- (degrees -60)
- (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
- --> Nothing
-
--}
+{-| -}
projectOnto : Plane3d -> Direction3d -> Maybe Direction3d
projectOnto plane direction =
toVector direction |> Vector3d.projectOnto plane |> Vector3d.direction
-{-| 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.fromAzimuthAndElevation
- --> (degrees -30)
- --> (degrees 0)
-
- Direction3d.relativeTo rotatedFrame Direction3d.y
- --> Direction3d.fromAzimuthAndElevation
- --> (degrees 60)
- --> (degrees 0)
-
- Direction3d.relativeTo rotatedFrame Direction3d.z
- --> Direction3d.z
-
--}
+{-| -}
relativeTo : Frame3d -> Direction3d -> Direction3d
relativeTo frame direction =
toVector direction |> Vector3d.relativeTo frame |> toDirection
-{-| 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.fromAzimuthAndElevation
- --> (degrees 30)
- --> (degrees 0)
-
- Direction3d.placeIn rotatedFrame Direction3d.y
- --> Direction3d.fromAzimuthAndElevation
- --> (degrees 120)
- --> (degrees 0)
-
- Direction3d.placeIn rotatedFrame Direction3d.z
- --> Direction3d.z
-
--}
+{-| -}
placeIn : Frame3d -> Direction3d -> Direction3d
placeIn frame direction =
toVector direction |> Vector3d.placeIn frame |> toDirection
-{-| Project a direction into a given sketch plane. Conceptually, this finds the
-[orthographic projection](https://en.wikipedia.org/wiki/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.fromAzimuthAndElevation
- (degrees -60)
- (degrees 0)
-
- Direction3d.projectInto SketchPlane3d.xy direction
- --> Just (Direction2d.fromAngle (degrees -60))
-
- Direction3d.projectInto SketchPlane3d.xz direction
- --> Just Direction2d.x
-
- Direction3d.projectInto SketchPlane3d.yz direction
- --> Just Direction2d.negativeX
-
- Direction3d.projectInto SketchPlane3d.xy Direction3d.z
- --> Nothing
-
--}
+{-| -}
projectInto : SketchPlane3d -> Direction3d -> Maybe Direction2d
projectInto sketchPlane direction =
toVector direction |> Vector3d.projectInto sketchPlane |> Vector2d.direction
diff --git a/src/Ellipse2d.elm b/src/Ellipse2d.elm
index 794ac1ea..1a765c46 100644
--- a/src/Ellipse2d.elm
+++ b/src/Ellipse2d.elm
@@ -68,20 +68,7 @@ type alias Ellipse2d =
Types.Ellipse2d
-{-| Construct an ellipse from its center point, X direction, and X and Y radii.
-If you pass a negative radius, the absolute value will be used.
-
- exampleEllipse =
- Ellipse2d.with
- { centerPoint =
- Point2d.fromCoordinates ( 10, 10 )
- , xDirection =
- Direction2d.fromAngle (degrees 30)
- , xRadius = 5
- , yRadius = 3
- }
-
--}
+{-| -}
with : { centerPoint : Point2d, xDirection : Direction2d, xRadius : Float, yRadius : Float } -> Ellipse2d
with properties =
Types.Ellipse2d
@@ -92,127 +79,61 @@ with properties =
}
-{-| Get the center point of an ellipse.
-
- Ellipse2d.centerPoint exampleEllipse
- --> Point2d.fromCoordinates ( 10, 10 )
-
--}
+{-| -}
centerPoint : Ellipse2d -> Point2d
centerPoint ellipse =
Frame2d.originPoint (axes ellipse)
-{-| Get the X and Y axes of an ellipse as a `Frame2d`.
-
- Ellipse2d.axes exampleEllipse
- --> Frame2d.withXDirection
- --> (Direction2d.fromAngle (degrees 30))
- --> (Point2d.fromCoordinates ( 10, 10 ))
-
--}
+{-| -}
axes : Ellipse2d -> Frame2d
axes (Types.Ellipse2d ellipse) =
ellipse.axes
-{-| Get the X axis of an ellipse.
-
- Ellipse2d.xAxis exampleEllipse
- --> Axis2d.through
- --> (Point2d.fromCoordinates ( 10, 10 ))
- --> (Direction2d.fromAngle (degrees 30))
-
--}
+{-| -}
xAxis : Ellipse2d -> Axis2d
xAxis ellipse =
Frame2d.xAxis (axes ellipse)
-{-| Get the Y axis of an ellipse.
-
- Ellipse2d.yAxis exampleEllipse
- --> Axis2d.through
- --> (Point2d.fromCoordinates ( 10, 10 ))
- --> (Direction2d.fromAngle (degrees 120))
-
--}
+{-| -}
yAxis : Ellipse2d -> Axis2d
yAxis ellipse =
Frame2d.yAxis (axes ellipse)
-{-| Get the radius of an ellipse along its X axis. This may be either the
-minimum or maximum radius.
-
- Ellipse2d.xRadius exampleEllipse
- --> 5
-
--}
+{-| -}
xRadius : Ellipse2d -> Float
xRadius (Types.Ellipse2d ellipse) =
ellipse.xRadius
-{-| Get the radius of an ellipse along its Y axis. This may be either the
-minimum or maximum radius.
-
- Ellipse2d.yRadius exampleEllipse
- --> 3
-
--}
+{-| -}
yRadius : Ellipse2d -> Float
yRadius (Types.Ellipse2d ellipse) =
ellipse.yRadius
-{-| Get the direction of the ellipse's X axis.
-
- Ellipse2d.xDirection exampleEllipse
- --> Direction2d.fromAngle (degrees 30)
-
--}
+{-| -}
xDirection : Ellipse2d -> Direction2d
xDirection ellipse =
Frame2d.xDirection (axes ellipse)
-{-| Get the direction of an ellipse's Y axis.
-
- Ellipse2d.yDirection exampleEllipse
- --> Direction2d.fromAngle (degrees 120)
-
--}
+{-| -}
yDirection : Ellipse2d -> Direction2d
yDirection ellipse =
Frame2d.yDirection (axes ellipse)
-{-| Get the area of an ellipse.
-
- Ellipse2d.area exampleEllipse
- --> 47.1239
-
--}
+{-| -}
area : Ellipse2d -> Float
area ellipse =
pi * xRadius ellipse * yRadius ellipse
-{-| Scale an ellipse about a given point by a given scale.
-
- exampleEllipse
- |> Ellipse2d.scaleAbout Point2d.origin 3
- --> Ellipse2d.with
- --> { centerPoint =
- --> Point2d.fromCoordinates ( 30, 30 )
- --> , xDirection =
- --> Direction2d.fromAngle (degrees 30)
- --> , xRadius = 15
- --> , yRadius = 9
- --> }
-
--}
+{-| -}
scaleAbout : Point2d -> Float -> Ellipse2d -> Ellipse2d
scaleAbout point scale ellipse =
let
@@ -246,124 +167,37 @@ transformBy axesTransformation (Types.Ellipse2d properties) =
{ properties | axes = axesTransformation properties.axes }
-{-| Rotate an ellipse around a given point by a given angle (in radians).
-
- exampleEllipse
- |> Ellipse2d.rotateAround Point2d.origin
- (degrees 45)
- --> Ellipse2d.with
- --> { centerPoint =
- --> Point2d.fromCoordinates ( 0, 14.142 )
- --> , xDirection =
- --> Direction2d.fromAngle (degrees 75)
- --> , xRadius = 5
- --> , yRadius = 3
- --> }
-
--}
+{-| -}
rotateAround : Point2d -> Float -> Ellipse2d -> Ellipse2d
rotateAround point angle =
transformBy (Frame2d.rotateAround point angle)
-{-| Translate an ellipse by a given displacement.
-
- exampleEllipse
- |> Ellipse2d.translateBy
- (Vector2d.fromComponents ( 5, 10 ))
- --> Ellipse2d.with
- --> { centerPoint =
- --> Point2d.fromCoordinates ( 15, 20 )
- --> , xDirection =
- --> Direction2d.fromAngle (degrees 30)
- --> , xRadius = 5
- --> , yRadius = 3
- --> }
-
--}
+{-| -}
translateBy : Vector2d -> Ellipse2d -> Ellipse2d
translateBy displacement =
transformBy (Frame2d.translateBy displacement)
-{-| Translate an ellipse in a given direction by a given distance;
-
- Ellipse2d.translateIn direction distance
-
-is equivalent to
-
- Ellipse2d.translateBy
- (Vector2d.withLength distance direction)
-
--}
+{-| -}
translateIn : Direction2d -> Float -> Ellipse2d -> Ellipse2d
translateIn direction distance ellipse =
translateBy (Vector2d.withLength distance direction) ellipse
-{-| Mirror an ellipse across a given axis.
-
- mirroredEllipse =
- Ellipse2d.mirrorAcross Axis2d.x exampleEllipse
-
- Ellipse2d.centerPoint mirroredEllipse
- --> Point2d.fromCoordinates ( 10, -10 )
-
- Ellipse2d.xDirection mirroredEllipse
- --> Direction2d.fromAngle (degrees -30)
-
- Ellipse2d.yDirection mirroredEllipse
- --> Direction2d.fromAngle (degrees -120)
-
-Note that if the axes of the original ellipse form a [right-handed](https://en.wikipedia.org/wiki/Cartesian_coordinate_system#Orientation_and_handedness)
-frame, then the axes of the mirrored ellipse will form a left-handed frame (and
-vice versa).
-
--}
+{-| -}
mirrorAcross : Axis2d -> Ellipse2d -> Ellipse2d
mirrorAcross axis =
transformBy (Frame2d.mirrorAcross axis)
-{-| Take an ellipse defined in global coordinates, and return it expressed in
-local coordinates relative to a given reference frame.
-
- localFrame =
- Frame2d.atPoint (Point2d.fromCoordinates (15, 5))
-
- Ellipse2d.relativeTo localFrame exampleEllipse
- --> Ellipse2d.with
- --> { centerPoint =
- --> Point2d.fromCoordinates ( -5, 5 )
- --> , xDirection =
- --> Direction2d.fromAngle (degrees 30)
- --> , xRadius = 5
- --> , yRadius = 3
- --> }
-
--}
+{-| -}
relativeTo : Frame2d -> Ellipse2d -> Ellipse2d
relativeTo frame =
transformBy (Frame2d.relativeTo frame)
-{-| Take an ellipse considered to be defined in local coordinates relative to a
-given reference frame, and return that circle expressed in global coordinates.
-
- localFrame =
- Frame2d.atPoint (Point2d.fromCoordinates (15, 5))
-
- Ellipse2d.placeIn localFrame exampleEllipse
- --> Ellipse2d.with
- --> { centerPoint =
- --> Point2d.fromCoordinates ( 25, 15 )
- --> , xDirection =
- --> Direction2d.fromAngle (degrees 30)
- --> , xRadius = 5
- --> , yRadius = 3
- --> }
-
--}
+{-| -}
placeIn : Frame2d -> Ellipse2d -> Ellipse2d
placeIn frame =
transformBy (Frame2d.placeIn frame)
diff --git a/src/EllipticalArc2d.elm b/src/EllipticalArc2d.elm
index d0f29525..8e605a73 100644
--- a/src/EllipticalArc2d.elm
+++ b/src/EllipticalArc2d.elm
@@ -72,10 +72,6 @@ treat them as actual angles and everything will behave as you expect.
# Properties
@docs startAngle, sweptAngle, startPoint, endPoint
-
-All remaining properties of elliptical arcs are actually just properties of the
-underlying ellipse; check out the [Ellipse2d](Ellipse2d) module for details.
-
@docs centerPoint, axes, xAxis, yAxis, xDirection, yDirection, xRadius, yRadius
@@ -138,38 +134,7 @@ type alias EllipticalArc2d =
Types.EllipticalArc2d
-{-| Construct an elliptical arc from its center point, X direction, X and Y
-radii, start angle and swept angle. If you pass a negative radius, the absolute
-value will be used.
-
-For example, to construct a simple 90 degree elliptical arc, you might use
-
- exampleArc =
- EllipticalArc2d.with
- { centerPoint = Point2d.origin
- , xDirection = Direction2d.x
- , xRadius = 2
- , yRadius = 1
- , startAngle = 0
- , sweptAngle = degrees 90
- }
-
-
-
-To make an inclined 180 degree elliptical arc, you might use
-
- EllipticalArc2d.with
- { centerPoint = Point2d.origin
- , xDirection = Direction2d.fromAngle (degrees 30)
- , xRadius = 2
- , yRadius = 1
- , startAngle = degrees -90
- , sweptAngle = degrees 180
- }
-
-
-
--}
+{-| -}
with : { centerPoint : Point2d, xDirection : Direction2d, xRadius : Float, yRadius : Float, startAngle : Float, sweptAngle : Float } -> EllipticalArc2d
with properties =
Types.EllipticalArc2d
@@ -185,37 +150,7 @@ with properties =
}
-{-| Attempt to construct an elliptical arc from its endpoints, X direction, and
-X and Y radii. For any given valid set of these inputs, there are four possible
-solutions, so you also need to specify which of the four solutions you want -
-whether the swept angle of the arc should be less than or greater than 180
-degrees, and whether the swept angle should be positive (counterclockwise) or
-negative (clockwise).
-
-The example below is interactive; try dragging either endpoint or the tip of the
-X direction (or the center point to move the whole arc), clicking on the X or Y
-radial lines and then scrolling to changet that radius, or clicking/tapping on
-the various dashed arcs to switch what kind of swept angle to use.
-
-
-
-This function will return `Nothing` if no solution can found. Typically this
-means that the two endpoints are too far apart, but could also mean that one of
-the specified radii was negative or zero, or the two given points were
-coincident.
-
-The behavior of this function is very close to [the SVG spec](https://www.w3.org/TR/SVG/implnote.html#ArcImplementationNotes),
-but when 'out of range' parameters are given this function will simply return
-`Nothing` instead of attempting to degrade gracefully (for example, by
-increasing X and Y radius slightly if the given endpoints are slightly too far
-apart). Note that this means this function is dangerous to use for 180 degree
-arcs, since then slight numerical roundoff can mean the difference between a
-solution being found and not - for 180 degree arcs it is safer to use
-`EllipticalArc2d.with` instead.
-
--}
+{-| -}
fromEndpoints : { startPoint : Point2d, endPoint : Point2d, xRadius : Float, yRadius : Float, xDirection : Direction2d, sweptAngle : SweptAngle } -> Maybe EllipticalArc2d
fromEndpoints arguments =
if arguments.xRadius > 0 && arguments.yRadius > 0 then
@@ -340,43 +275,19 @@ yRadius (Types.EllipticalArc2d arc) =
Ellipse2d.yRadius arc.ellipse
-{-| The start angle of an elliptical arc is the value of the [ellipse parameter](https://en.wikipedia.org/wiki/Ellipse#Parametric_representation)
-at the start point of the arc.
-
- EllipticalArc2d.startAngle exampleArc
- --> 0
-
--}
+{-| -}
startAngle : EllipticalArc2d -> Float
startAngle (Types.EllipticalArc2d arc) =
arc.startAngle
-{-| The swept angle of an elliptical arc is the difference between values of the
-[ellipse parameter](https://en.wikipedia.org/wiki/Ellipse#Parametric_representation)
-from the start point to the end point of the arc.
-
- EllipticalArc2d.sweptAngle exampleArc
- --> degrees 90
-
--}
+{-| -}
sweptAngle : EllipticalArc2d -> Float
sweptAngle (Types.EllipticalArc2d arc) =
arc.sweptAngle
-{-| Get the point along an elliptical arc at a given parameter value:
-
- EllipticalArc2d.pointOn exampleArc ParameterValue.zero
- --> Point2d.fromCoordinates ( 2, 0 )
-
- EllipticalArc2d.pointOn exampleArc ParameterValue.half
- --> Point2d.fromCoordinates ( 1.4142, 0.7071 )
-
- EllipticalArc2d.pointOn exampleArc ParameterValue.one
- --> Point2d.fromCoordinates ( 0, 1 )
-
--}
+{-| -}
pointOn : EllipticalArc2d -> ParameterValue -> Point2d
pointOn arc parameterValue =
let
@@ -392,37 +303,13 @@ pointOn arc parameterValue =
)
-{-| Get points along an elliptical arc at a given set of parameter values:
-
- exampleArc
- |> EllipticalArc2d.pointsAt
- (ParameterValue.steps 2)
- --> [ Point2d.fromCoordinates ( 2, 0 )
- --> , Point2d.fromCoordinates ( 1.4142, 0.7071 )
- --> , Point2d.fromCoordinates ( 0, 1 )
- --> ]
-
--}
+{-| -}
pointsAt : List ParameterValue -> EllipticalArc2d -> List Point2d
pointsAt parameterValues arc =
List.map (pointOn arc) parameterValues
-{-| Get the first derivative of an elliptical arc at a given parameter value:
-
- EllipticalArc2d.firstDerivative exampleArc
- ParameterValue.zero
- --> Vector2d.fromComponents ( 0, 1.5708 )
-
- EllipticalArc2d.firstDerivative exampleArc
- ParameterValue.half
- --> Vector2d.fromComponents ( -2.2214, 1.1107 )
-
- EllipticalArc2d.firstDerivative exampleArc
- ParameterValue.one
- --> Vector2d.fromComponents ( -3.1416, 0 )
-
--}
+{-| -}
firstDerivative : EllipticalArc2d -> ParameterValue -> Vector2d
firstDerivative arc parameterValue =
let
@@ -442,46 +329,20 @@ firstDerivative arc parameterValue =
)
-{-| Evaluate the first derivative of an elliptical arc at a given set of
-parameter values:
-
- exampleArc
- |> EllipticalArc2d.firstDerivativesAt
- (ParameterValue.steps 2)
- --> [ Vector2d.fromComponents ( 0, 1.5708 )
- --> , Vector2d.fromComponents ( -2.2214, 1.1107 )
- --> , Vector2d.fromComponents ( -3.1416, 0 )
- --> ]
-
--}
+{-| -}
firstDerivativesAt : List ParameterValue -> EllipticalArc2d -> List Vector2d
firstDerivativesAt parameterValues arc =
List.map (firstDerivative arc) parameterValues
-{-| If a curve has zero length (consists of just a single point), then we say
-that it is 'degenerate'. Some operations such as computing tangent directions
-are not defined on degenerate curves.
-
-A `Nondegenerate` value represents an arc that is definitely not degenerate. It
-is used as input to functions such as `EllipticalArc2d.tangentDirection` and can
-be constructed using `EllipticalArc2d.nondegenerate`.
-
--}
+{-| -}
type Nondegenerate
= Curved EllipticalArc2d
| Horizontal EllipticalArc2d
| Vertical EllipticalArc2d
-{-| Attempt to construct a nondegenerate elliptical arc from a general
-`EllipticalArc2d`. If the arc is in fact degenerate (consists of a single
-point), returns an `Err` with that point.
-
- EllipticalArc2d.nondegenerate exampleArc
- --> Ok nondegenerateExampleArc
-
--}
+{-| -}
nondegenerate : EllipticalArc2d -> Result Point2d Nondegenerate
nondegenerate arc =
let
@@ -503,13 +364,7 @@ nondegenerate arc =
Ok (Curved arc)
-{-| Convert a nondegenerate elliptical arc back to a general `EllipticalArc2d`.
-
- EllipticalArc2d.fromNondegenerate
- nondegenerateExampleArc
- --> exampleArc
-
--}
+{-| -}
fromNondegenerate : Nondegenerate -> EllipticalArc2d
fromNondegenerate nondegenerateArc =
case nondegenerateArc of
@@ -523,22 +378,7 @@ fromNondegenerate nondegenerateArc =
arc
-{-| Get the tangent direction to a nondegenerate elliptical arc at a given
-parameter value:
-
- EllipticalArc2d.tangentDirection nondegenerateExampleArc
- ParameterValue.zero
- --> Direction2d.fromAngle (degrees 90)
-
- EllipticalArc2d.tangentDirection nondegenerateExampleArc
- ParameterValue.half
- --> Direction2d.fromAngle (degrees 153.4)
-
- EllipticalArc2d.tangentDirection nondegenerateExampleArc
- ParameterValue.one
- --> Direction2d.fromAngle (degrees 180)
-
--}
+{-| -}
tangentDirection : Nondegenerate -> ParameterValue -> Direction2d
tangentDirection nondegenerateArc parameterValue =
let
@@ -589,45 +429,13 @@ tangentDirection nondegenerateArc parameterValue =
xDirection horizontalArc
-{-| Get tangent directions to a nondegenerate elliptical arc at a given set of
-parameter values:
-
- nondegenerateExampleArc
- |> EllipticalArc2d.tangentDirectionsAt
- (ParameterValue.steps 2)
- --> [ Direction2d.fromAngle (degrees 90)
- --> , Direction2d.fromAngle (degrees 153.4)
- --> , Direction2d.fromAngle (degrees 180)
- --> ]
-
--}
+{-| -}
tangentDirectionsAt : List ParameterValue -> Nondegenerate -> List Direction2d
tangentDirectionsAt parameterValues nondegenerateArc =
List.map (tangentDirection nondegenerateArc) parameterValues
-{-| Get both the point and tangent direction of a nondegenerate elliptical arc
-at a given parameter value:
-
- EllipticalArc2d.sample nondegenerateExampleArc
- ParameterValue.zero
- --> ( Point2d.fromCoordinates ( 2, 0 )
- --> , Direction2d.fromAngle (degrees 90)
- --> )
-
- EllipticalArc2d.sample nondegenerateExampleArc
- ParameterValue.half
- --> ( Point2d.fromCoordinates ( 1.4142, 0.7071 )
- --> , Direction2d.fromAngle (degrees 153.4)
- --> )
-
- EllipticalArc2d.sample nondegenerateExampleArc
- ParameterValue.one
- --> ( Point2d.fromCoordinates ( 0, 1 )
- --> , Direction2d.fromAngle (degrees 180)
- --> )
-
--}
+{-| -}
sample : Nondegenerate -> ParameterValue -> ( Point2d, Direction2d )
sample nondegenerateArc parameterValue =
( pointOn (fromNondegenerate nondegenerateArc) parameterValue
@@ -635,46 +443,19 @@ sample nondegenerateArc parameterValue =
)
-{-| Get points and tangent directions of a nondegenerate arc at a given set of
-parameter values:
-
- nondegenerateExampleArc
- |> EllipticalArc2d.samplesAt
- (ParameterValue.steps 2)
- --> [ ( Point2d.fromCoordinates ( 2, 0 )
- --> , Direction2d.fromAngle (degrees 90)
- --> )
- --> , ( Point2d.fromCoordinates ( 1.4142, 0.7071 )
- --> , Direction2d.fromAngle (degrees 153.4)
- --> )
- --> , ( Point2d.fromCoordinates ( 0, 1 )
- --> , Direction2d.fromAngle (degrees 180)
- --> )
- --> ]
-
--}
+{-| -}
samplesAt : List ParameterValue -> Nondegenerate -> List ( Point2d, Direction2d )
samplesAt parameterValues nondegenerateArc =
List.map (sample nondegenerateArc) parameterValues
-{-| Get the start point of an elliptical arc.
-
- EllipticalArc2d.startPoint exampleArc
- --> Point2d.fromCoordinates ( 2, 0 )
-
--}
+{-| -}
startPoint : EllipticalArc2d -> Point2d
startPoint arc =
pointOn arc ParameterValue.zero
-{-| Get the end point of an elliptical arc.
-
- EllipticalArc2d.endPoint exampleArc
- --> Point2d.fromCoordinates ( 0, 1 )
-
--}
+{-| -}
endPoint : EllipticalArc2d -> Point2d
endPoint arc =
pointOn arc ParameterValue.one
@@ -692,21 +473,7 @@ yDirection arc =
Frame2d.yDirection (axes arc)
-{-| Reverse the direction of an elliptical arc, so that the start point becomes
-the end point and vice versa. Does not change the shape of the arc or any
-properties of the underlying ellipse.
-
- EllipticalArc2d.reverse exampleArc
- --> EllipticalArc2d.with
- --> { centerPoint = Point2d.origin
- --> , xDirection = Direction2d.x
- --> , xRadius = 2
- --> , yRadius = 1
- --> , startAngle = degrees 90
- --> , sweptAngle = degrees -90
- --> }
-
--}
+{-| -}
reverse : EllipticalArc2d -> EllipticalArc2d
reverse (Types.EllipticalArc2d properties) =
Types.EllipticalArc2d
@@ -722,155 +489,49 @@ transformBy ellipseTransformation (Types.EllipticalArc2d properties) =
{ properties | ellipse = ellipseTransformation properties.ellipse }
-{-| Scale an elliptical arc about a given point by a given scale.
-
- exampleArc
- |> EllipticalArc2d.scaleAbout Point2d.origin 3
- --> EllipticalArc2d.with
- --> { centerPoint = Point2d.origin
- --> , xDirection = Direction2d.x
- --> , xRadius = 6
- --> , yRadius = 3
- --> , startAngle = 0
- --> , sweptAngle = degrees 90
- --> }
-
--}
+{-| -}
scaleAbout : Point2d -> Float -> EllipticalArc2d -> EllipticalArc2d
scaleAbout point scale =
transformBy (Ellipse2d.scaleAbout point scale)
-{-| Rotate an elliptical arc around a given point by a given angle (in radians).
-
- exampleArc
- |> EllipticalArc2d.rotateAround Point2d.origin
- (degrees 180)
- --> EllipticalArc2d.with
- --> { centerPoint = Point2d.origin
- --> , xDirection = Direction2d.negativeX
- --> , xRadius = 2
- --> , yRadius = 1
- --> , startAngle = 0
- --> , sweptAngle = degrees 90
- --> }
-
--}
+{-| -}
rotateAround : Point2d -> Float -> EllipticalArc2d -> EllipticalArc2d
rotateAround point angle =
transformBy (Ellipse2d.rotateAround point angle)
-{-| Translate an elliptical arc by a given displacement.
-
- exampleArc
- |> EllipticalArc2d.translateBy
- (Vector2d.fromComponents ( 2, 3 ))
- --> EllipticalArc2d.with
- --> { centerPoint =
- --> Point2d.fromCoordinates ( 2, 3 )
- --> , xDirection = Direction2d.x
- --> , xRadius = 2
- --> , yRadius = 1
- --> , startAngle = 0
- --> , sweptAngle = degrees 90
- --> }
-
--}
+{-| -}
translateBy : Vector2d -> EllipticalArc2d -> EllipticalArc2d
translateBy displacement =
transformBy (Ellipse2d.translateBy displacement)
-{-| Translate an elliptical arc in a given direction by a given distance;
-
- EllipticalArc2d.translateIn direction distance
-
-is equivalent to
-
- EllipticalArc2d.translateBy
- (Vector2d.withLength distance direction)
-
--}
+{-| -}
translateIn : Direction2d -> Float -> EllipticalArc2d -> EllipticalArc2d
translateIn direction distance arc =
translateBy (Vector2d.withLength distance direction) arc
-{-| Mirror an elliptical arc across a given axis.
-
- mirroredArc =
- exampleArc
- |> EllipticalArc2d.mirrorAcross Axis2d.y
-
- EllipticalArc2d.startPoint mirroredArc
- --> Point2d.fromCoordinates ( -2, 0 )
-
- EllipticalArc2d.endPoint mirroredArc
- --> Point2d.fromCoordinates ( 0, 1 )
-
--}
+{-| -}
mirrorAcross : Axis2d -> EllipticalArc2d -> EllipticalArc2d
mirrorAcross axis =
transformBy (Ellipse2d.mirrorAcross axis)
-{-| Take an elliptical arc defined in global coordinates, and return it expressed in
-local coordinates relative to a given reference frame.
-
- localFrame =
- Frame2d.atPoint (Point2d.fromCoordinates ( 1, 2 ))
-
- EllipticalArc2d.relativeTo localFrame exampleArc
- --> EllipticalArc2d.with
- --> { centerPoint =
- --> Point2d.fromCoordinates ( -1, -2 )
- --> , xDirection = Direction2d.x
- --> , xRadius = 2
- --> , yRadius = 1
- --> , startAngle = 0
- --> , sweptAngle = degrees 90
- --> }
-
--}
+{-| -}
relativeTo : Frame2d -> EllipticalArc2d -> EllipticalArc2d
relativeTo frame =
transformBy (Ellipse2d.relativeTo frame)
-{-| Take an elliptical arc considered to be defined in local coordinates
-relative to a given reference frame, and return that arc expressed in global
-coordinates.
-
- localFrame =
- Frame2d.atPoint (Point2d.fromCoordinates ( 1, 2 ))
-
- EllipticalArc2d.relativeTo localFrame exampleArc
- --> EllipticalArc2d.with
- --> { centerPoint =
- --> Point2d.fromCoordinates ( 1, 2 )
- --> , xDirection = Direction2d.x
- --> , xRadius = 2
- --> , yRadius = 1
- --> , startAngle = 0
- --> , sweptAngle = degrees 90
- --> }
-
--}
+{-| -}
placeIn : Frame2d -> EllipticalArc2d -> EllipticalArc2d
placeIn frame =
transformBy (Ellipse2d.placeIn frame)
-{-| Find a conservative upper bound on the magnitude of the second derivative of
-an elliptical arc. This can be useful when determining error bounds for various
-kinds of linear approximations.
-
- exampleArc
- |> EllipticalArc2d.maxSecondDerivativeMagnitude
- --> 4.935
-
--}
+{-| -}
maxSecondDerivativeMagnitude : EllipticalArc2d -> Float
maxSecondDerivativeMagnitude arc =
let
@@ -984,8 +645,7 @@ derivativeMagnitude arc =
absDTheta * sqrt (dx * dx + dy * dy)
-{-| An elliptical arc that has been parameterized by arc length.
--}
+{-| -}
type ArcLengthParameterized
= ArcLengthParameterized
{ underlyingArc : EllipticalArc2d
@@ -994,17 +654,7 @@ type ArcLengthParameterized
}
-{-| Build an arc length parameterization of the given elliptical arc, with a
-given accuracy. Generally speaking, all operations on the resulting
-`ArcLengthParameterized` value will be accurate to within the specified maximum
-error.
-
- parameterizedArc =
- exampleArc
- |> EllipticalArc2d.arcLengthParameterized
- { maxError = 1.0e-4 }
-
--}
+{-| -}
arcLengthParameterized : { maxError : Float } -> EllipticalArc2d -> ArcLengthParameterized
arcLengthParameterized { maxError } arc =
let
@@ -1023,40 +673,14 @@ arcLengthParameterized { maxError } arc =
}
-{-| Find the total arc length of an elliptical arc. This will be accurate to
-within the tolerance given when calling `arcLengthParameterized`.
-
- arcLength : Float
- arcLength =
- EllipticalArc2d.arcLength parameterizedArc
-
- arcLength
- --> 2.4221
-
--}
+{-| -}
arcLength : ArcLengthParameterized -> Float
arcLength parameterizedArc =
arcLengthParameterization parameterizedArc
|> ArcLengthParameterization.totalArcLength
-{-| Try to get the point along an elliptical arc at a given arc length. For
-example, to get the true midpoint of `exampleArc`:
-
- EllipticalArc2d.pointAlong parameterizedArc
- (arcLength / 2)
- --> Just (Point2d.fromCoordinates ( 1.1889, 0.8041 ))
-
-Note that this is not the same as evaulating at a parameter value of 0.5:
-
- EllipticalArc2d.pointOn exampleArc
- ParameterValue.half
- --> Point2d.fromCoordinates ( 1.4142, 0.7071 )
-
-If the given arc length is less than zero or greater than the arc length of the
-arc, returns `Nothing`.
-
--}
+{-| -}
pointAlong : ArcLengthParameterized -> Float -> Maybe Point2d
pointAlong (ArcLengthParameterized parameterized) distance =
parameterized.parameterization
@@ -1064,17 +688,7 @@ pointAlong (ArcLengthParameterized parameterized) distance =
|> Maybe.map (pointOn parameterized.underlyingArc)
-{-| Try to get the tangent direction along an elliptical arc at a given arc
-length. To get the tangent direction at the midpoint of `exampleArc`:
-
- EllipticalArc2d.tangentDirectionAlong parameterizedArc
- (arcLength / 2)
- --> Just (Direction2d.fromAngle (degrees 159.7))
-
-If the given arc length is less than zero or greater than the arc length of the
-elliptical arc (or if the elliptical arc is degenerate), returns `Nothing`.
-
--}
+{-| -}
tangentDirectionAlong : ArcLengthParameterized -> Float -> Maybe Direction2d
tangentDirectionAlong (ArcLengthParameterized parameterized) distance =
case parameterized.nondegenerateArc of
@@ -1087,21 +701,7 @@ tangentDirectionAlong (ArcLengthParameterized parameterized) distance =
Nothing
-{-| Try to get the point and tangent direction along an elliptical arc at a
-given arc length. To get the point and tangent direction at the midpoint of
-`exampleArc`:
-
- EllipticalArc2d.sampleAlong parameterizedArc
- (arcLength / 2)
- --> Just
- --> ( Point2d.fromCoordinates ( 1.1889, 0.8041 )
- --> , Direction2d.fromAngle (degrees 159.7)
- --> )
-
-If the given arc length is less than zero or greater than the arc length of the
-spline (or if the spline is degenerate), returns `Nothing`.
-
--}
+{-| -}
sampleAlong : ArcLengthParameterized -> Float -> Maybe ( Point2d, Direction2d )
sampleAlong (ArcLengthParameterized parameterized) distance =
case parameterized.nondegenerateArc of
diff --git a/src/Float/Range.elm b/src/Float/Range.elm
index e636521c..e0ba31ee 100644
--- a/src/Float/Range.elm
+++ b/src/Float/Range.elm
@@ -122,51 +122,13 @@ toList range =
map identity range
-{-| Specify the number of steps to take between 0 and 1. Note that the number of
-values in the range will be one greater than the number of steps!
-
- Range.values (Range.from 0 5 (Range.numSteps 1))
- --> [ 0, 5 ]
-
- Range.values (Range.from 0 1 (Range.numSteps 2))
- --> [ 0, 0.5, 1 ]
-
- Range.values (Range.from 0 1 (Range.numSteps 5))
- --> [ 0, 0.2, 0.4, 0.6, 0.8, 1 ]
-
-Passing a negative or zero number of steps will result in an empty range:
-
- Range.values (Range.from 0 1 (Range.numSteps 0))
- --> []
-
--}
+{-| -}
numSteps : Int -> Resolution
numSteps =
NumSteps
-{-| Specify the _maximum_ step size from one parameter value to the next. The
-actual step size will be chosen to result in an even parameter spacing.
-
- Range.values (Range.from 0 1 (Range.maxStepSize 0.5))
- --> [ 0, 0.5, 1 ]
-
- Range.values (Range.from 0 1 (Range.maxStepSize 0.499))
- --> [ 0, 0.3333, 0.6667, 1 ]
-
- Range.values (Range.from 0 1 (Range.maxStepSize 1))
- --> [ 0, 1 ]
-
- Range.values (Range.from 0 1 (Range.maxStepSize 1.5))
- --> [ 0, 1 ]
-
-Passing a negative or zero maximum step size will result in no values being
-produced:
-
- Range.values (Range.from 0 1 (Range.maxStepSize 0))
- --> []
-
--}
+{-| -}
maxStepSize : Float -> Resolution
maxStepSize =
MaxStepSize
diff --git a/src/Frame2d.elm b/src/Frame2d.elm
index 7b2ec7be..41eb55f4 100644
--- a/src/Frame2d.elm
+++ b/src/Frame2d.elm
@@ -95,36 +95,13 @@ type alias Frame2d =
Types.Frame2d
-{-| The global XY frame.
-
- Frame2d.originPoint Frame2d.xy
- --> Point2d.origin
-
- Frame2d.xDirection Frame2d.xy
- --> Direction2d.x
-
- Frame2d.yDirection Frame2d.xy
- --> Direction2d.y
-
--}
+{-| -}
xy : Frame2d
xy =
atPoint Point2d.origin
-{-| Construct a frame with the given X axis direction, having the given origin
-point. The Y axis direction will be constructed by rotating the given X
-direction 90 degrees counterclockwise:
-
- frame =
- Frame2d.withXDirection
- (Direction2d.fromAngle (degrees 30))
- (Point2d.fromCoordinates ( 2, 3 ))
-
- Frame2d.yDirection frame
- --> Direction2d.fromAngle (degrees 120)
-
--}
+{-| -}
withXDirection : Direction2d -> Point2d -> Frame2d
withXDirection xDirection_ originPoint_ =
unsafe
@@ -134,19 +111,7 @@ withXDirection xDirection_ originPoint_ =
}
-{-| Construct a frame with the given Y axis direction, having the given origin
-point. The X axis direction will be constructed by rotating the given X
-direction 90 degrees clockwise:
-
- frame =
- Frame2d.withYDirection
- (Direction2d.fromAngle (degrees 30))
- (Point2d.fromCoordinates ( 2, 3 ))
-
- Frame2d.yDirection frame
- --> Direction2d.fromAngle (degrees -60)
-
--}
+{-| -}
withYDirection : Direction2d -> Point2d -> Frame2d
withYDirection yDirection_ originPoint_ =
unsafe
@@ -156,48 +121,13 @@ withYDirection yDirection_ originPoint_ =
}
-{-| Construct a frame directly from its origin point and X and Y directions:
-
- frame =
- Frame2d.unsafe
- { originPoint =
- Point2d.fromCoordinates ( 2, 3 )
- , xDirection =
- Direction2d.fromAngle (degrees 45)
- , yDirection =
- Direction2d.fromAngle (degrees 135)
- }
-
-In this case **you must be careful to ensure that the X and Y directions are
-perpendicular**. To construct pairs of perpendicular directions,
-[`Direction2d.orthonormalize`](Direction2d#orthonormalize) or
-[`Direction2d.orthogonalize`](Direction2d#orthogonalize) may be useful.
-
--}
+{-| -}
unsafe : { originPoint : Point2d, xDirection : Direction2d, yDirection : Direction2d } -> Frame2d
unsafe =
Types.Frame2d
-{-| Construct a frame aligned with the global XY frame but with the given origin
-point.
-
- point =
- Point2d.fromCoordinates ( 2, 3 )
-
- frame =
- Frame2d.atPoint point
-
- Frame2d.originPoint frame
- --> point
-
- Frame2d.xDirection frame
- --> Direction2d.x
-
- Frame2d.yDirection frame
- --> Direction2d.y
-
--}
+{-| -}
atPoint : Point2d -> Frame2d
atPoint point =
unsafe
@@ -207,66 +137,31 @@ atPoint point =
}
-{-| Shorthand for `Frame2d.atPoint`;
-
- Frame2d.atCoordinates ( x, y )
-
-is equivalent to
-
- Frame2d.atPoint (Point2d.fromCoordinates ( x, y ))
-
--}
+{-| -}
atCoordinates : ( Float, Float ) -> Frame2d
atCoordinates coordinates =
atPoint (Point2d.fromCoordinates coordinates)
-{-| Get the origin point of a given frame.
-
- Frame2d.originPoint Frame2d.xy
- --> Point2d.origin
-
--}
+{-| -}
originPoint : Frame2d -> Point2d
originPoint (Types.Frame2d frame) =
frame.originPoint
-{-| Get the X direction of a given frame.
-
- Frame2d.xDirection Frame2d.xy
- --> Direction2d.x
-
--}
+{-| -}
xDirection : Frame2d -> Direction2d
xDirection (Types.Frame2d frame) =
frame.xDirection
-{-| Get the Y direction of a given frame.
-
- Frame2d.yDirection Frame2d.xy
- --> Direction2d.y
-
--}
+{-| -}
yDirection : Frame2d -> Direction2d
yDirection (Types.Frame2d frame) =
frame.yDirection
-{-| Check if a frame is [right-handed](https://en.wikipedia.org/wiki/Cartesian_coordinate_system#Orientation_and_handedness).
-
- Frame2d.isRightHanded Frame2d.xy
- --> True
-
- Frame2d.isRightHanded (Frame2d.reverseX Frame2d.xy)
- --> False
-
-All predefined frames are right-handed, and most operations on frames preserve
-handedness, so about the only ways to end up with a left-handed frame are by
-constructing one explicitly with `unsafe` or by mirroring a right-handed frame.
-
--}
+{-| -}
isRightHanded : Frame2d -> Bool
isRightHanded frame =
let
@@ -279,52 +174,19 @@ isRightHanded frame =
Vector2d.crossProduct xVector yVector > 0
-{-| Get the X axis of a given frame (the axis formed from the frame's origin
-point and X direction).
-
- Frame2d.xAxis Frame2d.xy
- --> Axis2d.x
-
--}
+{-| -}
xAxis : Frame2d -> Axis2d
xAxis (Types.Frame2d frame) =
Axis2d.through frame.originPoint frame.xDirection
-{-| Get the Y axis of a given frame (the axis formed from the frame's origin
-point and Y direction).
-
- Frame2d.yAxis Frame2d.xy
- --> Axis2d.y
-
--}
+{-| -}
yAxis : Frame2d -> Axis2d
yAxis (Types.Frame2d frame) =
Axis2d.through frame.originPoint frame.yDirection
-{-| Reverse the X direction of a frame, leaving its Y direction and origin point
-the same.
-
- point =
- Point2d.fromCoordinates ( 2, 3 )
-
- frame =
- Frame2d.atPoint point |> Frame2d.reverseX
-
- Frame2d.originPoint frame
- --> point
-
- Frame2d.xDirection frame
- --> Direction2d.negativeX
-
- Frame2d.yDirection frame
- --> Direction2d.y
-
-Note that this will switch the [handedness](https://en.wikipedia.org/wiki/Cartesian_coordinate_system#Orientation_and_handedness)
-of the frame.
-
--}
+{-| -}
reverseX : Frame2d -> Frame2d
reverseX frame =
unsafe
@@ -334,28 +196,7 @@ reverseX frame =
}
-{-| Reverse the Y direction of a frame, leaving its X direction and origin point
-the same.
-
- point =
- Point2d.fromCoordinates ( 2, 3 )
-
- frame =
- Frame2d.atPoint point |> Frame2d.reverseY
-
- Frame2d.originPoint frame
- --> point
-
- Frame2d.xDirection frame
- --> Direction2d.x
-
- Frame2d.yDirection frame
- --> Direction2d.negativeY
-
-Note that this will switch the [handedness](https://en.wikipedia.org/wiki/Cartesian_coordinate_system#Orientation_and_handedness)
-of the frame.
-
--}
+{-| -}
reverseY : Frame2d -> Frame2d
reverseY frame =
unsafe
@@ -365,15 +206,7 @@ reverseY frame =
}
-{-| Move a frame so that it has the given origin point.
-
- point =
- Point2d.fromCoordinates ( 1, 1 )
-
- Frame2d.xy |> Frame2d.moveTo point
- --> Frame2d.atPoint point
-
--}
+{-| -}
moveTo : Point2d -> Frame2d -> Frame2d
moveTo newOrigin frame =
unsafe
@@ -383,20 +216,7 @@ moveTo newOrigin frame =
}
-{-| Rotate a frame counterclockwise by a given angle around the frame's own
-origin point. The resulting frame will have the same origin point, and its X and
-Y directions will be rotated by the given angle.
-
- rotatedFrame =
- Frame2d.rotateBy (degrees 30) Frame2d.xy
-
- Frame2d.xDirection rotatedFrame
- --> Direction2d.fromAngle (degrees 30)
-
- Frame2d.yDirection rotatedFrame
- --> Direction2d.fromAngle (degrees 120)
-
--}
+{-| -}
rotateBy : Float -> Frame2d -> Frame2d
rotateBy angle frame =
let
@@ -410,25 +230,7 @@ rotateBy angle frame =
}
-{-| Rotate a frame counterclockwise around a given point by a given angle. The
-frame's origin point will be rotated around the given point by the given angle,
-and its X and Y basis directions will be rotated by the given angle.
-
- rotatedFrame =
- Frame2d.atPoint (Point2d.fromCoordinates ( 1, 1 ))
- |> Frame2d.rotateAround Point2d.origin
- (degrees 45)
-
- Frame2d.originPoint rotatedFrame
- --> Point2d.fromCoordinates ( 0, 1.4142 )
-
- Frame2d.xDirection rotatedFrame
- --> Direction2d.fromAngle (degrees 45)
-
- Frame2d.yDirection rotatedFrame
- --> Direction2d.fromAngle (degrees 135)
-
--}
+{-| -}
rotateAround : Point2d -> Float -> Frame2d -> Frame2d
rotateAround centerPoint angle =
let
@@ -446,18 +248,7 @@ rotateAround centerPoint angle =
}
-{-| Translate a frame by a given displacement.
-
- frame =
- Frame2d.atPoint (Point2d.fromCoordinates ( 2, 3 ))
-
- displacement =
- Vector2d.fromComponents ( 1, 1 )
-
- Frame2d.translateBy displacement frame
- --> Frame2d.atPoint (Point2d.fromCoordinates ( 3, 4 ))
-
--}
+{-| -}
translateBy : Vector2d -> Frame2d -> Frame2d
translateBy vector frame =
unsafe
@@ -467,50 +258,13 @@ translateBy vector frame =
}
-{-| Translate a frame in a given direction by a given distance;
-
- Frame2d.translateIn direction distance
-
-is equivalent to
-
- Frame2d.translateBy
- (Vector2d.withLength distance direction)
-
--}
+{-| -}
translateIn : Direction2d -> Float -> Frame2d -> Frame2d
translateIn direction distance frame =
translateBy (Vector2d.withLength distance direction) frame
-{-| Translate a frame along one of its own axes by a given distance.
-
-The first argument is a function that returns the axis to translate along, given
-the current frame. The majority of the time this argument will be either
-`Frame2d.xAxis` or `Frame2d.yAxis`. The second argument is the distance to
-translate along the given axis.
-
-This function is convenient when constructing frames via a series of
-transformations. For example,
-
- frame =
- Frame2d.atPoint (Point2d.fromCoordinates ( 2, 0 ))
- |> Frame2d.rotateBy (degrees 45)
- |> Frame2d.translateAlongOwn Frame2d.xAxis 2
-
-means "construct a frame at the point (2, 0), rotate it around its own origin
-point by 45 degrees, then translate it along its own X axis by 2 units",
-resulting in
-
- Frame2d.originPoint frame
- --> Point2d.fromCoordinates ( 3.4142, 1.4142 )
-
- Frame2d.xDirection frame
- --> Direction2d.fromAngle (degrees 45)
-
- Frame2d.yDirection frame
- --> Direction2d.fromAngle (degrees 135)
-
--}
+{-| -}
translateAlongOwn : (Frame2d -> Axis2d) -> Float -> Frame2d -> Frame2d
translateAlongOwn axis distance frame =
let
@@ -520,27 +274,7 @@ translateAlongOwn axis distance frame =
translateBy displacement frame
-{-| Mirror a frame across an axis.
-
- frame =
- Frame2d.atPoint (Point2d.fromCoordinates ( 2, 3 ))
-
- mirroredFrame =
- Frame2d.mirrorAcross Axis2d.x frame
-
- Frame2d.originPoint mirroredFrame
- --> Point2d.fromCoordinates ( 2, -3 )
-
- Frame2d.xDirection mirroredFrame
- --> Direction2d.x
-
- Frame2d.yDirection mirroredFrame
- --> Direction2d.negativeY
-
-Note that this will switch the [handedness](https://en.wikipedia.org/wiki/Cartesian_coordinate_system#Orientation_and_handedness)
-of the frame.
-
--}
+{-| -}
mirrorAcross : Axis2d -> Frame2d -> Frame2d
mirrorAcross axis =
let
@@ -558,9 +292,7 @@ mirrorAcross axis =
}
-{-| Take two frames defined in global coordinates, and return the second one
-expressed in local coordinates relative to the first.
--}
+{-| -}
relativeTo : Frame2d -> Frame2d -> Frame2d
relativeTo otherFrame =
let
@@ -578,10 +310,7 @@ relativeTo otherFrame =
}
-{-| Take one frame defined in global coordinates and a second frame defined
-in local coordinates relative to the first frame, and return the second frame
-expressed in global coordinates.
--}
+{-| -}
placeIn : Frame2d -> Frame2d -> Frame2d
placeIn otherFrame =
let
diff --git a/src/Frame3d.elm b/src/Frame3d.elm
index aeba5b9c..65cda9a7 100644
--- a/src/Frame3d.elm
+++ b/src/Frame3d.elm
@@ -84,31 +84,7 @@ The `withXDirection`, `withYDirection` and `withZDirection` functions all
construct a new `Frame3d` with the given axis direction, having the given origin
point. The other two directions will be chosen arbitrarily. This can be useful
when constructing 'scratch' frames where (for example) you want a particular Z
-direction but the specific X/Y directions are unimportant:
-
- zDirection =
- Direction3d.fromAzimuthAndElevation
- (degrees 0)
- (degrees 60)
-
- frame =
- Frame3d.withZDirection zDirection Point3d.origin
-
- Frame3d.zDirection frame
- --> Direction3d.fromAzimuthAndElevation
- --> (degrees 0)
- --> (degrees 60)
-
- Frame3d.originPoint frame
- --> Point3d.origin
-
- Frame3d.xDirection frame
- --> Direction3d.fromAzimuthAndElevation
- --> (degrees 0)
- --> (degrees -30)
-
- Frame3d.yDirection frame
- --> Direction3d.y
+direction but the specific X/Y directions are unimportant.
No guarantees are given about the other two directions other than that the three
directions will be mutually perpendicular, and will be oriented so that the
@@ -132,19 +108,7 @@ resulting frame is [right-handed](https://en.wikipedia.org/wiki/Cartesian_coordi
The following functions all return planes with the same origin point as the
given frame, but with varying normal directions. In each case the normal
direction of the resulting plane is given by the cross product of the two
-indicated basis directions (assuming a right-handed frame); for example,
-
- Frame3d.xyPlane Frame3d.xyz
- --> Plane3d.through Point3d.origin
- --> Direction3d.positiveZ
-
-since the cross product of the X and Y basis directions of a frame is equal to
-its Z basis direction. And since reversing the order of arguments in a cross
-product reverses the sign of the result,
-
- Frame3d.yxPlane Frame3d.xyz
- --> Plane3d.through Point3d.origin
- --> Direction3d.negativeZ
+indicated basis directions (assuming a right-handed frame).
@docs xyPlane, yxPlane, yzPlane, zyPlane, zxPlane, xzPlane
@@ -152,24 +116,7 @@ product reverses the sign of the result,
## Sketch planes
These functions all form a `SketchPlane3d` from two axes of the given frame. The
-X and Y axes of the sketch plane will correspond to the two indicated axes. For
-example,
-
- yzSketchPlane =
- Frame3d.yzSketchPlane Frame3d.xyz
-
- SketchPlane3d.originPoint yzSketchPlane
- --> Point3d.origin
-
- SketchPlane3d.xDirection yzSketchPlane
- --> Direction3d.y
-
- SketchPlane3d.yDirection yzSketchPlane
- --> Direction3d.z
-
-Note that this can be confusing - for example, a local X coordinate in the above
-sketch plane corresponds to a global Y coordinate, and a local Y coordinate
-corresponds to a global Z coordinate!
+X and Y axes of the sketch plane will correspond to the two indicated axes.
@docs xySketchPlane, yxSketchPlane, yzSketchPlane, zySketchPlane, zxSketchPlane, xzSketchPlane
@@ -199,28 +146,13 @@ type alias Frame3d =
Types.Frame3d
-{-| The global XYZ frame.
-
- Frame3d.originPoint Frame3d.xyz
- --> Point3d.origin
-
- Frame3d.xDirection Frame3d.xyz
- --> Direction3d.x
-
- Frame3d.yDirection Frame3d.xyz
- --> Direction3d.y
-
- Frame3d.zDirection Frame3d.xyz
- --> Direction3d.z
-
--}
+{-| -}
xyz : Frame3d
xyz =
atPoint Point3d.origin
-{-| Construct a frame with the given origin point and X direction.
--}
+{-| -}
withXDirection : Direction3d -> Point3d -> Frame3d
withXDirection xDirection_ originPoint_ =
let
@@ -235,8 +167,7 @@ withXDirection xDirection_ originPoint_ =
}
-{-| Construct a frame with the given origin point and Y direction.
--}
+{-| -}
withYDirection : Direction3d -> Point3d -> Frame3d
withYDirection yDirection_ originPoint_ =
let
@@ -251,8 +182,7 @@ withYDirection yDirection_ originPoint_ =
}
-{-| Construct a frame with the given origin point and Z direction.
--}
+{-| -}
withZDirection : Direction3d -> Point3d -> Frame3d
withZDirection zDirection_ originPoint_ =
let
@@ -267,55 +197,13 @@ withZDirection zDirection_ originPoint_ =
}
-{-| Construct a frame directly from its origin point and X, Y and Z directions:
-
- frame =
- Frame3d.unsafe
- { originPoint =
- Point3d.fromCoordinates ( 2, 1, 3 )
- , xDirection =
- Direction3d.unsafe ( 0.8, 0.6, 0 )
- , yDirection =
- Direction3d.unsafe ( -0.6, 0.8, 0 )
- , zDirection =
- Direction3d.unsafe ( 0, 0, 1 )
- }
-
-In this case **you must be careful to ensure that the X, Y and Z directions are
-perpendicular**. (You will likely also want to make sure that they form a
-[right-handed](https://en.wikipedia.org/wiki/Cartesian_coordinate_system#Orientation_and_handedness)
-coordinate system.) To construct sets of mutually perpendicular directions,
-[`Direction3d.orthonormalize`](Direction3d#orthonormalize),
-[`Direction3d.orthogonalize`](Direction3d#orthogonalize), or
-[`Direction3d.perpendicularBasis`](Direction3d#perpendicularBasis) may be
-useful.
-
--}
+{-| -}
unsafe : { originPoint : Point3d, xDirection : Direction3d, yDirection : Direction3d, zDirection : Direction3d } -> Frame3d
unsafe =
Types.Frame3d
-{-| Construct a frame aligned with the global XYZ frame but with the given
-origin point.
-
- frame =
- Frame3d.atPoint
- (Point3d.fromCoordinates ( 2, 1, 3 ))
-
- Frame3d.originPoint frame
- --> Point3d.fromCoordinates ( 2, 1, 3 )
-
- Frame3d.xDirection frame
- --> Direction3d.x
-
- Frame3d.yDirection frame
- --> Direction3d.y
-
- Frame3d.zDirection frame
- --> Direction3d.z
-
--}
+{-| -}
atPoint : Point3d -> Frame3d
atPoint point =
unsafe
@@ -326,77 +214,37 @@ atPoint point =
}
-{-| Shorthand for `Frame3d.atPoint`;
-
- Frame3d.atCoordinates ( x, y, z )
-
-is equivalent to
-
- Frame3d.atPoint (Point3d.fromCoordinates ( x, y, z ))
-
--}
+{-| -}
atCoordinates : ( Float, Float, Float ) -> Frame3d
atCoordinates coordinates =
atPoint (Point3d.fromCoordinates coordinates)
-{-| Get the origin point of a given frame.
-
- Frame3d.originPoint Frame3d.xyz
- --> Point3d.origin
-
--}
+{-| -}
originPoint : Frame3d -> Point3d
originPoint (Types.Frame3d properties) =
properties.originPoint
-{-| Get the X direction of a given frame.
-
- Frame3d.xDirection Frame3d.xyz
- --> Direction3d.x
-
--}
+{-| -}
xDirection : Frame3d -> Direction3d
xDirection (Types.Frame3d properties) =
properties.xDirection
-{-| Get the Y direction of a given frame.
-
- Frame3d.yDirection Frame3d.xyz
- --> Direction3d.y
-
--}
+{-| -}
yDirection : Frame3d -> Direction3d
yDirection (Types.Frame3d properties) =
properties.yDirection
-{-| Get the Z direction of a given frame.
-
- Frame3d.zDirection Frame3d.xyz
- --> Direction3d.z
-
--}
+{-| -}
zDirection : Frame3d -> Direction3d
zDirection (Types.Frame3d properties) =
properties.zDirection
-{-| Check if a frame is [right-handed](https://en.wikipedia.org/wiki/Cartesian_coordinate_system#Orientation_and_handedness).
-
- Frame3d.isRightHanded Frame3d.xyz
- --> True
-
- Frame3d.isRightHanded (Frame3d.reverseZ Frame3d.xyz)
- --> False
-
-All predefined frames are right-handed, and most operations on frames preserve
-handedness, so about the only ways to end up with a left-handed frame are by
-constructing one explicitly with `unsafe` or by mirroring a right-handed frame.
-
--}
+{-| -}
isRightHanded : Frame3d -> Bool
isRightHanded frame =
let
@@ -412,86 +260,61 @@ isRightHanded frame =
Vector3d.dotProduct zVector (Vector3d.crossProduct xVector yVector) > 0
-{-| Get the X axis of a given frame (the axis formed from the frame's origin
-point and X direction).
-
- Frame3d.xAxis Frame3d.xyz
- --> Axis3d.x
-
--}
+{-| -}
xAxis : Frame3d -> Axis3d
xAxis (Types.Frame3d frame) =
Axis3d.through frame.originPoint frame.xDirection
-{-| Get the Y axis of a given frame (the axis formed from the frame's origin
-point and Y direction).
-
- Frame3d.yAxis Frame3d.xyz
- --> Axis3d.y
-
--}
+{-| -}
yAxis : Frame3d -> Axis3d
yAxis (Types.Frame3d frame) =
Axis3d.through frame.originPoint frame.yDirection
-{-| Get the Z axis of a given frame (the axis formed from the frame's origin
-point and Z direction).
-
- Frame3d.zAxis Frame3d.xyz
- --> Axis3d.z
-
--}
+{-| -}
zAxis : Frame3d -> Axis3d
zAxis (Types.Frame3d frame) =
Axis3d.through frame.originPoint frame.zDirection
-{-| Get a plane with normal direction equal to the frame's positive Z direction.
--}
+{-| -}
xyPlane : Frame3d -> Plane3d
xyPlane (Types.Frame3d frame) =
Plane3d.through frame.originPoint frame.zDirection
-{-| Get a plane with normal direction equal to the frame's negative Z direction.
--}
+{-| -}
yxPlane : Frame3d -> Plane3d
yxPlane (Types.Frame3d frame) =
Plane3d.through frame.originPoint (Direction3d.reverse frame.zDirection)
-{-| Get a plane with normal direction equal to the frame's positive X direction.
--}
+{-| -}
yzPlane : Frame3d -> Plane3d
yzPlane (Types.Frame3d frame) =
Plane3d.through frame.originPoint frame.xDirection
-{-| Get a plane with normal direction equal to the frame's negative X direction.
--}
+{-| -}
zyPlane : Frame3d -> Plane3d
zyPlane (Types.Frame3d frame) =
Plane3d.through frame.originPoint (Direction3d.reverse frame.xDirection)
-{-| Get a plane with normal direction equal to the frame's positive Y direction.
--}
+{-| -}
zxPlane : Frame3d -> Plane3d
zxPlane (Types.Frame3d frame) =
Plane3d.through frame.originPoint frame.yDirection
-{-| Get a plane with normal direction equal to the frame's negative Y direction.
--}
+{-| -}
xzPlane : Frame3d -> Plane3d
xzPlane (Types.Frame3d frame) =
Plane3d.through frame.originPoint (Direction3d.reverse frame.yDirection)
-{-| Form a sketch plane from the given frame's X and Y axes.
--}
+{-| -}
xySketchPlane : Frame3d -> SketchPlane3d
xySketchPlane frame =
SketchPlane3d.unsafe
@@ -501,8 +324,7 @@ xySketchPlane frame =
}
-{-| Form a sketch plane from the given frame's Y and X axes.
--}
+{-| -}
yxSketchPlane : Frame3d -> SketchPlane3d
yxSketchPlane frame =
SketchPlane3d.unsafe
@@ -512,8 +334,7 @@ yxSketchPlane frame =
}
-{-| Form a sketch plane from the given frame's Y and Z axes.
--}
+{-| -}
yzSketchPlane : Frame3d -> SketchPlane3d
yzSketchPlane frame =
SketchPlane3d.unsafe
@@ -523,8 +344,7 @@ yzSketchPlane frame =
}
-{-| Form a sketch plane from the given frame's Z and Y axes.
--}
+{-| -}
zySketchPlane : Frame3d -> SketchPlane3d
zySketchPlane frame =
SketchPlane3d.unsafe
@@ -534,8 +354,7 @@ zySketchPlane frame =
}
-{-| Form a sketch plane from the given frame's Z and X axes.
--}
+{-| -}
zxSketchPlane : Frame3d -> SketchPlane3d
zxSketchPlane frame =
SketchPlane3d.unsafe
@@ -545,8 +364,7 @@ zxSketchPlane frame =
}
-{-| Form a sketch plane from the given frame's X and Z axes.
--}
+{-| -}
xzSketchPlane : Frame3d -> SketchPlane3d
xzSketchPlane frame =
SketchPlane3d.unsafe
@@ -556,15 +374,7 @@ xzSketchPlane frame =
}
-{-| Reverse the X direction of a frame.
-
- Frame3d.xDirection (Frame3d.reverseX Frame3d.xyz)
- --> Direction3d.negativeX
-
-Note that this will switch the [handedness](https://en.wikipedia.org/wiki/Cartesian_coordinate_system#Orientation_and_handedness)
-of the frame.
-
--}
+{-| -}
reverseX : Frame3d -> Frame3d
reverseX frame =
unsafe
@@ -575,15 +385,7 @@ reverseX frame =
}
-{-| Reverse the Y direction of a frame.
-
- Frame3d.yDirection (Frame3d.reverseY Frame3d.xyz)
- --> Direction3d.negativeY
-
-Note that this will switch the [handedness](https://en.wikipedia.org/wiki/Cartesian_coordinate_system#Orientation_and_handedness)
-of the frame.
-
--}
+{-| -}
reverseY : Frame3d -> Frame3d
reverseY frame =
unsafe
@@ -594,15 +396,7 @@ reverseY frame =
}
-{-| Reverse the Z direction of a frame.
-
- Frame3d.zDirection (Frame3d.reverseZ Frame3d.xyz)
- --> Direction3d.negativeZ
-
-Note that this will switch the [handedness](https://en.wikipedia.org/wiki/Cartesian_coordinate_system#Orientation_and_handedness)
-of the frame.
-
--}
+{-| -}
reverseZ : Frame3d -> Frame3d
reverseZ frame =
unsafe
@@ -613,16 +407,7 @@ reverseZ frame =
}
-{-| Move a frame so that it has the given origin point but unchanged
-orientation.
-
- point =
- Point3d.fromCoordinates ( 2, 1, 3 )
-
- Frame3d.moveTo point Frame3d.xyz
- --> Frame3d.atPoint point
-
--}
+{-| -}
moveTo : Point3d -> Frame3d -> Frame3d
moveTo newOrigin frame =
unsafe
@@ -633,29 +418,7 @@ moveTo newOrigin frame =
}
-{-| Rotate a frame around an axis by a given angle (in radians). The frame's
-origin point and basis directions will all be rotated around the given axis.
-
- frame =
- Frame3d.atPoint
- (Point3d.fromCoordinates ( 2, 1, 3 ))
-
- rotatedFrame =
- Frame3d.rotateAround Axis3d.z (degrees 90) frame
-
- Frame3d.originPoint rotatedFrame
- --> Point3d.fromCoordinates ( -1, 2, 3 )
-
- Frame3d.xDirection rotatedFrame
- --> Direction3d.y
-
- Frame3d.yDirection rotatedFrame
- --> Direction3d.negativeX
-
- Frame3d.zDirection rotatedFrame
- --> Direction3d.z
-
--}
+{-| -}
rotateAround : Axis3d -> Float -> Frame3d -> Frame3d
rotateAround axis angle =
let
@@ -674,62 +437,13 @@ rotateAround axis angle =
}
-{-| Rotate a frame around one of its own axes by a given angle (in radians).
-
-The first argument is a function that returns the axis to rotate around, given
-the current frame. The majority of the time this will be either `Frame3d.xAxis`,
-`Frame3d.yAxis` or `Frame3d.zAxis`. Compare the following to the above example
-for `rotateAround`:
-
- frame =
- Frame3d.atPoint
- (Point3d.fromCoordinates ( 2, 1, 3 ))
-
- rotatedFrame =
- frame
- |> Frame3d.rotateAroundOwn Frame3d.zAxis
- (degrees 90)
-
- Frame3d.originPoint rotatedFrame
- --> Point3d.fromCoordinates ( 2, 1, 3 )
-
- Frame3d.xDirection rotatedFrame
- --> Direction3d.y
-
- Frame3d.yDirection rotatedFrame
- --> Direction3d.negativeX
-
- Frame3d.zDirection rotatedFrame
- --> Direction3d.z
-
-Since the rotation is done around the frame's own Z axis (which passes through
-the frame's origin point), the origin point remains the same after rotation.
-
-In this example the frame's Z axis has the same orientation as the global Z axis
-so the frame's basis directions are rotated the same way, but in more complex
-examples involving rotated frames a rotation around (for example) the frame's
-own Z axis may be completely different from a rotation around the global Z axis.
-
--}
+{-| -}
rotateAroundOwn : (Frame3d -> Axis3d) -> Float -> Frame3d -> Frame3d
rotateAroundOwn axis angle frame =
rotateAround (axis frame) angle frame
-{-| Translate a frame by a given displacement.
-
- frame =
- Frame3d.atPoint
- (Point3d.fromCoordinates ( 2, 1, 3 ))
-
- displacement =
- Vector3d.fromComponents ( 1, 1, 1 )
-
- Frame3d.translateBy displacement frame
- --> Frame3d.atPoint
- --> (Point3d.fromCoordinates ( 3, 2, 4 ))
-
--}
+{-| -}
translateBy : Vector3d -> Frame3d -> Frame3d
translateBy vector frame =
unsafe
@@ -740,60 +454,13 @@ translateBy vector frame =
}
-{-| Translate a frame in a given direction by a given distance;
-
- Frame3d.translateIn direction distance
-
-is equivalent to
-
- Frame3d.translateBy
- (Vector3d.withLength distance direction)
-
--}
+{-| -}
translateIn : Direction3d -> Float -> Frame3d -> Frame3d
translateIn direction distance frame =
translateBy (Vector3d.withLength distance direction) frame
-{-| Translate a frame along one of its own axes by a given distance.
-
-The first argument is a function that returns the axis to translate along, given
-the current frame. The majority of the time this will be either `Frame3d.xAxis`,
-`Frame3d.yAxis` or `Frame3d.zAxis`.
-
-This function is convenient when constructing frames via a series of
-transformations. For example,
-
- point =
- Point3d.fromCoordinates ( 2, 0, 0 )
-
- frame =
- Frame3d.atPoint point
- |> Frame3d.rotateAroundOwn Frame3d.zAxis
- (degrees 45)
- |> Frame3d.translateAlongOwn Frame3d.xAxis 2
-
-means "construct a frame at the point (2, 0, 0), rotate it around its own Z axis
-counterclockwise by 45 degrees, then translate it along its own (rotated) X axis
-by 2 units", resulting in
-
- Frame3d.originPoint frame
- --> Point3d.fromCoordinates ( 3.4142, 1.4142, 0 )
-
- Frame3d.xDirection frame
- --> Direction3d.fromAzimuthAndElevation
- --> (degrees 45)
- --> (degrees 0)
-
- Frame3d.yDirection frame
- --> Direction3d.fromAzimuthAndElevation
- --> (degrees 135)
- --> (degrees 0)
-
- Frame3d.zDirection frame
- --> Direction3d.z
-
--}
+{-| -}
translateAlongOwn : (Frame3d -> Axis3d) -> Float -> Frame3d -> Frame3d
translateAlongOwn axis distance frame =
let
@@ -803,31 +470,7 @@ translateAlongOwn axis distance frame =
translateBy displacement frame
-{-| Mirror a frame across a plane.
-
- frame =
- Frame3d.atPoint
- (Point3d.fromCoordinates ( 2, 1, 3 ))
-
- mirroredFrame =
- Frame3d.mirrorAcross Plane3d.xy frame
-
- Frame3d.originPoint mirroredFrame
- --> Point3d.fromCoordinates ( 2, 1, -3 )
-
- Frame3d.xDirection mirroredFrame
- --> Direction3d.x
-
- Frame3d.yDirection mirroredFrame
- --> Direction3d.y
-
- Frame3d.zDirection mirroredFrame
- --> Direction3d.negativeZ
-
-Note that this will switch the [handedness](https://en.wikipedia.org/wiki/Cartesian_coordinate_system#Orientation_and_handedness)
-of the frame.
-
--}
+{-| -}
mirrorAcross : Plane3d -> Frame3d -> Frame3d
mirrorAcross plane =
let
@@ -846,9 +489,7 @@ mirrorAcross plane =
}
-{-| Take two frames defined in global coordinates, and return the second one
-expressed in local coordinates relative to the first.
--}
+{-| -}
relativeTo : Frame3d -> Frame3d -> Frame3d
relativeTo otherFrame =
let
@@ -867,10 +508,7 @@ relativeTo otherFrame =
}
-{-| Take one frame defined in global coordinates and a second frame defined
-in local coordinates relative to the first frame, and return the second frame
-expressed in global coordinates.
--}
+{-| -}
placeIn : Frame3d -> Frame3d -> Frame3d
placeIn otherFrame =
let
diff --git a/src/Geometry/Examples/Expect.elm b/src/Geometry/Examples/Expect.elm
index 40ece1c6..a788a221 100644
--- a/src/Geometry/Examples/Expect.elm
+++ b/src/Geometry/Examples/Expect.elm
@@ -7,13 +7,7 @@ import Result
import String
-{-| This is a very hacky function to compare arbitrary types and the numbers in them with a certain precision.
-In order to achieve this all numbers in the string representation of the two objects are truncated and then the
-resulting strings are compared.
-
- It should never be used.
-
--}
+{-| -}
equalWithinTolerance : a -> a -> Expectation
equalWithinTolerance a b =
let
diff --git a/src/LineSegment2d.elm b/src/LineSegment2d.elm
index 3cb036da..7ab92bd4 100644
--- a/src/LineSegment2d.elm
+++ b/src/LineSegment2d.elm
@@ -83,9 +83,6 @@ points and forming a new line segment between the resulting points.
# Coordinate conversions
-Functions for transforming line segments between local and global coordinates in
-different coordinate frames.
-
@docs relativeTo, placeIn
-}
@@ -104,97 +101,43 @@ type alias LineSegment2d =
Types.LineSegment2d
-{-| Construct a line segment from its two endpoints:
-
- exampleLineSegment =
- LineSegment2d.fromEndpoints
- ( Point2d.fromCoordinates ( 1, 2 )
- , Point2d.fromCoordinates ( 3, 4 )
- )
-
--}
+{-| -}
fromEndpoints : ( Point2d, Point2d ) -> LineSegment2d
fromEndpoints =
Types.LineSegment2d
-{-| Construct a line segment from the first point to the second;
-
- LineSegment2d.from firstPoint secondPoint
-
-is equivalent to
-
- LineSegment2d.fromEndpoints ( firstPoint, secondPoint )
-
--}
+{-| -}
from : Point2d -> Point2d -> LineSegment2d
from startPoint_ endPoint_ =
fromEndpoints ( startPoint_, endPoint_ )
-{-| Construct a line segment lying on the given axis, with its endpoints at the
-given distances from the axis' origin point.
-
- LineSegment2d.along Axis2d.x 3 5
- --> LineSegment2d.fromEndpoints
- --> ( Point2d.fromCoordinates ( 3, 0 )
- --> , Point2d.fromCoordinates ( 5, 0 )
- --> )
-
- LineSegment2d.along Axis2d.y 2 -4
- --> LineSegment2d.fromEndpoints
- --> ( Point2d.fromCoordinates ( 0, 2 )
- --> , Point2d.fromCoordinates ( 0, -4 )
- --> )
-
--}
+{-| -}
along : Axis2d -> Float -> Float -> LineSegment2d
along axis start end =
fromEndpoints ( Point2d.along axis start, Point2d.along axis end )
-{-| Get the start point of a line segment.
-
- LineSegment2d.startPoint exampleLineSegment
- --> Point2d.fromCoordinates ( 1, 2 )
-
--}
+{-| -}
startPoint : LineSegment2d -> Point2d
startPoint (Types.LineSegment2d ( start, _ )) =
start
-{-| Get the end point of a line segment.
-
- LineSegment2d.endPoint exampleLineSegment
- --> Point2d.fromCoordinates ( 3, 4 )
-
--}
+{-| -}
endPoint : LineSegment2d -> Point2d
endPoint (Types.LineSegment2d ( _, end )) =
end
-{-| Get the endpoints of a line segment as a tuple.
-
- ( p1, p2 ) =
- LineSegment2d.endpoints lineSegment
-
--}
+{-| -}
endpoints : LineSegment2d -> ( Point2d, Point2d )
endpoints (Types.LineSegment2d endpoints_) =
endpoints_
-{-| Reverse a line segment, swapping its start and end points.
-
- LineSegment2d.reverse exampleLineSegment
- --> LineSegment2d.fromEndpoints
- --> ( Point2d.fromCoordinates ( 3, 4 )
- --> , Point2d.fromCoordinates ( 1, 2 )
- --> )
-
--}
+{-| -}
reverse : LineSegment2d -> LineSegment2d
reverse lineSegment =
let
@@ -204,29 +147,13 @@ reverse lineSegment =
fromEndpoints ( p2, p1 )
-{-| Get the midpoint of a line segment.
-
- LineSegment2d.midpoint exampleLineSegment
- --> Point2d.fromCoordinates ( 2, 3 )
-
--}
+{-| -}
midpoint : LineSegment2d -> Point2d
midpoint lineSegment =
interpolate lineSegment 0.5
-{-| Interpolate a line segment between its start and end points; a value of 0.0
-corresponds to the start point of the line segment, a value of 0.5 corresponds
-to its midpoint and a value of 1.0 corresponds to its end point. Values less
-than 0.0 or greater than 1.0 can be used to extrapolate.
-
- LineSegment2d.interpolate exampleLineSegment 0.25
- --> Point2d.fromCoordinates ( 1.5, 2.5 )
-
- LineSegment2d.interpolate exampleLineSegment 1.5
- --> Point2d.fromCoordinates ( 4, 5 )
-
--}
+{-| -}
interpolate : LineSegment2d -> Float -> Point2d
interpolate lineSegment =
let
@@ -236,60 +163,31 @@ interpolate lineSegment =
Point2d.interpolateFrom start end
-{-| Get the length of a line segment.
-
- LineSegment2d.length exampleLineSegment
- --> 2.8284
-
--}
+{-| -}
length : LineSegment2d -> Float
length =
vector >> Vector2d.length
-{-| Get the squared length of a line segment. Slightly more efficient than
-`length` since it avoids a square root.
-
- LineSegment2d.squaredLength exampleLineSegment
- --> 8
-
--}
+{-| -}
squaredLength : LineSegment2d -> Float
squaredLength =
vector >> Vector2d.squaredLength
-{-| Get the direction from a line segment's start point to its end point. If the
-line segment has zero length (the start and end points are the same), returns
-`Nothing`.
-
- LineSegment2d.direction exampleLineSegment
- --> Just (Direction2d.fromAngle (degrees 45))
-
--}
+{-| -}
direction : LineSegment2d -> Maybe Direction2d
direction =
vector >> Vector2d.direction
-{-| Get the direction perpendicular to a line segment, pointing to the left. If
-the line segment has zero length, returns `Nothing`.
-
- LineSegment2d.perpendicularDirection exampleLineSegment
- --> Just (Direction2d.fromAngle (degrees 135))
-
--}
+{-| -}
perpendicularDirection : LineSegment2d -> Maybe Direction2d
perpendicularDirection =
vector >> Vector2d.perpendicularTo >> Vector2d.direction
-{-| Get the vector from a given line segment's start point to its end point.
-
- LineSegment2d.vector exampleLineSegment
- --> Vector2d.fromComponents ( 2, 2 )
-
--}
+{-| -}
vector : LineSegment2d -> Vector2d
vector lineSegment =
let
@@ -299,54 +197,7 @@ vector lineSegment =
Vector2d.from p1 p2
-{-| Attempt to find the unique intersection point of two line segments. If there
-is no such point (the two line segments do not touch, or they overlap), returns
-`Nothing`.
-
- -- 4 corners of a square
-
- a =
- Point2d.fromCoordinates ( 0, 0 )
-
- b =
- Point2d.fromCoordinates ( 1, 0 )
-
- c =
- Point2d.fromCoordinates ( 1, 1 )
-
- d =
- Point2d.fromCoordinates ( 0, 1 )
-
- -- definition of some segments with those points
-
- ab =
- LineSegment2d.from a b
- ...
-
- -- searching for intersections
-
- LineSegment2d.intersectionPoint ab bc
- --> Just (Point2d.fromCoordinates ( 1, 0 ))
- -- corner point b
-
- LineSegment2d.intersectionPoint ac bd
- --> Just (Point2d.fromCoordinates ( 0.5, 0.5 ))
- -- diagonal crossing at square center
-
- LineSegment2d.intersectionPoint ab cd
- --> Nothing -- parallel lines
-
- LineSegment2d.intersectionPoint ab ab
- --> Nothing -- collinear lines
-
-Note that if the endpoint of one line segment lies on the other line segment,
-numerical roundoff means that the intersection may or may not be found. If two
-segments have a shared endpoint (the two segments meet in something like a 'V',
-where the end point of one segment is the start point of the next), that point
-is guaranteed to be returned as the intersection point, but if two segments meet
-in a 'T' shape the intersection point may or may not be found.
-
--}
+{-| -}
intersectionPoint : LineSegment2d -> LineSegment2d -> Maybe Point2d
intersectionPoint lineSegment1 lineSegment2 =
-- The two line segments are:
@@ -439,124 +290,43 @@ intersectionPoint lineSegment1 lineSegment2 =
Nothing
-{-| Scale a line segment about the given center point by the given scale.
-
- point =
- Point2d.fromCoordinates ( 1, 1 )
-
- LineSegment2d.scaleAbout point 2 exampleLineSegment
- --> LineSegment2d.fromEndpoints
- --> ( Point2d.fromCoordinates ( 1, 3 )
- --> , Point2d.fromCoordinates ( 5, 7 )
- --> )
-
--}
+{-| -}
scaleAbout : Point2d -> Float -> LineSegment2d -> LineSegment2d
scaleAbout point scale =
mapEndpoints (Point2d.scaleAbout point scale)
-{-| Rotate a line segment counterclockwise around a given center point by a
-given angle (in radians).
-
- exampleLineSegment
- |> LineSegment2d.rotateAround Point2d.origin
- (degrees 90)
- --> LineSegment2d.fromEndpoints
- --> ( Point2d.fromCoordinates ( -2, 1 )
- --> , Point2d.fromCoordinates ( -4, 3 )
- --> )
-
--}
+{-| -}
rotateAround : Point2d -> Float -> LineSegment2d -> LineSegment2d
rotateAround centerPoint angle =
mapEndpoints (Point2d.rotateAround centerPoint angle)
-{-| Translate a line segment by a given displacement.
-
- displacement =
- Vector2d.fromComponents ( 1, 2 )
-
- exampleLineSegment
- |> LineSegment2d.translateBy displacement
- --> LineSegment2d.fromEndpoints
- --> ( Point2d.fromCoordinates ( 2, 4 )
- --> , Point2d.fromCoordinates ( 4, 6 )
- --> )
-
--}
+{-| -}
translateBy : Vector2d -> LineSegment2d -> LineSegment2d
translateBy displacementVector =
mapEndpoints (Point2d.translateBy displacementVector)
-{-| Translate a line segment in a given direction by a given distance;
-
- LineSegment2d.translateIn direction distance
-
-is equivalent to
-
- LineSegment2d.translateBy
- (Vector2d.withLength distance direction)
-
--}
+{-| -}
translateIn : Direction2d -> Float -> LineSegment2d -> LineSegment2d
translateIn translationDirection distance lineSegment =
translateBy (Vector2d.withLength distance translationDirection) lineSegment
-{-| Mirror a line segment across an axis.
-
- LineSegment2d.mirrorAcross Axis2d.y exampleLineSegment
- --> LineSegment2d.fromEndpoints
- --> ( Point2d.fromCoordinates ( -1, 2 )
- --> , Point2d.fromCoordinates ( -3, 4 )
- --> )
-
-Note that the endpoints of a mirrored segment are equal to the mirrored
-endpoints of the original segment, but as a result the normal direction of a
-mirrored segment is the _opposite_ of the mirrored normal direction of the
-original segment (since the normal direction is always considered to be 'to the
-left' of the line segment).
-
--}
+{-| -}
mirrorAcross : Axis2d -> LineSegment2d -> LineSegment2d
mirrorAcross axis =
mapEndpoints (Point2d.mirrorAcross axis)
-{-| Project a line segment onto an axis.
-
- LineSegment2d.projectOnto Axis2d.x exampleLineSegment
- --> LineSegment2d.fromEndpoints
- --> ( Point2d.fromCoordinates ( 1, 0 )
- --> , Point2d.fromCoordinates ( 3, 0 )
- --> )
-
- LineSegment2d.projectOnto Axis2d.y exampleLineSegment
- --> LineSegment2d.fromEndpoints
- --> ( Point2d.fromCoordinates ( 0, 2 )
- --> , Point2d.fromCoordinates ( 0, 4 )
- --> )
-
--}
+{-| -}
projectOnto : Axis2d -> LineSegment2d -> LineSegment2d
projectOnto axis =
mapEndpoints (Point2d.projectOnto axis)
-{-| Transform the start and end points of a line segment by a given function
-and create a new line segment from the resulting points. Most other
-transformation functions can be defined in terms of `mapEndpoints`; for example,
-
- LineSegment2d.projectOnto axis
-
-is equivalent to
-
- LineSegment2d.mapEndpoints (Point2d.projectOnto axis)
-
--}
+{-| -}
mapEndpoints : (Point2d -> Point2d) -> LineSegment2d -> LineSegment2d
mapEndpoints function lineSegment =
let
@@ -566,54 +336,19 @@ mapEndpoints function lineSegment =
fromEndpoints ( function p1, function p2 )
-{-| Take a line segment defined in global coordinates, and return it expressed
-in local coordinates relative to a given reference frame.
-
- localFrame =
- Frame2d.atPoint (Point2d.fromCoordinates ( 1, 2 ))
-
- LineSegment2d.relativeTo localFrame exampleLineSegment
- --> LineSegment2d.fromEndpoints
- --> ( Point2d.fromCoordinates ( 0, 0 )
- --> , Point2d.fromCoordinates ( 2, 2 )
- --> )
-
--}
+{-| -}
relativeTo : Frame2d -> LineSegment2d -> LineSegment2d
relativeTo frame =
mapEndpoints (Point2d.relativeTo frame)
-{-| Take a line segment considered to be defined in local coordinates relative
-to a given reference frame, and return that line segment expressed in global
-coordinates.
-
- localFrame =
- Frame2d.atPoint (Point2d.fromCoordinates ( 1, 2 ))
-
- LineSegment2d.placeIn localFrame exampleLineSegment
- --> LineSegment2d.fromEndpoints
- --> ( Point2d.fromCoordinates ( 2, 4 )
- --> , Point2d.fromCoordinates ( 4, 6 )
- --> )
-
--}
+{-| -}
placeIn : Frame2d -> LineSegment2d -> LineSegment2d
placeIn frame =
mapEndpoints (Point2d.placeIn frame)
-{-| Get the minimal bounding box containing a given line segment.
-
- LineSegment2d.boundingBox exampleLineSegment
- --> BoundingBox2d.fromExtrema
- --> { minX = 1
- --> , maxX = 3
- --> , minY = 2
- --> , maxY = 4
- --> }
-
--}
+{-| -}
boundingBox : LineSegment2d -> BoundingBox2d
boundingBox lineSegment =
let
diff --git a/src/LineSegment3d.elm b/src/LineSegment3d.elm
index 517175ee..c013cf05 100644
--- a/src/LineSegment3d.elm
+++ b/src/LineSegment3d.elm
@@ -79,9 +79,6 @@ points and forming a new line segment between the resulting points.
# Coordinate conversions
-Functions for transforming line segments between local and global coordinates in
-different coordinate frames.
-
@docs relativeTo, placeIn, projectInto
-}
@@ -103,69 +100,25 @@ type alias LineSegment3d =
Types.LineSegment3d
-{-| Construct a line segment from its two endpoints:
-
- exampleLineSegment =
- LineSegment3d.fromEndpoints
- ( Point3d.fromCoordinates ( 1, 2, 3 )
- , Point3d.fromCoordinates ( 4, 5, 6 )
- )
-
--}
+{-| -}
fromEndpoints : ( Point3d, Point3d ) -> LineSegment3d
fromEndpoints =
Types.LineSegment3d
-{-| Construct a line segment from the first point to the second;
-
- LineSegment3d.from firstPoint secondPoint
-
-is equivalent to
-
- LineSegment3d.fromEndpoints ( firstPoint, secondPoint )
-
--}
+{-| -}
from : Point3d -> Point3d -> LineSegment3d
from startPoint_ endPoint_ =
fromEndpoints ( startPoint_, endPoint_ )
-{-| Construct a line segment lying on the given axis, with its endpoints at the
-given distances from the axis' origin point.
-
- LineSegment3d.along Axis3d.x 3 5
- --> LineSegment3d.fromEndpoints
- --> ( Point3d.fromCoordinates ( 3, 0, 0 )
- --> , Point3d.fromCoordinates ( 5, 0, 0 )
- --> )
-
- LineSegment3d.along Axis3d.y 2 -4
- --> LineSegment3d.fromEndpoints
- --> ( Point3d.fromCoordinates ( 0, 2, 0 )
- --> , Point3d.fromCoordinates ( 0, -4, 0 )
- --> )
-
--}
+{-| -}
along : Axis3d -> Float -> Float -> LineSegment3d
along axis start end =
fromEndpoints ( Point3d.along axis start, Point3d.along axis end )
-{-| Construct a 3D line segment lying _on_ a sketch plane by providing a 2D line
-segment specified in XY coordinates _within_ the sketch plane.
-
- LineSegment3d.on SketchPlane3d.yz <|
- LineSegment2d.fromEndpoints
- ( Point2d.fromCoordinates ( 1, 2 )
- , Point2d.fromCoordinates ( 3, 4 )
- )
- --> LineSegment3d.fromEndpoints
- --> ( Point3d.fromCoordinates ( 0, 1, 2 )
- --> , Point3d.fromCoordinates ( 0, 3, 4 )
- --> )
-
--}
+{-| -}
on : SketchPlane3d -> LineSegment2d -> LineSegment3d
on sketchPlane lineSegment2d =
let
@@ -178,48 +131,25 @@ on sketchPlane lineSegment2d =
)
-{-| Get the start point of a line segment.
-
- LineSegment3d.startPoint exampleLineSegment
- --> Point3d.fromCoordinates ( 1, 2, 3 )
-
--}
+{-| -}
startPoint : LineSegment3d -> Point3d
startPoint (Types.LineSegment3d ( start, _ )) =
start
-{-| Get the end point of a line segment.
-
- LineSegment3d.endPoint exampleLineSegment
- --> Point3d.fromCoordinates ( 4, 5, 6 )
-
--}
+{-| -}
endPoint : LineSegment3d -> Point3d
endPoint (Types.LineSegment3d ( _, end )) =
end
-{-| Get the endpoints of a line segment as a tuple.
-
- ( p1, p2 ) =
- LineSegment3d.endpoints lineSegment
-
--}
+{-| -}
endpoints : LineSegment3d -> ( Point3d, Point3d )
endpoints (Types.LineSegment3d endpoints_) =
endpoints_
-{-| Reverse a line segment, swapping its start and end points.
-
- LineSegment3d.reverse exampleLineSegment
- --> LineSegment3d.fromEndpoints
- --> ( Point3d.fromCoordinates ( 4, 5, 6 )
- --> , Point3d.fromCoordinates ( 1, 2, 3 )
- --> )
-
--}
+{-| -}
reverse : LineSegment3d -> LineSegment3d
reverse lineSegment =
let
@@ -229,29 +159,13 @@ reverse lineSegment =
fromEndpoints ( p2, p1 )
-{-| Get the midpoint of a line segment.
-
- LineSegment3d.midpoint exampleLineSegment
- --> Point3d.fromCoordinates ( 2.5, 3.5, 4.5 )
-
--}
+{-| -}
midpoint : LineSegment3d -> Point3d
midpoint lineSegment =
interpolate lineSegment 0.5
-{-| Interpolate a line segment between its start and end points; a value of 0.0
-corresponds to the start point of the line segment, a value of 0.5 corresponds
-to its midpoint and a value of 1.0 corresponds to its end point. Values less
-than 0.0 or greater than 1.0 can be used to extrapolate.
-
- LineSegment3d.interpolate exampleLineSegment (1 / 3)
- --> Point3d.fromCoordinates ( 2, 4, 5 )
-
- LineSegment3d.interpolate exampleLineSegment (-1 / 3)
- --> Point3d.fromCoordinates ( 0, 1, 2 )
-
--}
+{-| -}
interpolate : LineSegment3d -> Float -> Point3d
interpolate lineSegment =
let
@@ -261,68 +175,31 @@ interpolate lineSegment =
Point3d.interpolateFrom start end
-{-| Get the length of a line segment.
-
- LineSegment3d.length exampleLineSegment
- --> 5.1962
-
--}
+{-| -}
length : LineSegment3d -> Float
length =
vector >> Vector3d.length
-{-| Get the squared length of a line segment. Slightly more efficient than
-`length` since it avoids a square root.
-
- LineSegment3d.squaredLength exampleLineSegment
- --> 27
-
--}
+{-| -}
squaredLength : LineSegment3d -> Float
squaredLength =
vector >> Vector3d.squaredLength
-{-| Get the direction from a line segment's start point to its end point. If the
-line segment has zero length (the start and end points are the same), returns
-`Nothing`.
-
- LineSegment3d.direction exampleLineSegment
- --> Just
- --> (Direction3d.fromAzimuthAndElevation
- --> (degrees 45)
- --> (degrees 35.26)
- --> )
-
--}
+{-| -}
direction : LineSegment3d -> Maybe Direction3d
direction =
vector >> Vector3d.direction
-{-| Get an arbitrary direction perpendicular to a line segment. If the line
-segment has zero length, returns `Nothing`.
-
- LineSegment3d.perpendicularDirection exampleLineSegment
- --> Just
- --> (Direction3d.fromAzimuthAndElevation
- --> (degrees -90)
- --> (degrees 45)
- --> )
-
--}
+{-| -}
perpendicularDirection : LineSegment3d -> Maybe Direction3d
perpendicularDirection =
vector >> Vector3d.perpendicularTo >> Vector3d.direction
-{-| Get the vector from a line segment's start point to its end point.
-
- LineSegment3d.vector exampleLineSegment
- --> Vector3d.fromComponents ( 2, 2, 2 )
-
--}
+{-| -}
vector : LineSegment3d -> Vector3d
vector lineSegment =
let
@@ -332,112 +209,43 @@ vector lineSegment =
Vector3d.from p1 p2
-{-| Scale a line segment about the given center point by the given scale.
-
- point =
- Point3d.fromCoordinates ( 1, 1, 1 )
-
- LineSegment3d.scaleAbout point 2 exampleLineSegment
- --> LineSegment3d.fromEndpoints
- --> ( Point3d.fromCoordinates ( 1, 3, 5 )
- --> , Point3d.fromCoordinates ( 7, 9, 11 )
- --> )
-
--}
+{-| -}
scaleAbout : Point3d -> Float -> LineSegment3d -> LineSegment3d
scaleAbout point scale =
mapEndpoints (Point3d.scaleAbout point scale)
-{-| Rotate a line segment around a given axis by a given angle (in radians).
-
- exampleLineSegment
- |> LineSegment3d.rotateAround Axis3d.z (degrees 90)
- --> LineSegment3d.fromEndpoints
- --> ( Point3d.fromCoordinates ( -2, 1, 3 )
- --> , Point3d.fromCoordinates ( -5, 4, 6 )
- --> )
-
--}
+{-| -}
rotateAround : Axis3d -> Float -> LineSegment3d -> LineSegment3d
rotateAround axis angle =
mapEndpoints (Point3d.rotateAround axis angle)
-{-| Translate a line segment by a given displacement.
-
- displacement =
- Vector3d.fromComponents ( 1, 2, 3 )
-
- exampleLineSegment
- |> LineSegment3d.translateBy displacement
- --> LineSegment3d.fromEndpoints
- --> ( Point3d.fromCoordinates ( 2, 4, 6 )
- --> , Point3d.fromCoordinates ( 5, 7, 9 )
- --> )
-
--}
+{-| -}
translateBy : Vector3d -> LineSegment3d -> LineSegment3d
translateBy displacementVector =
mapEndpoints (Point3d.translateBy displacementVector)
-{-| Translate a line segment in a given direction by a given distance;
-
- LineSegment3d.translateIn direction distance
-
-is equivalent to
-
- LineSegment3d.translateBy
- (Vector3d.withLength distance direction)
-
--}
+{-| -}
translateIn : Direction3d -> Float -> LineSegment3d -> LineSegment3d
translateIn translationDirection distance lineSegment =
translateBy (Vector3d.withLength distance translationDirection) lineSegment
-{-| Mirror a line segment across a plane.
-
- exampleLineSegment
- |> LineSegment3d.mirrorAcross Plane3d.xy
- --> LineSegment3d.fromEndpoints
- --> ( Point3d.fromCoordinates ( 1, 2, -3 )
- --> , Point3d.fromCoordinates ( 4, 5, -6 )
- --> )
-
--}
+{-| -}
mirrorAcross : Plane3d -> LineSegment3d -> LineSegment3d
mirrorAcross plane =
mapEndpoints (Point3d.mirrorAcross plane)
-{-| Find the [orthographic projection](https://en.wikipedia.org/wiki/Orthographic_projection)
-of a line segment onto a plane.
-
- LineSegment3d.projectOnto Plane3d.yz exampleLineSegment
- --> LineSegment3d.fromEndpoints
- --> ( Point3d.fromCoordinates ( 0, 2, 3 )
- --> , Point3d.fromCoordinates ( 0, 5, 6 )
- --> )
-
--}
+{-| -}
projectOnto : Plane3d -> LineSegment3d -> LineSegment3d
projectOnto plane =
mapEndpoints (Point3d.projectOnto plane)
-{-| Transform the start and end points of a line segment by a given function
-and create a new line segment from the resulting points. Most other
-transformation functions can be defined in terms of `mapEndpoints`; for example,
-
- LineSegment3d.projectOnto plane
-
-is equivalent to
-
- LineSegment3d.mapEndpoints (Point3d.projectOnto plane)
-
--}
+{-| -}
mapEndpoints : (Point3d -> Point3d) -> LineSegment3d -> LineSegment3d
mapEndpoints function lineSegment =
let
@@ -447,72 +255,19 @@ mapEndpoints function lineSegment =
fromEndpoints ( function p1, function p2 )
-{-| Take a line segment defined in global coordinates, and return it expressed
-in local coordinates relative to a given reference frame.
-
- localFrame =
- Frame3d.atPoint
- (Point3d.fromCoordinates ( 1, 2, 3 ))
-
- LineSegment3d.relativeTo localFrame exampleLineSegment
- --> LineSegment3d.fromEndpoints
- --> ( Point3d.fromCoordinates ( 0, 0, 0 )
- --> , Point3d.fromCoordinates ( 3, 3, 3 )
- --> )
-
--}
+{-| -}
relativeTo : Frame3d -> LineSegment3d -> LineSegment3d
relativeTo frame =
mapEndpoints (Point3d.relativeTo frame)
-{-| Take a line segment considered to be defined in local coordinates relative
-to a given reference frame, and return that line segment expressed in global
-coordinates.
-
- localFrame =
- Frame3d.atPoint
- (Point3d.fromCoordinates ( 1, 2, 3 ))
-
- LineSegment3d.placeIn localFrame exampleLineSegment
- --> LineSegment3d.fromEndpoints
- --> ( Point3d.fromCoordinates ( 2, 4, 6 )
- --> , Point3d.fromCoordinates ( 5, 7, 9 )
- --> )
-
--}
+{-| -}
placeIn : Frame3d -> LineSegment3d -> LineSegment3d
placeIn frame =
mapEndpoints (Point3d.placeIn frame)
-{-| Project a line segment into a given sketch plane. Conceptually, this finds
-the [orthographic projection](https://en.wikipedia.org/wiki/Orthographic_projection)
-of the line segment onto the plane and then expresses the projected line segment
-in 2D sketch coordinates.
-
- exampleLineSegment
- |> LineSegment3d.projectInto SketchPlane3d.xy
- --> LineSegment2d.fromEndpoints
- --> ( Point2d.fromCoordinates ( 1, 2 )
- --> , Point2d.fromCoordinates ( 4, 5 )
- --> )
-
- exampleLineSegment
- |> LineSegment3d.projectInto SketchPlane3d.yz
- --> LineSegment2d.fromEndpoints
- --> ( Point2d.fromCoordinates ( 2, 3 )
- --> , Point2d.fromCoordinates ( 5, 6 )
- --> )
-
- exampleLineSegment
- |> LineSegment3d.projectInto SketchPlane3d.zx
- --> LineSegment2d.fromEndpoints
- --> ( Point2d.fromCoordinates ( 3, 1 )
- --> , Point2d.fromCoordinates ( 6, 4 )
- --> )
-
--}
+{-| -}
projectInto : SketchPlane3d -> LineSegment3d -> LineSegment2d
projectInto sketchPlane lineSegment =
let
@@ -525,19 +280,7 @@ projectInto sketchPlane lineSegment =
LineSegment2d.fromEndpoints ( project p1, project p2 )
-{-| Get the minimal bounding box containing a line segment.
-
- LineSegment3d.boundingBox exampleLineSegment
- --> BoundingBox3d.fromExtrema
- --> { minX = 1
- --> , maxX = 4
- --> , minY = 2
- --> , maxY = 5
- --> , minZ = 3
- --> , maxZ = 6
- --> }
-
--}
+{-| -}
boundingBox : LineSegment3d -> BoundingBox3d
boundingBox lineSegment =
let
diff --git a/src/Plane3d.elm b/src/Plane3d.elm
index 99c7dff6..7379809e 100644
--- a/src/Plane3d.elm
+++ b/src/Plane3d.elm
@@ -83,48 +83,25 @@ type alias Plane3d =
Types.Plane3d
-{-| The global XY plane, centered at the origin with a normal in the positive Z
-direction.
-
- Plane3d.xy
- --> Plane3d.through Point3d.origin Direction3d.z
-
--}
+{-| -}
xy : Plane3d
xy =
through Point3d.origin Direction3d.z
-{-| The global YZ plane, centered at the origin with a normal in the positive X
-direction.
-
- Plane3d.yz
- --> Plane3d.through Point3d.origin Direction3d.x
-
--}
+{-| -}
yz : Plane3d
yz =
through Point3d.origin Direction3d.x
-{-| The global ZX plane, centered at the origin with a normal in the positive Y
-direction.
-
- Plane3d.zx
- --> through Point3d.origin Direction3d.y
-
--}
+{-| -}
zx : Plane3d
zx =
through Point3d.origin Direction3d.y
-{-| Construct a plane through the given point, with the given normal direction.
-
- xyPlane =
- Plane3d.through Point3d.origin Direction3d.z
-
--}
+{-| -}
through : Point3d -> Direction3d -> Plane3d
through point normalDirection_ =
Types.Plane3d
@@ -133,14 +110,7 @@ through point normalDirection_ =
}
-{-| Construct a plane with the given normal direction, through the given point.
-Flipped version of `through`.
-
- plane =
- Plane3d.withNormalDirection Direction3d.y
- (Point3d.fromCoordinates ( 2, 1, 3 ))
-
--}
+{-| -}
withNormalDirection : Direction3d -> Point3d -> Plane3d
withNormalDirection normalDirection_ originPoint_ =
Types.Plane3d
@@ -149,32 +119,7 @@ withNormalDirection normalDirection_ originPoint_ =
}
-{-| Attempt to construct a plane passing through the three given points. The
-origin point of the resulting plane will be equal to the first given point, and
-the normal direction will be such that the three given points are in
-counterclockwise order around it according to the right-hand rule. If the three
-given points are collinear, returns `Nothing`.
-
- Plane3d.throughPoints
- (Point3d.fromCoordinates ( 2, 0, 0 ))
- (Point3d.fromCoordinates ( 3, 0, 0 ))
- (Point3d.fromCoordinates ( 4, 1, 1 ))
- --> Just
- --> (Plane3d.through
- --> (Point3d.fromCoordinates ( 2, 0, 0 ))
- --> (Direction3d.fromAzimuthAndElevation
- --> (degrees -90)
- --> (degrees 45)
- --> )
- --> )
-
- Plane3d.throughPoints
- (Point3d.fromCoordinates ( 2, 0, 0 ))
- (Point3d.fromCoordinates ( 3, 0, 0 ))
- (Point3d.fromCoordinates ( 4, 0, 0 ))
- --> Nothing
-
--}
+{-| -}
throughPoints : Point3d -> Point3d -> Point3d -> Maybe Plane3d
throughPoints firstPoint secondPoint thirdPoint =
let
@@ -190,50 +135,25 @@ throughPoints firstPoint secondPoint thirdPoint =
Vector3d.direction crossProduct |> Maybe.map (through firstPoint)
-{-| Get the origin point of a plane.
-
- Plane3d.originPoint Plane3d.xy
- --> Point3d.origin
-
--}
+{-| -}
originPoint : Plane3d -> Point3d
originPoint (Types.Plane3d plane) =
plane.originPoint
-{-| Get the normal direction of a plane.
-
- Plane3d.normalDirection Plane3d.xy
- --> Direction3d.z
-
--}
+{-| -}
normalDirection : Plane3d -> Direction3d
normalDirection (Types.Plane3d plane) =
plane.normalDirection
-{-| Construct an axis from the origin point and normal direction of a plane.
-
- Plane3d.normalAxis Plane3d.zx
- --> Axis3d.y
-
--}
+{-| -}
normalAxis : Plane3d -> Axis3d
normalAxis (Types.Plane3d plane) =
Axis3d.through plane.originPoint plane.normalDirection
-{-| Shift a plane in its own normal direction by the given (signed) distance.
-
- Plane3d.offsetBy 1.0 Plane3d.zx
- --> Plane3d.withNormalDirection Direction3d.y
- --> (Point3d.fromCoordinates ( 0, 1, 0 ))
-
- Plane3d.offsetBy -2.0 Plane3d.xy
- --> Plane3d.withNormalDirection Direction3d.z
- --> (Point3d.fromCoordinates ( 0, 0, -2 ))
-
--}
+{-| -}
offsetBy : Float -> Plane3d -> Plane3d
offsetBy distance plane =
let
@@ -243,24 +163,13 @@ offsetBy distance plane =
translateBy displacement plane
-{-| Reverse a plane's normal direction while leaving its origin point unchanged.
-
- Plane3d.reverseNormal Plane3d.xy
- --> Plane3d.through Point3d.origin
- --> Direction3d.negativeZ
-
--}
+{-| -}
reverseNormal : Plane3d -> Plane3d
reverseNormal (Types.Plane3d plane) =
through plane.originPoint (Direction3d.reverse plane.normalDirection)
-{-| Rotate a plane around an axis by a given angle.
-
- Plane3d.rotateAround Axis3d.y (degrees 90) Plane3d.xy
- --> Plane3d.yz
-
--}
+{-| -}
rotateAround : Axis3d -> Float -> Plane3d -> Plane3d
rotateAround axis angle =
let
@@ -275,113 +184,40 @@ rotateAround axis angle =
(rotateDirection plane.normalDirection)
-{-| Translate a plane by a given displacement. Applies the given displacement to
-the plane's origin point and leaves its normal direction unchanged.
-
- plane =
- Plane3d.withNormalDirection Direction3d.z
- (Point3d.fromCoordinates ( 1, 1, 1 ))
-
- displacement =
- Vector3d.fromComponents ( 1, 2, 3 )
-
- Plane3d.translateBy displacement plane
- --> Plane3d.withNormalDirection Direction3d.z
- --> (Point3d.fromCoordinates ( 2, 3, 4 ))
-
--}
+{-| -}
translateBy : Vector3d -> Plane3d -> Plane3d
translateBy vector (Types.Plane3d plane) =
withNormalDirection plane.normalDirection
(Point3d.translateBy vector plane.originPoint)
-{-| Translate a plane in a given direction by a given distance;
-
- Plane3d.translateIn direction distance
-
-is equivalent to
-
- Plane3d.translateBy
- (Vector3d.withLength distance direction)
-
--}
+{-| -}
translateIn : Direction3d -> Float -> Plane3d -> Plane3d
translateIn direction distance plane =
translateBy (Vector3d.withLength distance direction) plane
-{-| Move a plane so that it has the given origin point but unchanged normal
-direction.
-
- newOrigin =
- Point3d.fromCoordinates ( 1, 2, 3 )
-
- Plane3d.moveTo newOrigin Plane3d.xy
- --> Plane3d.through newOrigin Direction3d.z
-
--}
+{-| -}
moveTo : Point3d -> Plane3d -> Plane3d
moveTo newOrigin (Types.Plane3d plane) =
through newOrigin plane.normalDirection
-{-| Mirror one plane across another. The plane to mirror across is given first
-and the plane to mirror is given second.
-
- plane =
- Plane3d.withNormalDirection Direction3d.z
- (Point3d.fromCoordinates ( 1, 2, 3 ))
-
- Plane3d.mirrorAcross Plane3d.xy plane
- --> Plane3d.withNormalDirection Direction3d.negativeZ
- --> (Point3d.fromCoordinates ( 1, 2, -3 ))
-
--}
+{-| -}
mirrorAcross : Plane3d -> Plane3d -> Plane3d
mirrorAcross otherPlane (Types.Plane3d plane) =
through (Point3d.mirrorAcross otherPlane plane.originPoint)
(Direction3d.mirrorAcross otherPlane plane.normalDirection)
-{-| Take a plane defined in global coordinates, and return it expressed in local
-coordinates relative to a given reference frame.
-
- referenceFrame =
- Frame3d.atPoint
- (Point3d.fromCoordinates ( 1, 1, 1 ))
-
- plane =
- Plane3d.withNormalDirection Direction3d.z
- (Point3d.fromCoordinates ( 0, 0, 2 ))
-
- Plane3d.relativeTo referenceFrame plane
- --> Plane3d.withNormalDirection Direction3d.z
- --> (Point3d.fromCoordinates ( -1, -1, 1 ))
-
--}
+{-| -}
relativeTo : Frame3d -> Plane3d -> Plane3d
relativeTo frame (Types.Plane3d plane) =
through (Point3d.relativeTo frame plane.originPoint)
(Direction3d.relativeTo frame plane.normalDirection)
-{-| Take a plane defined in local coordinates relative to a given reference
-frame, and return that plane expressed in global coordinates.
-
- referenceFrame =
- Frame3d.atPoint
- (Point3d.fromCoordinates ( 1, 1, 1 ))
-
- plane =
- Plane3d.withNormalDirection Direction3d.z
- (Point3d.fromCoordinates ( 1, 2, 3 ))
-
- Plane3d.placeIn referenceFrame plane
- --> Plane3d.withNormalDirection Direction3d.z
- --> (Point3d.fromCoordinates ( 2, 3, 4 ))
-
--}
+{-| -}
placeIn : Frame3d -> Plane3d -> Plane3d
placeIn frame (Types.Plane3d plane) =
through (Point3d.placeIn frame plane.originPoint)
diff --git a/src/Point2d.elm b/src/Point2d.elm
index 4adc80a7..2d83a588 100644
--- a/src/Point2d.elm
+++ b/src/Point2d.elm
@@ -91,9 +91,6 @@ like you can add two vectors.
# Coordinate conversions
-Functions for transforming points between local and global coordinates in
-different coordinate frames.
-
@docs relativeTo, placeIn
-}
@@ -116,90 +113,31 @@ type alias Point2d =
Types.Point2d
-{-| The point (0, 0).
-
- Point2d.origin
- --> Point2d.fromCoordinates ( 0, 0 )
-
--}
+{-| -}
origin : Point2d
origin =
fromCoordinates ( 0, 0 )
-{-| Construct a point from its X and Y coordinates.
-
- point =
- Point2d.fromCoordinates ( 2, 3 )
-
--}
+{-| -}
fromCoordinates : ( Float, Float ) -> Point2d
fromCoordinates =
Types.Point2d
-{-| Construct a point from a radius and angle. Radius is measured from the
-origin and angle is measured counterclockwise from the positive X direction.
-
- Point2d.fromPolarCoordinates ( 2, degrees 135 )
- --> Point2d.fromCoordinates ( -1.4142, 1.4142 )
-
--}
+{-| -}
fromPolarCoordinates : ( Float, Float ) -> Point2d
fromPolarCoordinates polarCoordinates_ =
fromCoordinates (fromPolar polarCoordinates_)
-{-| Construct a point halfway between two other points.
-
- p1 =
- Point2d.fromCoordinates ( 1, 1 )
-
- p2 =
- Point2d.fromCoordinates ( 3, 7 )
-
- Point2d.midpoint p1 p2
- --> Point2d.fromCoordinates ( 2, 4 )
-
--}
+{-| -}
midpoint : Point2d -> Point2d -> Point2d
midpoint firstPoint secondPoint =
interpolateFrom firstPoint secondPoint 0.5
-{-| Construct a point by interpolating from the first given point to the second,
-based on a parameter that ranges from zero to one.
-
- startPoint =
- Point2d.origin
-
- endPoint =
- Point2d.fromCoordinates ( 8, 12 )
-
- Point2d.interpolateFrom startPoint endPoint 0.25
- --> Point2d.fromCoordinates ( 2, 3 )
-
-Partial application may be useful:
-
- interpolatedPoint : Float -> Point2d
- interpolatedPoint =
- Point2d.interpolateFrom startPoint endPoint
-
- List.map interpolatedPoint [ 0, 0.5, 1 ]
- --> [ Point2d.fromCoordinates ( 0, 0 )
- --> , Point2d.fromCoordinates ( 4, 6 )
- --> , Point2d.fromCoordinates ( 8, 12 )
- --> ]
-
-You can pass values less than zero or greater than one to extrapolate:
-
- interpolatedPoint -0.5
- --> Point2d.fromCoordinates ( -4, -6 )
-
- interpolatedPoint 1.25
- --> Point2d.fromCoordinates ( 10, 15 )
-
--}
+{-| -}
interpolateFrom : Point2d -> Point2d -> Float -> Point2d
interpolateFrom p1 p2 t =
let
@@ -215,104 +153,26 @@ interpolateFrom p1 p2 t =
)
-{-| Construct a point along an axis at a particular distance from the axis'
-origin point.
-
- Point2d.along Axis2d.y 3
- --> Point2d.fromCoordinates ( 0, 3 )
-
-Positive and negative distances will be interpreted relative to the direction of
-the axis:
-
- horizontalAxis =
- Axis2d.withDirection Direction2d.negativeX
- (Point2d.fromCoordinates ( 1, 1 ))
-
- Point2d.along horizontalAxis 3
- --> Point2d.fromCoordinates ( -2, 1 )
-
- Point2d.along horizontalAxis -3
- --> Point2d.fromCoordinates ( 4, 1 )
-
--}
+{-| -}
along : Axis2d -> Float -> Point2d
along axis distance =
Axis2d.originPoint axis
|> translateBy (Vector2d.withLength distance (Axis2d.direction axis))
-{-| Construct a point given its local coordinates within a particular frame.
-
- rotatedFrame =
- Frame2d.xy |> Frame2d.rotateBy (degrees 45)
-
- Point2d.fromCoordinatesIn rotatedFrame ( 2, 0 )
- --> Point2d.fromCoordinates ( 1.4142, 1.4142 )
-
-This is shorthand for using `Point2d.placeIn`;
-
- Point2d.fromCoordinatesIn frame localCoordinates
-
-is equivalent to
-
- Point2d.fromCoordinates localCoordinates
- |> Point2d.placeIn frame
-
--}
+{-| -}
fromCoordinatesIn : Frame2d -> ( Float, Float ) -> Point2d
fromCoordinatesIn frame localCoordinates =
placeIn frame (fromCoordinates localCoordinates)
-{-| Construct a point given its local polar coordinates within a particular
-frame.
-
- localFrame =
- Frame2d.atPoint (Point2d.fromCoordinates ( 2, 1 ))
-
- Point2d.fromPolarCoordinatesIn localFrame
- ( 2, degrees 45 )
- --> Point2d.fromCoordinates ( 3.4142, 2.4142 )
-
--}
+{-| -}
fromPolarCoordinatesIn : Frame2d -> ( Float, Float ) -> Point2d
fromPolarCoordinatesIn frame polarCoordinates_ =
placeIn frame (fromPolarCoordinates polarCoordinates_)
-{-| Attempt to find the circumcenter of three points; this is the center of the
-circle that passes through all three points. If the three given points are
-collinear, returns `Nothing`.
-
- Point2d.circumcenter
- ( Point2d.origin
- , Point2d.fromCoordinates ( 1, 0 )
- , Point2d.fromCoordinates ( 0, 1 )
- )
- --> Just (Point2d.fromCoordinates ( 0.5, 0.5 ))
-
- Point2d.circumcenter
- ( Point2d.origin
- , Point2d.fromCoordinates ( 2, 1 )
- , Point2d.fromCoordinates ( 4, 0 )
- )
- --> Just (Point2d.fromCoordinates ( 2, -1.5 ))
-
- Point2d.circumCenter
- ( Point2d.origin
- , Point2d.fromCoordinates ( 2, 0 )
- , Point2d.fromCoordinates ( 4, 0 )
- )
- --> Nothing
-
- Point2d.circumCenter
- ( Point2d.origin
- , Point2d.origin
- , Point2d.fromCoordinates ( 1, 0 )
- )
- --> Nothing
-
--}
+{-| -}
circumcenter : Point2d -> Point2d -> Point2d -> Maybe Point2d
circumcenter p1 p2 p3 =
let
@@ -366,187 +226,56 @@ circumcenter p1 p2 p3 =
)
-{-| Get the coordinates of a point as a tuple.
-
- ( x, y ) =
- Point2d.coordinates point
-
--}
+{-| -}
coordinates : Point2d -> ( Float, Float )
coordinates (Types.Point2d coordinates_) =
coordinates_
-{-| Get the X coordinate of a point.
-
- Point2d.xCoordinate (Point2d.fromCoordinates ( 2, 3 ))
- --> 2
-
--}
+{-| -}
xCoordinate : Point2d -> Float
xCoordinate (Types.Point2d ( x, _ )) =
x
-{-| Get the Y coordinate of a point.
-
- Point2d.yCoordinate (Point2d.fromCoordinates ( 2, 3 ))
- --> 3
-
--}
+{-| -}
yCoordinate : Point2d -> Float
yCoordinate (Types.Point2d ( _, y )) =
y
-{-| Get the polar coordinates (radius and polar angle) of a point.
-
- Point2d.polarCoordinates
- (Point2d.fromCoordinates ( 1, 1 ))
- --> ( 1.4142, degrees 45 )
-
--}
+{-| -}
polarCoordinates : Point2d -> ( Float, Float )
polarCoordinates point =
toPolar (coordinates point)
-{-| Compare two points within a tolerance. Returns true if the distance
-between the two given points is less than the given tolerance.
-
- firstPoint =
- Point2d.fromCoordinates ( 1, 2 )
-
- secondPoint =
- Point2d.fromCoordinates ( 0.9999, 2.0002 )
-
- Point2d.equalWithin 1e-3 firstPoint secondPoint
- --> True
-
- Point2d.equalWithin 1e-6 firstPoint secondPoint
- --> False
-
--}
+{-| -}
equalWithin : Float -> Point2d -> Point2d -> Bool
equalWithin tolerance firstPoint secondPoint =
squaredDistanceFrom firstPoint secondPoint <= tolerance * tolerance
-{-| Find the distance from the first point to the second.
-
- p1 =
- Point2d.fromCoordinates ( 2, 3 )
-
- p2 =
- Point2d.fromCoordinates ( 5, 7 )
-
- Point2d.distanceFrom p1 p2
- --> 5
-
-Partial application can be useful:
-
- points =
- [ Point2d.fromCoordinates ( 3, 4 )
- , Point2d.fromCoordinates ( 10, 0 )
- , Point2d.fromCoordinates ( -1, 2 )
- ]
-
- points
- |> List.sortBy
- (Point2d.distanceFrom Point2d.origin)
- --> [ Point2d.fromCoordinates ( -1, 2 )
- --> , Point2d.fromCoordinates ( 3, 4 )
- --> , Point2d.fromCoordinates ( 10, 0 )
- --> ]
-
--}
+{-| -}
distanceFrom : Point2d -> Point2d -> Float
distanceFrom firstPoint secondPoint =
sqrt (squaredDistanceFrom firstPoint secondPoint)
-{-| Find the square of the distance from one point to another.
-`squaredDistanceFrom` is slightly faster than `distanceFrom`, so for example
-
- Point2d.squaredDistanceFrom p1 p2
- > tolerance * tolerance
-
-is equivalent to but slightly more efficient than
-
- Point2d.distanceFrom p1 p2 > tolerance
-
-since the latter requires a square root under the hood. In many cases, however,
-the speed difference will be negligible and using `distanceFrom` is much more
-readable!
-
--}
+{-| -}
squaredDistanceFrom : Point2d -> Point2d -> Float
squaredDistanceFrom firstPoint secondPoint =
Vector2d.squaredLength (Vector2d.from firstPoint secondPoint)
-{-| Determine how far along an axis a particular point lies. Conceptually, the
-point is projected perpendicularly onto the axis, and then the distance of this
-projected point from the axis' origin point is measured. The result will be
-positive if the projected point is ahead the axis' origin point and negative if
-it is behind, with 'ahead' and 'behind' defined by the direction of the axis.
-
- axis =
- Axis2d.withDirection Direction2d.x
- (Point2d.fromCoordinates ( 1, 2 ))
-
- point =
- Point2d.fromCoordinates ( 3, 3 )
-
- Point2d.signedDistanceAlong axis point
- --> 2
-
- Point2d.signedDistanceAlong axis Point2d.origin
- --> -1
-
--}
+{-| -}
signedDistanceAlong : Axis2d -> Point2d -> Float
signedDistanceAlong axis point =
Vector2d.from (Axis2d.originPoint axis) point
|> Vector2d.componentIn (Axis2d.direction axis)
-{-| Find the perpendicular distance of a point from an axis. The result
-will be positive if the point is to the left of the axis and negative if it is
-to the right, with the forwards direction defined by the direction of the axis.
-
- -- A horizontal axis through a point with a Y
- -- coordinate of 2 is effectively the line Y=2
- axis =
- Axis2d.withDirection Direction2d.x
- (Point2d.fromCoordinates ( 1, 2 ))
-
- point =
- Point2d.fromCoordinates ( 3, 3 )
-
- -- Since the axis is in the positive X direction,
- -- points above the axis are to the left (positive)
- Point2d.signedDistanceFrom axis point
- --> 1
-
- -- and points below are to the right (negative)
- Point2d.signedDistanceFrom axis Point2d.origin
- --> -2
-
-This means that reversing an axis will also flip the sign of the result of this
-function:
-
- -- Reversing an axis reverses its direction
- reversedAxis =
- Axis2d.reverse axis
-
- Point2d.signedDistanceFrom reversedAxis point
- --> -1
-
- Point2d.signedDistanceFrom reversedAxis Point2d.origin
- --> 2
-
--}
+{-| -}
signedDistanceFrom : Axis2d -> Point2d -> Float
signedDistanceFrom axis point =
let
@@ -559,28 +288,7 @@ signedDistanceFrom axis point =
Vector2d.crossProduct directionVector displacementVector
-{-| Perform a uniform scaling about the given center point. The center point is
-given first and the point to transform is given last. Points will contract or
-expand about the center point by the given scale. Scaling by a factor of 1 is a
-no-op, and scaling by a factor of 0 collapses all points to the center point.
-
- centerPoint =
- Point2d.fromCoordinates ( 1, 1 )
-
- point =
- Point2d.fromCoordinates ( 2, 3 )
-
- Point2d.scaleAbout centerPoint 3 point
- --> Point2d.fromCoordinates ( 4, 7 )
-
- Point2d.scaleAbout centerPoint 0.5 point
- --> Point2d.fromCoordinates ( 1.5, 2 )
-
-Avoid scaling by a negative scaling factor - while this may sometimes do what
-you want it is confusing and error prone. Try a combination of mirror and/or
-rotation operations instead.
-
--}
+{-| -}
scaleAbout : Point2d -> Float -> Point2d -> Point2d
scaleAbout centerPoint scale point =
Vector2d.from centerPoint point
@@ -588,40 +296,13 @@ scaleAbout centerPoint scale point =
|> addTo centerPoint
-{-| Rotate around a given center point counterclockwise by a given angle (in
-radians). The point to rotate around is given first and the point to rotate is
-given last.
-
- centerPoint =
- Point2d.fromCoordinates ( 2, 0 )
-
- angle =
- degrees 45
-
- point =
- Point2d.fromCoordinates ( 3, 0 )
-
- Point2d.rotateAround centerPoint angle point
- --> Point2d.fromCoordinates ( 2.7071, 0.7071 )
-
--}
+{-| -}
rotateAround : Point2d -> Float -> Point2d -> Point2d
rotateAround centerPoint angle =
Vector2d.from centerPoint >> Vector2d.rotateBy angle >> addTo centerPoint
-{-| Translate a point by a given displacement.
-
- point =
- Point2d.fromCoordinates ( 3, 4 )
-
- displacement =
- Vector2d.fromComponents ( 1, 2 )
-
- Point2d.translateBy displacement point
- --> Point2d.fromCoordinates ( 4, 6 )
-
--}
+{-| -}
translateBy : Vector2d -> Point2d -> Point2d
translateBy vector point =
let
@@ -634,29 +315,7 @@ translateBy vector point =
fromCoordinates ( px + vx, py + vy )
-{-| Translate a point in a given direction by a given distance.
-
- point =
- Point2d.fromCoordinates ( 3, 4 )
-
- point |> Point2d.translateIn Direction2d.x 2
- --> Point2d.fromCoordinates ( 5, 4 )
-
- point |> Point2d.translateIn Direction2d.y 2
- --> Point2d.fromCoordinates ( 3, 6 )
-
- angledDirection =
- Direction2d.fromAngle (degrees 45)
-
- point |> Point2d.translateIn angledDirection 1
- --> Point2d.fromCoordinates ( 3.7071, 4.7071 )
-
-The distance can be negative:
-
- Point2d.translateIn Direction2d.x -2
- --> Point2d.fromCoordinates ( 1, 4 )
-
--}
+{-| -}
translateIn : Direction2d -> Float -> Point2d -> Point2d
translateIn direction distance point =
let
@@ -669,19 +328,7 @@ translateIn direction distance point =
fromCoordinates ( px + distance * dx, py + distance * dy )
-{-| Mirror a point across an axis. The result will be the same distance from the
-axis but on the opposite side.
-
- point =
- Point2d.fromCoordinates ( 2, 3 )
-
- Point2d.mirrorAcross Axis2d.x point
- --> Point2d.fromCoordinates ( 2, -3 )
-
- Point2d.mirrorAcross Axis2d.y point
- --> Point2d.fromCoordinates ( -2, 3 )
-
--}
+{-| -}
mirrorAcross : Axis2d -> Point2d -> Point2d
mirrorAcross axis =
Vector2d.from (Axis2d.originPoint axis)
@@ -689,27 +336,7 @@ mirrorAcross axis =
>> addTo (Axis2d.originPoint axis)
-{-| Project a point perpendicularly onto an axis.
-
- point =
- Point2d.fromCoordinates ( 2, 3 )
-
- Point2d.projectOnto Axis2d.x point
- --> Point2d.fromCoordinates ( 2, 0 )
-
- Point2d.projectOnto Axis2d.y point
- --> Point2d.fromCoordinates ( 0, 3 )
-
-The axis does not have to pass through the origin:
-
- offsetYAxis =
- Axis2d.withDirection Direction2d.y
- (Point2d.fromCoordinates ( 1, 0 ))
-
- Point2d.projectOnto offsetYAxis point
- --> Point2d.fromCoordinates ( 1, 3 )
-
--}
+{-| -}
projectOnto : Axis2d -> Point2d -> Point2d
projectOnto axis =
Vector2d.from (Axis2d.originPoint axis)
@@ -717,21 +344,7 @@ projectOnto axis =
>> addTo (Axis2d.originPoint axis)
-{-| Take a point defined in global coordinates, and return it expressed in local
-coordinates relative to a given reference frame.
-
- localFrame =
- Frame2d.atPoint (Point2d.fromCoordinates ( 1, 2 ))
-
- Point2d.relativeTo localFrame
- (Point2d.fromCoordinates ( 4, 5 ))
- --> Point2d.fromCoordinates ( 3, 3 )
-
- Point2d.relativeTo localFrame
- (Point2d.fromCoordinates ( 1, 1 ))
- --> Point2d.fromCoordinates ( 0, -1 )
-
--}
+{-| -}
relativeTo : Frame2d -> Point2d -> Point2d
relativeTo frame point =
Vector2d.from (Frame2d.originPoint frame) point
@@ -740,21 +353,7 @@ relativeTo frame point =
|> fromCoordinates
-{-| Take a point defined in local coordinates relative to a given reference
-frame, and return that point expressed in global coordinates.
-
- localFrame =
- Frame2d.atPoint (Point2d.fromCoordinates ( 1, 2 ))
-
- Point2d.placeIn localFrame
- (Point2d.fromCoordinates ( 3, 3 ))
- --> Point2d.fromCoordinates ( 4, 5 )
-
- Point2d.placeIn localFrame
- (Point2d.fromCoordinates ( 0, 1 ))
- --> Point2d.fromCoordinates ( 1, 1 )
-
--}
+{-| -}
placeIn : Frame2d -> Point2d -> Point2d
placeIn frame point =
Vector2d.fromComponents (coordinates point)
diff --git a/src/Point3d.elm b/src/Point3d.elm
index 3d37de44..a4b50e1f 100644
--- a/src/Point3d.elm
+++ b/src/Point3d.elm
@@ -95,9 +95,6 @@ like you can add two vectors.
# Coordinate conversions
-Functions for transforming points between local and global coordinates in
-different coordinate frames.
-
@docs relativeTo, placeIn, projectInto
-}
@@ -122,78 +119,25 @@ type alias Point3d =
Types.Point3d
-{-| The point (0, 0, 0).
-
- Point3d.origin
- --> Point3d.fromCoordinates ( 0, 0, 0 )
-
--}
+{-| -}
origin : Point3d
origin =
fromCoordinates ( 0, 0, 0 )
-{-| Construct a point from its X, Y and Z coordinates.
-
- point =
- Point3d.fromCoordinates ( 2, 1, 3 )
-
--}
+{-| -}
fromCoordinates : ( Float, Float, Float ) -> Point3d
fromCoordinates =
Types.Point3d
-{-| Construct a point halfway between two other points.
-
- p1 =
- Point3d.fromCoordinates ( 1, 1, 1 )
-
- p2 =
- Point3d.fromCoordinates ( 3, 7, 9 )
-
- Point3d.midpoint p1 p2
- --> Point3d.fromCoordinates ( 2, 4, 5 )
-
--}
+{-| -}
midpoint : Point3d -> Point3d -> Point3d
midpoint firstPoint secondPoint =
interpolateFrom firstPoint secondPoint 0.5
-{-| Construct a point by interpolating from the first given point to the second,
-based on a parameter that ranges from zero to one.
-
- startPoint =
- Point3d.fromCoordinates ( 1, 2, 4 )
-
- endPoint =
- Point3d.fromCoordinates ( 1, 2, 8 )
-
- Point3d.interpolateFrom startPoint endPoint 0.25
- --> Point3d.fromCoordinates ( 1, 2, 5 )
-
-Partial application may be useful:
-
- interpolatedPoint : Float -> Point3d
- interpolatedPoint =
- Point3d.interpolateFrom startPoint endPoint
-
- List.map interpolatedPoint [ 0, 0.5, 1 ]
- --> [ Point3d.fromCoordinates ( 1, 2, 4 )
- --> , Point3d.fromCoordinates ( 1, 2, 6 )
- --> , Point3d.fromCoordinates ( 1, 2, 8 )
- --> ]
-
-You can pass values less than zero or greater than one to extrapolate:
-
- interpolatedPoint -0.5
- --> Point3d.fromCoordinates ( 1, 2, 2 )
-
- interpolatedPoint 1.25
- --> Point3d.fromCoordinates ( 1, 2, 9 )
-
--}
+{-| -}
interpolateFrom : Point3d -> Point3d -> Float -> Point3d
interpolateFrom p1 p2 t =
let
@@ -210,57 +154,14 @@ interpolateFrom p1 p2 t =
)
-{-| Construct a point along an axis at a particular distance from the axis'
-origin point.
-
- Point3d.along Axis3d.z 2
- --> Point3d.fromCoordinates ( 0, 0, 2 )
-
-Positive and negative distances are interpreted relative to the direction of the
-axis:
-
- horizontalAxis =
- Axis3d.withDirection Direction3d.negativeX
- (Point3d.fromCoordinates ( 1, 1, 1 ))
-
- Point3d.along horizontalAxis 3
- --> Point3d.fromCoordinates ( -2, 1, 1 )
-
- Point3d.along horizontalAxis -3
- --> Point3d.fromCoordinates ( 4, 1, 1 )
-
--}
+{-| -}
along : Axis3d -> Float -> Point3d
along (Types.Axis3d axis) distance =
axis.originPoint
|> translateBy (Vector3d.withLength distance axis.direction)
-{-| Construct a 3D point lying _on_ a sketch plane by providing a 2D point
-specified in XY coordinates _within_ the sketch plane.
-
- Point3d.on SketchPlane3d.xy <|
- Point2d.fromCoordinates ( 2, 1 )
- --> Point3d.fromCoordinates ( 2, 1, 0 )
-
- Point3d.on SketchPlane3d.xz <|
- Point2d.fromCoordinates ( 2, 1 )
- --> Point3d.fromCoordinates ( 2, 0, 1 )
-
-The sketch plane can have any position and orientation:
-
- tiltedSketchPlane =
- SketchPlane3d.xy
- |> SketchPlane3d.rotateAround Axis3d.x
- (degrees 45)
- |> SketchPlane3d.moveTo
- (Point3d.fromCoordinates ( 10, 10, 10 ))
-
- Point3d.on tiltedSketchPlane <|
- Point2d.fromCoordinates ( 2, 1 )
- --> Point3d.fromCoordinates ( 12, 10.7071, 10.7071 )
-
--}
+{-| -}
on : SketchPlane3d -> Point2d -> Point3d
on sketchPlane point2d =
let
@@ -283,47 +184,13 @@ on sketchPlane point2d =
)
-{-| Construct a point given its local coordinates within a particular frame.
-
- frame =
- Frame3d.atPoint
- (Point3d.fromCoordinates ( 1, 1, 1 ))
-
- Point3d.fromCoordinatesIn frame ( 1, 2, 3 )
- --> Point3d.fromCoordinates ( 2, 3, 4 )
-
-This is shorthand for using `Point3d.placeIn`;
-
- Point3d.fromCoordinatesIn frame localCoordinates
-
-is equivalent to
-
- Point3d.fromCoordinates localCoordinates
- |> Point3d.placeIn frame
-
--}
+{-| -}
fromCoordinatesIn : Frame3d -> ( Float, Float, Float ) -> Point3d
fromCoordinatesIn frame localCoordinates =
placeIn frame (fromCoordinates localCoordinates)
-{-| Attempt to find the circumcenter of three points; this is the center of the
-circle that passes through all three points. If the three given points are
-collinear, returns `Nothing`.
-
- Point3d.circumcenter
- (Point3d.fromCoordinates ( 1, 0, 0 ))
- (Point3d.fromCoordinates ( 0, 1, 0 ))
- (Point3d.fromCoordinates ( 0, 0, 1 ))
- --> Just (Point3d.fromCoordinates (0.33, 0.33, 0.33))
-
- Point3d.circumcenter
- Point3d.origin
- (Point3d.fromCoordinates ( 1, 0, 0 ))
- (Point3d.fromCoordinates ( 2, 0, 0 ))
- --> Nothing
-
--}
+{-| -}
circumcenter : Point3d -> Point3d -> Point3d -> Maybe Point3d
circumcenter p1 p2 p3 =
let
@@ -378,179 +245,61 @@ circumcenter p1 p2 p3 =
)
-{-| Get the coordinates of a point as a tuple.
-
- ( x, y, z ) =
- Point3d.coordinates point
-
--}
+{-| -}
coordinates : Point3d -> ( Float, Float, Float )
coordinates (Types.Point3d coordinates_) =
coordinates_
-{-| Get the X coordinate of a point.
-
- Point3d.fromCoordinates ( 2, 1, 3 )
- |> Point3d.xCoordinate
- --> 2
-
--}
+{-| -}
xCoordinate : Point3d -> Float
xCoordinate (Types.Point3d ( x, _, _ )) =
x
-{-| Get the Y coordinate of a point.
-
- Point3d.fromCoordinates ( 2, 1, 3 )
- |> Point3d.yCoordinate
- --> 1
-
--}
+{-| -}
yCoordinate : Point3d -> Float
yCoordinate (Types.Point3d ( _, y, _ )) =
y
-{-| Get the Z coordinate of a point.
-
- Point3d.fromCoordinates ( 2, 1, 3 )
- |> Point3d.zCoordinate
- --> 3
-
--}
+{-| -}
zCoordinate : Point3d -> Float
zCoordinate (Types.Point3d ( _, _, z )) =
z
-{-| Compare two points within a tolerance. Returns true if the distance
-between the two given points is less than the given tolerance.
-
- firstPoint =
- Point3d.fromCoordinates ( 2, 1, 3 )
-
- secondPoint =
- Point3d.fromCoordinates ( 2.0002, 0.9999, 3.0001 )
-
- Point3d.equalWithin 1e-3 firstPoint secondPoint
- --> True
-
- Point3d.equalWithin 1e-6 firstPoint secondPoint
- --> False
-
--}
+{-| -}
equalWithin : Float -> Point3d -> Point3d -> Bool
equalWithin tolerance firstPoint secondPoint =
squaredDistanceFrom firstPoint secondPoint <= tolerance * tolerance
-{-| Find the distance from the first point to the second.
-
- p1 =
- Point3d.fromCoordinates ( 1, 1, 2 )
-
- p2 =
- Point3d.fromCoordinates ( 2, 3, 4 )
-
- Point3d.distanceFrom p1 p2
- --> 3
-
-Partial application can be useful:
-
- points =
- [ Point3d.fromCoordinates ( 3, 4, 5 )
- , Point3d.fromCoordinates ( 10, 10, 10 )
- , Point3d.fromCoordinates ( -1, 2, -3 )
- ]
-
- points
- |> List.sortBy
- (Point3d.distanceFrom Point3d.origin)
- --> [ Point3d.fromCoordinates ( -1, 2, -3 )
- --> , Point3d.fromCoordinates ( 3, 4, 5 )
- --> , Point3d.fromCoordinates ( 10, 10, 10 )
- --> ]
-
--}
+{-| -}
distanceFrom : Point3d -> Point3d -> Float
distanceFrom firstPoint secondPoint =
sqrt (squaredDistanceFrom firstPoint secondPoint)
-{-| Find the square of the distance from one point to another.
-`squaredDistanceFrom` is slightly faster than `distanceFrom`, so for example
-
- Point3d.squaredDistanceFrom p1 p2
- > tolerance * tolerance
-
-is equivalent to but slightly more efficient than
-
- Point3d.distanceFrom p1 p2 > tolerance
-
-since the latter requires a square root under the hood. In many cases, however,
-the speed difference will be negligible and using `distanceFrom` is much more
-readable!
-
--}
+{-| -}
squaredDistanceFrom : Point3d -> Point3d -> Float
squaredDistanceFrom firstPoint secondPoint =
Vector3d.squaredLength (Vector3d.from firstPoint secondPoint)
-{-| Determine how far along an axis a particular point lies. Conceptually, the
-point is projected perpendicularly onto the axis, and then the distance of this
-projected point from the axis' origin point is measured. The result will be
-positive if the projected point is ahead the axis' origin point and negative if
-it is behind, with 'ahead' and 'behind' defined by the direction of the axis.
-
- axis =
- Axis3d.withDirection Direction3d.x
- (Point3d.fromCoordinates ( 1, 0, 0 ))
-
- point =
- Point3d.fromCoordinates ( 3, 3, 3 )
-
- Point3d.signedDistanceAlong axis point
- --> 2
-
- Point3d.signedDistanceAlong axis Point3d.origin
- --> -1
-
--}
+{-| -}
signedDistanceAlong : Axis3d -> Point3d -> Float
signedDistanceAlong (Types.Axis3d axis) point =
Vector3d.from axis.originPoint point |> Vector3d.componentIn axis.direction
-{-| Find the perpendicular (nearest) distance of a point from an axis.
-
- point =
- Point3d.fromCoordinates ( -3, 4, 0 )
-
- Point3d.distanceFromAxis Axis3d.x point
- --> 4
-
- Point3d.distanceFromAxis Axis3d.y point
- --> 3
-
- Point3d.distanceFromAxis Axis3d.z point
- --> 5
-
-Note that unlike in 2D, the result is always positive (unsigned) since there is
-no such thing as the left or right side of an axis in 3D.
-
--}
+{-| -}
distanceFromAxis : Axis3d -> Point3d -> Float
distanceFromAxis axis point =
sqrt (squaredDistanceFromAxis axis point)
-{-| Find the square of the perpendicular distance of a point from an axis. As
-with `distanceFrom`/`squaredDistanceFrom` this is slightly more efficient than
-`distanceFromAxis` since it avoids a square root.
--}
+{-| -}
squaredDistanceFromAxis : Axis3d -> Point3d -> Float
squaredDistanceFromAxis (Types.Axis3d axis) point =
Vector3d.from axis.originPoint point
@@ -558,36 +307,7 @@ squaredDistanceFromAxis (Types.Axis3d axis) point =
|> Vector3d.squaredLength
-{-| Find the perpendicular distance of a point from a plane. The result will be
-positive if the point is 'above' the plane and negative if it is 'below', with
-'up' defined by the normal direction of the plane.
-
- plane =
- Plane3d.withNormalDirection Direction3d.y
- (Point3d.fromCoordinates ( 1, 2, 3 ))
-
- point =
- Point3d.fromCoordinates ( 3, 3, 3 )
-
- Point3d.signedDistanceFrom plane point
- --> 1
-
- Point3d.signedDistanceFrom plane Point3d.origin
- --> -2
-
-This means that flipping a plane (reversing its normal direction) will also flip
-the sign of the result of this function:
-
- flippedPlane =
- Plane3d.reverseNormal plane
-
- Point3d.signedDistanceFrom flippedPlane point
- --> -1
-
- Point3d.signedDistanceFrom flippedPlane Point3d.origin
- --> 2
-
--}
+{-| -}
signedDistanceFrom : Plane3d -> Point3d -> Float
signedDistanceFrom plane point =
let
@@ -603,28 +323,7 @@ signedDistanceFrom plane point =
(x - x0) * nx + (y - y0) * ny + (z - z0) * nz
-{-| Perform a uniform scaling about the given center point. The center point is
-given first and the point to transform is given last. Points will contract or
-expand about the center point by the given scale. Scaling by a factor of 1 is a
-no-op, and scaling by a factor of 0 collapses all points to the center point.
-
- centerPoint =
- Point3d.fromCoordinates ( 1, 1, 1 )
-
- point =
- Point3d.fromCoordinates ( 1, 2, 3 )
-
- Point3d.scaleAbout centerPoint 3 point
- --> Point3d.fromCoordinates ( 1, 4, 7 )
-
- Point3d.scaleAbout centerPoint 0.5 point
- --> Point3d.fromCoordinates ( 1, 1.5, 2 )
-
-Avoid scaling by a negative scaling factor - while this may sometimes do what
-you want it is confusing and error prone. Try a combination of mirror and/or
-rotation operations instead.
-
--}
+{-| -}
scaleAbout : Point3d -> Float -> Point3d -> Point3d
scaleAbout centerPoint scale point =
Vector3d.from centerPoint point
@@ -632,24 +331,7 @@ scaleAbout centerPoint scale point =
|> addTo centerPoint
-{-| Rotate a point around an axis by a given angle (in radians).
-
- axis =
- Axis3d.x
-
- angle =
- degrees 45
-
- point =
- Point3d.fromCoordinates ( 3, 1, 0 )
-
- Point3d.rotateAround axis angle point
- --> Point3d.fromCoordinates ( 3, 0.7071, 0.7071 )
-
-Rotation direction is given by the right-hand rule, counterclockwise around the
-direction of the axis.
-
--}
+{-| -}
rotateAround : Axis3d -> Float -> Point3d -> Point3d
rotateAround ((Types.Axis3d axis) as axis_) angle point =
Vector3d.from axis.originPoint point
@@ -657,18 +339,7 @@ rotateAround ((Types.Axis3d axis) as axis_) angle point =
|> addTo axis.originPoint
-{-| Translate a point by a given displacement.
-
- point =
- Point3d.fromCoordinates ( 3, 4, 5 )
-
- displacement =
- Vector3d.fromComponents ( 1, 2, 3 )
-
- Point3d.translateBy displacement point
- --> Point3d.fromCoordinates ( 4, 6, 8 )
-
--}
+{-| -}
translateBy : Vector3d -> Point3d -> Point3d
translateBy vector point =
let
@@ -681,23 +352,7 @@ translateBy vector point =
fromCoordinates ( px + vx, py + vy, pz + vz )
-{-| Translate a point in a given direction by a given distance.
-
- point =
- Point3d.fromCoordinates ( 3, 4, 5 )
-
- point |> Point3d.translateIn Direction3d.x 2
- --> Point3d.fromCoordinates ( 5, 4, 5 )
-
- point |> Point3d.translateIn Direction3d.y 2
- --> Point3d.fromCoordinates ( 3, 6, 5 )
-
-The distance can be negative:
-
- Point3d.translateIn Direction3d.x -2
- --> Point3d.fromCoordinates ( 1, 4, 5 )
-
--}
+{-| -}
translateIn : Direction3d -> Float -> Point3d -> Point3d
translateIn direction distance point =
let
@@ -714,32 +369,7 @@ translateIn direction distance point =
)
-{-| Mirror a point across a plane. The result will be the same distance from the
-plane but on the opposite side.
-
- point =
- Point3d.fromCoordinates ( 1, 2, 3 )
-
- -- Plane3d.xy is the plane Z=0
- Point3d.mirrorAcross Plane3d.xy point
- --> Point3d.fromCoordinates ( 1, 2, -3 )
-
- -- Plane3d.yz is the plane X=0
- Point3d.mirrorAcross Plane3d.yz point
- --> Point3d.fromCoordinates ( -1, 2, 3 )
-
-The plane does not have to pass through the origin:
-
- -- offsetPlane is the plane Z=1
- offsetPlane =
- Plane3d.offsetBy 1 Plane3d.xy
-
- -- The origin point is 1 unit below the offset
- -- plane, so its mirrored copy is one unit above
- Point3d.mirrorAcross offsetPlane Point3d.origin
- --> Point3d.fromCoordinates ( 0, 0, 2 )
-
--}
+{-| -}
mirrorAcross : Plane3d -> Point3d -> Point3d
mirrorAcross plane point =
let
@@ -751,27 +381,7 @@ mirrorAcross plane point =
|> addTo originPoint
-{-| Find the [orthographic projection](https://en.wikipedia.org/wiki/Orthographic_projection)
-of a point onto a plane:
-
- point =
- Point3d.fromCoordinates ( 1, 2, 3 )
-
- Point3d.projectOnto Plane3d.xy point
- --> Point3d.fromCoordinates ( 1, 2, 0 )
-
- Point3d.projectOnto Plane3d.yz point
- --> Point3d.fromCoordinates ( 0, 2, 3 )
-
-The plane does not have to pass through the origin:
-
- offsetPlane =
- Plane3d.offsetBy 1 Plane3d.xy
-
- Point3d.projectOnto offsetPlane point
- --> Point3d.fromCoordinates ( 1, 2, 1 )
-
--}
+{-| -}
projectOnto : Plane3d -> Point3d -> Point3d
projectOnto plane point =
let
@@ -782,43 +392,13 @@ projectOnto plane point =
translateBy displacement point
-{-| Project a point perpendicularly onto an axis.
-
- point =
- Point3d.fromCoordinates ( 1, 2, 3 )
-
- Point3d.projectOntoAxis Axis3d.x
- --> Point3d.fromCoordinates ( 1, 0, 0 )
-
- verticalAxis =
- Axis3d.withDirection Direction3d.z
- (Point3d.fromCoordinates ( 0, 1, 2 ))
-
- Point3d.projectOntoAxis verticalAxis
- --> Point3d.fromCoordinates ( 0, 1, 3 )
-
--}
+{-| -}
projectOntoAxis : Axis3d -> Point3d -> Point3d
projectOntoAxis axis point =
along axis (signedDistanceAlong axis point)
-{-| Take a point defined in global coordinates, and return it expressed in local
-coordinates relative to a given reference frame.
-
- localFrame =
- Frame3d.atPoint
- (Point3d.fromCoordinates ( 1, 2, 3 ))
-
- Point3d.relativeTo localFrame
- (Point3d.fromCoordinates ( 4, 5, 6 ))
- --> Point3d.fromCoordinates ( 3, 3, 3 )
-
- Point3d.relativeTo localFrame
- (Point3d.fromCoordinates ( 1, 1, 1 ))
- --> Point3d.fromCoordinates ( 0, -1, -2 )
-
--}
+{-| -}
relativeTo : Frame3d -> Point3d -> Point3d
relativeTo frame point =
Vector3d.from (Frame3d.originPoint frame) point
@@ -827,22 +407,7 @@ relativeTo frame point =
|> fromCoordinates
-{-| Take a point defined in local coordinates relative to a given reference
-frame, and return that point expressed in global coordinates.
-
- localFrame =
- Frame3d.atPoint
- (Point3d.fromCoordinates ( 1, 2, 3 ))
-
- Point3d.placeIn localFrame
- (Point3d.fromCoordinates ( 3, 3, 3 ))
- --> Point3d.fromCoordinates ( 4, 5, 6 )
-
- Point3d.placeIn localFrame
- (Point3d.fromCoordinates ( 0, -1, -2 ))
- --> Point3d.fromCoordinates ( 1, 1, 1 )
-
--}
+{-| -}
placeIn : Frame3d -> Point3d -> Point3d
placeIn frame point =
Vector3d.fromComponents (coordinates point)
@@ -850,24 +415,7 @@ placeIn frame point =
|> addTo (Frame3d.originPoint frame)
-{-| Project a point into a given sketch plane. Conceptually, this finds the
-[orthographic projection](https://en.wikipedia.org/wiki/Orthographic_projection)
-of the point onto the plane and then expresses the projected point in 2D sketch
-coordinates.
-
- point =
- Point3d.fromCoordinates ( 2, 1, 3 )
-
- Point3d.projectInto SketchPlane3d.xy point
- --> Point2d.fromCoordinates ( 2, 1 )
-
- Point3d.projectInto SketchPlane3d.yz point
- --> Point2d.fromCoordinates ( 1, 3 )
-
- Point3d.projectInto SketchPlane3d.zx point
- --> Point2d.fromCoordinates ( 3, 2 )
-
--}
+{-| -}
projectInto : SketchPlane3d -> Point3d -> Point2d
projectInto sketchPlane point =
let
diff --git a/src/Polygon2d.elm b/src/Polygon2d.elm
index cd99a21f..2a1ceea2 100644
--- a/src/Polygon2d.elm
+++ b/src/Polygon2d.elm
@@ -133,22 +133,7 @@ makeInnerLoop vertices_ =
List.reverse vertices_
-{-| Construct a polygon without holes from a list of its vertices:
-
- rectangle =
- Polygon2d.singleLoop
- [ Point2d.fromCoordinates ( 1, 1 )
- , Point2d.fromCoordinates ( 3, 1 )
- , Point2d.fromCoordinates ( 3, 2 )
- , Point2d.fromCoordinates ( 1, 2 )
- ]
-
-The last vertex is implicitly considered to be connected back to the first
-vertex (you do not have to close the polygon explicitly). Vertices should
-ideally be provided in counterclockwise order; if they are provided in clockwise
-order they will be reversed.
-
--}
+{-| -}
singleLoop : List Point2d -> Polygon2d
singleLoop vertices_ =
Types.Polygon2d
@@ -157,35 +142,7 @@ singleLoop vertices_ =
}
-{-| Construct a polygon with holes from one outer loop and a list of inner
-loops. The loops must not touch or intersect each other.
-
- outerLoop =
- [ Point2d.fromCoordinates ( 0, 0 )
- , Point2d.fromCoordinates ( 3, 0 )
- , Point2d.fromCoordinates ( 3, 3 )
- , Point2d.fromCoordinates ( 0, 3 )
- ]
-
- innerLoop =
- [ Point2d.fromCoordinates ( 1, 1 )
- , Point2d.fromCoordinates ( 1, 2 )
- , Point2d.fromCoordinates ( 2, 2 )
- , Point2d.fromCoordinates ( 2, 1 )
- ]
-
- squareWithHole =
- Polygon2d.with
- { outerLoop = outerLoop
- , innerLoops = [ innerLoop ]
- }
-
-As with `Polygon2d.singleLoop`, the last vertex of each loop is considered to be
-connected back to the first. Vertices of the outer loop should ideally be
-provided in counterclockwise order and vertices of the inner loops should
-ideally be provided in clockwise order.
-
--}
+{-| -}
with : { outerLoop : List Point2d, innerLoops : List (List Point2d) } -> Polygon2d
with arguments =
Types.Polygon2d
@@ -220,14 +177,7 @@ chain =
chainHelp []
-{-| Build the [convex hull](https://en.wikipedia.org/wiki/Convex_hull) of a list
-of points:
-
-
-
-This is an O(n log n) operation.
-
--}
+{-| -}
convexHull : List Point2d -> Polygon2d
convexHull points =
-- See http://www.algorithmist.com/index.php/Monotone_Chain_Convex_Hull
@@ -245,55 +195,19 @@ convexHull points =
singleLoop (lower ++ upper)
-{-| Get the list of vertices definining the outer loop (border) of a polygon.
-The vertices will be in counterclockwise order.
-
- Polygon2d.outerLoop squareWithHole
- --> [ Point2d.fromCoordinates ( 0, 0 )
- --> , Point2d.fromCoordinates ( 3, 0 )
- --> , Point2d.fromCoordinates ( 3, 3 )
- --> , Point2d.fromCoordinates ( 0, 3 )
- --> ]
-
--}
+{-| -}
outerLoop : Polygon2d -> List Point2d
outerLoop (Types.Polygon2d polygon) =
polygon.outerLoop
-{-| Get the holes (if any) of a polygon, each defined by a list of vertices.
-Each list of vertices will be in clockwise order.
-
- Polygon2d.innerLoops squareWithHole
- --> [ [ Point2d.fromCoordinates ( 1, 1 )
- --> , Point2d.fromCoordinates ( 1, 2 )
- --> , Point2d.fromCoordinates ( 2, 2 )
- --> , Point2d.fromCoordinates ( 2, 1 )
- --> ]
- --> ]
-
--}
+{-| -}
innerLoops : Polygon2d -> List (List Point2d)
innerLoops (Types.Polygon2d polygon) =
polygon.innerLoops
-{-| Get all vertices of a polygon; this will include vertices from the outer
-loop of the polygon and all inner loops. The order of the returned vertices is
-undefined.
-
- Polygon2d.vertices squareWithHole
- --> [ Point2d ( 0, 0 )
- --> , Point2d ( 3, 0 )
- --> , Point2d ( 3, 3 )
- --> , Point2d ( 0, 3 )
- --> , Point2d ( 1, 1 )
- --> , Point2d ( 1, 2 )
- --> , Point2d ( 2, 2 )
- --> , Point2d ( 2, 1 )
- --> ]
-
--}
+{-| -}
vertices : Polygon2d -> List Point2d
vertices polygon =
List.concat (outerLoop polygon :: innerLoops polygon)
@@ -309,45 +223,7 @@ loopEdges vertices_ =
List.map2 LineSegment2d.from all (rest ++ [ first ])
-{-| Get all edges of a polygon. This will include both outer edges and inner
-(hole) edges.
-
- Polygon2d.edges squareWithHole
- --> [ LineSegment2d.fromEndpoints
- --> ( Point2d.fromCoordinates ( 0, 0 )
- --> , Point2d.fromCoordinates ( 3, 0 )
- --> )
- --> , LineSegment2d.fromEndpoints
- --> ( Point2d.fromCoordinates ( 3, 0 )
- --> , Point2d.fromCoordinates ( 3, 3 )
- --> )
- --> , LineSegment2d.fromEndpoints
- --> ( Point2d.fromCoordinates ( 3, 3 )
- --> , Point2d.fromCoordinates ( 0, 3 )
- --> )
- --> , LineSegment2d.fromEndpoints
- --> ( Point2d.fromCoordinates ( 0, 3 )
- --> , Point2d.fromCoordinates ( 0, 0 )
- --> )
- --> , LineSegment2d.fromEndpoints
- --> ( Point2d.fromCoordinates ( 1, 1 )
- --> , Point2d.fromCoordinates ( 1, 2 )
- --> )
- --> , LineSegment2d.fromEndpoints
- --> ( Point2d.fromCoordinates ( 1, 2 )
- --> , Point2d.fromCoordinates ( 2, 2 )
- --> )
- --> , LineSegment2d.fromEndpoints
- --> ( Point2d.fromCoordinates ( 2, 2 )
- --> , Point2d.fromCoordinates ( 2, 1 )
- --> )
- --> , LineSegment2d.fromEndpoints
- --> ( Point2d.fromCoordinates ( 2, 1 )
- --> , Point2d.fromCoordinates ( 1, 1 )
- --> )
- --> ]
-
--}
+{-| -}
edges : Polygon2d -> List LineSegment2d
edges polygon =
let
@@ -360,121 +236,44 @@ edges polygon =
List.concat (outerEdges :: innerEdges)
-{-| Get the perimeter of a polygon (the sum of the lengths of its edges). This
-includes the outer perimeter and the perimeter of any holes.
-
- Polygon2d.perimeter squareWithHole
- --> 16
-
--}
+{-| -}
perimeter : Polygon2d -> Float
perimeter =
edges >> List.map LineSegment2d.length >> List.sum
-{-| Get the area of a polygon. This value will never be negative.
-
- Polygon2d.area squareWithHole
- --> 8
-
--}
+{-| -}
area : Polygon2d -> Float
area polygon =
counterclockwiseArea (outerLoop polygon)
+ List.sum (List.map counterclockwiseArea (innerLoops polygon))
-{-| Scale a polygon about a given center point by a given scale.
-
- point =
- Point2d.fromCoordinates ( 2, 1 )
-
- Polygon2d.scaleAbout point 2 rectangle
- --> Polygon2d.singleLoop
- --> [ Point2d.fromCoordinates ( 0, 1 )
- --> , Point2d.fromCoordinates ( 4, 1 )
- --> , Point2d.fromCoordinates ( 4, 3 )
- --> , Point2d.fromCoordinates ( 0, 3 )
- --> ]
-
-If the given scale is negative, the order of the polygon's vertices will be
-reversed so that the resulting polygon still has its outer vertices in
-counterclockwise order and its inner vertices in clockwise order.
-
--}
+{-| -}
scaleAbout : Point2d -> Float -> Polygon2d -> Polygon2d
scaleAbout point scale =
mapVertices (Point2d.scaleAbout point scale) (scale < 0)
-{-| Rotate a polygon around the given center point counterclockwise by the given
-angle (in radians).
-
- rectangle
- |> Polygon2d.rotateAround Point2d.origin
- (degrees 90)
- --> Polygon2d.singleLoop
- --> [ Point2d.fromCoordinates ( -1, 1 )
- --> , Point2d.fromCoordinates ( -1, 3 )
- --> , Point2d.fromCoordinates ( -2, 3 )
- --> , Point2d.fromCoordinates ( -2, 1 )
- --> ]
-
--}
+{-| -}
rotateAround : Point2d -> Float -> Polygon2d -> Polygon2d
rotateAround point angle =
mapVertices (Point2d.rotateAround point angle) False
-{-| Translate a polygon by the given displacement.
-
- displacement =
- Vector2d.fromComponents ( 2, 3 )
-
- Polygon2d.translateBy displacement rectangle
- --> Polygon2d.singleLoop
- --> [ Point2d.fromCoordinates ( 3, 4 )
- --> , Point2d.fromCoordinates ( 5, 4 )
- --> , Point2d.fromCoordinates ( 5, 5 )
- --> , Point2d.fromCoordinates ( 3, 5 )
- --> ]
-
--}
+{-| -}
translateBy : Vector2d -> Polygon2d -> Polygon2d
translateBy vector =
mapVertices (Point2d.translateBy vector) False
-{-| Translate a polygon in a given direction by a given distance;
-
- Polygon2d.translateIn direction distance
-
-is equivalent to
-
- Polygon2d.translateBy
- (Vector2d.withLength distance direction)
-
--}
+{-| -}
translateIn : Direction2d -> Float -> Polygon2d -> Polygon2d
translateIn direction distance polygon =
translateBy (Vector2d.withLength distance direction) polygon
-{-| Mirror a polygon across the given axis.
-
- Polygon2d.mirrorAcross Axis2d.x rectangle
- --> Polygon2d.singleLoop
- --> [ Point2d.fromCoordinates ( 1, -1 )
- --> , Point2d.fromCoordinates ( 3, -1 )
- --> , Point2d.fromCoordinates ( 3, -2 )
- --> , Point2d.fromCoordinates ( 1, -2 )
- --> ]
-
-The order of the polygon's vertices will be reversed so that the resulting
-polygon still has its outer vertices in counterclockwise order and its inner
-vertices in clockwise order.
-
--}
+{-| -}
mirrorAcross : Axis2d -> Polygon2d -> Polygon2d
mirrorAcross axis =
mapVertices (Point2d.mirrorAcross axis) True
@@ -501,87 +300,25 @@ mapVertices function invert polygon =
}
-{-| Take a polygon defined in global coordinates, and return it expressed
-in local coordinates relative to a given reference frame.
-
- localFrame =
- Frame2d.atPoint (Point2d.fromCoordinates ( 1, 2 ))
-
- Polygon2d.relativeTo localFrame rectangle
- --> Polygon2d.singleLoop
- --> [ Point2d.fromCoordinates ( 0, -1 )
- --> , Point2d.fromCoordinates ( 2, -1 )
- --> , Point2d.fromCoordinates ( 2, 0 )
- --> , Point2d.fromCoordinates ( 0, 0 )
- --> ]
-
-If the given frame is left-handed, the order of the polygon's vertices will be
-reversed so that the resulting polygon still has its outer vertices in
-counterclockwise order and its inner vertices in clockwise order.
-
--}
+{-| -}
relativeTo : Frame2d -> Polygon2d -> Polygon2d
relativeTo frame =
mapVertices (Point2d.relativeTo frame) (not (Frame2d.isRightHanded frame))
-{-| Take a polygon considered to be defined in local coordinates relative
-to a given reference frame, and return that polygon expressed in global
-coordinates.
-
- localFrame =
- Frame2d.atPoint (Point2d.fromCoordinates ( 1, 2 ))
-
- Polygon2d.placeIn localFrame rectangle
- --> Polygon2d.singleLoop
- --> [ Point2d.fromCoordinates ( 2, 3 )
- --> , Point2d.fromCoordinates ( 4, 3 )
- --> , Point2d.fromCoordinates ( 4, 4 )
- --> , Point2d.fromCoordinates ( 2, 4 )
- --> ]
-
-If the given frame is left-handed, the order of the polygon's vertices will be
-reversed so that the resulting polygon still has its outer vertices in
-counterclockwise order and its inner vertices in clockwise order.
-
--}
+{-| -}
placeIn : Frame2d -> Polygon2d -> Polygon2d
placeIn frame =
mapVertices (Point2d.placeIn frame) (not (Frame2d.isRightHanded frame))
-{-| Get the minimal bounding box containing a given polygon. Returns `Nothing`
-if the polygon has no vertices.
-
- Polygon2d.boundingBox rectangle
- --> Just
- --> (BoundingBox2d.fromExtrema
- --> { minX = 1
- --> , maxX = 3
- --> , minY = 1
- --> , maxY = 2
- --> }
- --> )
-
--}
+{-| -}
boundingBox : Polygon2d -> Maybe BoundingBox2d
boundingBox polygon =
BoundingBox2d.containingPoints (outerLoop polygon)
-{-| Triangulate a polygon. This uses the `TriangularMesh` data types from
-[`ianmackenzie/elm-triangular-mesh`](http://package.elm-lang.org/packages/ianmackenzie/elm-triangular-mesh/latest).
-Triangulation is useful for things like WebGL rendering; you can define a
-polygon just by specifying its outline (and holes, if it has any)
-
-
-
-then use this function to turn that polygon into a list of triangles which you
-can render using WebGL:
-
-
-
--}
+{-| -}
triangulate : Polygon2d -> TriangularMesh Point2d
triangulate polygon =
Monotone.triangulation polygon
diff --git a/src/Polyline2d.elm b/src/Polyline2d.elm
index 8626c324..7413165d 100644
--- a/src/Polyline2d.elm
+++ b/src/Polyline2d.elm
@@ -80,55 +80,19 @@ type alias Polyline2d =
Types.Polyline2d
-{-| Construct a polyline from a list of vertices:
-
- stepShape =
- Polyline2d.fromVertices
- [ Point2d.fromCoordinates ( 0, 0 )
- , Point2d.fromCoordinates ( 1, 0 )
- , Point2d.fromCoordinates ( 1, 1 )
- , Point2d.fromCoordinates ( 2, 1 )
- ]
-
--}
+{-| -}
fromVertices : List Point2d -> Polyline2d
fromVertices =
Types.Polyline2d
-{-| Get the vertices of a polyline.
-
- Polyline2d.vertices stepShape
- --> [ Point2d.fromCoordinates ( 0, 0 )
- --> , Point2d.fromCoordinates ( 1, 0 )
- --> , Point2d.fromCoordinates ( 1, 1 )
- --> , Point2d.fromCoordinates ( 2, 1 )
- --> ]
-
--}
+{-| -}
vertices : Polyline2d -> List Point2d
vertices (Types.Polyline2d vertices_) =
vertices_
-{-| Get the individual segments of a polyline.
-
- Polyline2d.segments stepShape
- --> [ LineSegment2d.fromEndpoints
- --> ( Point2d.fromCoordinates ( 0, 0 )
- --> , Point2d.fromCoordinates ( 1, 0 )
- --> )
- --> , LineSegment2d.fromEndpoints
- --> ( Point2d.fromCoordinates ( 1, 0 )
- --> , Point2d.fromCoordinates ( 1, 1 )
- --> )
- --> , LineSegment2d.fromEndpoints
- --> ( Point2d.fromCoordinates ( 1, 1 )
- --> , Point2d.fromCoordinates ( 2, 1 )
- --> )
- --> ]
-
--}
+{-| -}
segments : Polyline2d -> List LineSegment2d
segments polyline =
case vertices polyline of
@@ -139,192 +103,67 @@ segments polyline =
List.map2 LineSegment2d.from all rest
-{-| Get the overall length of a polyline (the sum of the lengths of its
-segments).
-
- Polyline2d.length stepShape
- --> 3
-
--}
+{-| -}
length : Polyline2d -> Float
length =
segments >> List.map LineSegment2d.length >> List.sum
-{-| Scale a polyline about a given center point by a given scale.
-
- point =
- Point2d.fromCoordinates ( 1, 0 )
-
- Polyline2d.scaleAbout point 2 stepShape
- --> Polyline2d.fromVertices
- --> [ Point2d.fromCoordinates ( -1, 0 )
- --> , Point2d.fromCoordinates ( 1, 0 )
- --> , Point2d.fromCoordinates ( 1, 2 )
- --> , Point2d.fromCoordinates ( 3, 2 )
- --> ]
-
--}
+{-| -}
scaleAbout : Point2d -> Float -> Polyline2d -> Polyline2d
scaleAbout point scale =
mapVertices (Point2d.scaleAbout point scale)
-{-| Rotate a polyline around the given center point counterclockwise by the
-given angle (in radians).
-
- stepShape
- |> Polyline2d.rotateAround Point2d.origin
- (degrees 90)
- --> Polyline2d.fromVertices
- --> [ Point2d.fromCoordinates ( 0, 0 )
- --> , Point2d.fromCoordinates ( 0, 1 )
- --> , Point2d.fromCoordinates ( -1, 1 )
- --> , Point2d.fromCoordinates ( -1, 2 )
- --> ]
-
--}
+{-| -}
rotateAround : Point2d -> Float -> Polyline2d -> Polyline2d
rotateAround point angle =
mapVertices (Point2d.rotateAround point angle)
-{-| Translate a polyline by the given displacement.
-
- displacement =
- Vector2d.fromComponents ( 2, 3 )
-
- Polyline2d.translateBy displacement stepShape
- --> Polyline2d.fromVertices
- --> [ Point2d.fromCoordinates ( 2, 3 )
- --> , Point2d.fromCoordinates ( 3, 3 )
- --> , Point2d.fromCoordinates ( 3, 4 )
- --> , Point2d.fromCoordinates ( 4, 4 )
- --> ]
-
--}
+{-| -}
translateBy : Vector2d -> Polyline2d -> Polyline2d
translateBy vector =
mapVertices (Point2d.translateBy vector)
-{-| Translate a polyline in a given direction by a given distance;
-
- Polyline2d.translateIn direction distance
-
-is equivalent to
-
- Polyline2d.translateBy
- (Vector2d.withLength distance direction)
-
--}
+{-| -}
translateIn : Direction2d -> Float -> Polyline2d -> Polyline2d
translateIn direction distance polyline =
translateBy (Vector2d.withLength distance direction) polyline
-{-| Mirror a polyline across the given axis.
-
- Polyline2d.mirrorAcross Axis2d.x stepShape
- --> Polyline2d.fromVertices
- --> [ Point2d.fromCoordinates ( 0, 0 )
- --> , Point2d.fromCoordinates ( 1, 0 )
- --> , Point2d.fromCoordinates ( 1, -1 )
- --> , Point2d.fromCoordinates ( 2, -1 )
- --> ]
-
--}
+{-| -}
mirrorAcross : Axis2d -> Polyline2d -> Polyline2d
mirrorAcross axis =
mapVertices (Point2d.mirrorAcross axis)
-{-| Project (flatten) a polyline onto the given axis.
-
- Polyline2d.projectOnto Axis2d.x stepShape
- --> Polyline2d.fromVertices
- --> [ Point2d.fromCoordinates ( 0, 0 )
- --> , Point2d.fromCoordinates ( 1, 0 )
- --> , Point2d.fromCoordinates ( 1, 0 )
- --> , Point2d.fromCoordinates ( 2, 0 )
- --> ]
-
--}
+{-| -}
projectOnto : Axis2d -> Polyline2d -> Polyline2d
projectOnto axis =
mapVertices (Point2d.projectOnto axis)
-{-| Transform each vertex of a polyline by the given function. All other
-transformations can be defined in terms of `mapVertices`; for example,
-
- Polyline2d.mirrorAcross axis
-
-is equivalent to
-
- Polyline2d.mapVertices (Point2d.mirrorAcross axis)
-
--}
+{-| -}
mapVertices : (Point2d -> Point2d) -> Polyline2d -> Polyline2d
mapVertices function =
vertices >> List.map function >> fromVertices
-{-| Take a polyline defined in global coordinates, and return it expressed
-in local coordinates relative to a given reference frame.
-
- localFrame =
- Frame2d.atPoint (Point2d.fromCoordinates ( 1, 2 ))
-
- Polyline2d.relativeTo localFrame stepShape
- --> Polyline2d.fromVertices
- --> [ Point2d.fromCoordinates ( -1, -2 )
- --> , Point2d.fromCoordinates ( 0, -2 )
- --> , Point2d.fromCoordinates ( 0, -1 )
- --> , Point2d.fromCoordinates ( 1, -1 )
- --> ]
-
--}
+{-| -}
relativeTo : Frame2d -> Polyline2d -> Polyline2d
relativeTo frame =
mapVertices (Point2d.relativeTo frame)
-{-| Take a polyline considered to be defined in local coordinates relative
-to a given reference frame, and return that polyline expressed in global
-coordinates.
-
- localFrame =
- Frame2d.atPoint (Point2d.fromCoordinates ( 1, 2 ))
-
- Polyline2d.placeIn localFrame stepShape
- --> Polyline2d.fromVertices
- --> [ Point2d.fromCoordinates ( 1, 2 )
- --> , Point2d.fromCoordinates ( 2, 2 )
- --> , Point2d.fromCoordinates ( 2, 3 )
- --> , Point2d.fromCoordinates ( 3, 3 )
- --> ]
-
--}
+{-| -}
placeIn : Frame2d -> Polyline2d -> Polyline2d
placeIn frame =
mapVertices (Point2d.placeIn frame)
-{-| Get the minimal bounding box containing a given polyline. Returns `Nothing`
-if the polyline has no vertices.
-
- Polyline2d.boundingBox stepShape
- --> Just
- --> (BoundingBox2d.fromExtrema
- --> { minX = 0
- --> , maxX = 2
- --> , minY = 0
- --> , maxY = 1
- --> }
- --> )
-
--}
+{-| -}
boundingBox : Polyline2d -> Maybe BoundingBox2d
boundingBox polyline =
BoundingBox2d.containingPoints (vertices polyline)
diff --git a/src/Polyline3d.elm b/src/Polyline3d.elm
index c9e06620..28d9259d 100644
--- a/src/Polyline3d.elm
+++ b/src/Polyline3d.elm
@@ -85,78 +85,25 @@ type alias Polyline3d =
Types.Polyline3d
-{-| Construct a polyline from its vertices:
-
- examplePolyline =
- Polyline3d.fromVertices
- [ Point2d.fromCoordinates ( 0, 0, 0 )
- , Point2d.fromCoordinates ( 1, 0, 0 )
- , Point2d.fromCoordinates ( 1, 2, 0 )
- , Point2d.fromCoordinates ( 1, 2, 3 )
- ]
-
--}
+{-| -}
fromVertices : List Point3d -> Polyline3d
fromVertices =
Types.Polyline3d
-{-| Construct a 3D polyline lying _on_ a sketch plane by providing a 2D polyline
-specified in XY coordinates _within_ the sketch plane.
-
- Polyline3d.on SketchPlane3d.yz <|
- Polyline2d.fromVertices
- [ Point2d.fromCoordinates ( 0, 0 )
- , Point2d.fromCoordinates ( 1, 0 )
- , Point2d.fromCoordinates ( 1, 1 )
- , Point2d.fromCoordinates ( 2, 1 )
- ]
- --> Polyline3d.fromVertices
- --> [ Point3d.fromCoordinates ( 0, 0, 0 )
- --> , Point3d.fromCoordinates ( 0, 1, 0 )
- --> , Point3d.fromCoordinates ( 0, 1, 1 )
- --> , Point3d.fromCoordinates ( 0, 2, 1 )
- --> ]
-
--}
+{-| -}
on : SketchPlane3d -> Polyline2d -> Polyline3d
on sketchPlane =
Polyline2d.vertices >> List.map (Point3d.on sketchPlane) >> fromVertices
-{-| Get the vertices of a polyline.
-
- Polyline3d.vertices examplePolyline
- --> [ Point3d.fromCoordinates ( 0, 0, 0 )
- --> , Point3d.fromCoordinates ( 1, 0, 0 )
- --> , Point3d.fromCoordinates ( 1, 2, 0 )
- --> , Point3d.fromCoordinates ( 1, 2, 3 )
- --> ]
-
--}
+{-| -}
vertices : Polyline3d -> List Point3d
vertices (Types.Polyline3d vertices_) =
vertices_
-{-| Get the individual segments of a polyline.
-
- Polyline3d.segments examplePolyline
- --> [ LineSegment3d.fromEndpoints
- --> ( Point3d.fromCoordinates ( 0, 0, 0 )
- --> , Point3d.fromCoordinates ( 1, 0, 0 )
- --> )
- --> , LineSegment3d.fromEndpoints
- --> ( Point3d.fromCoordinates ( 1, 0, 0 )
- --> , Point3d.fromCoordinates ( 1, 2, 0 )
- --> )
- --> , LineSegment3d.fromEndpoints
- --> ( Point3d.fromCoordinates ( 1, 2, 0 )
- --> , Point3d.fromCoordinates ( 1, 2, 3 )
- --> )
- --> ]
-
--}
+{-| -}
segments : Polyline3d -> List LineSegment3d
segments polyline =
case vertices polyline of
@@ -167,193 +114,67 @@ segments polyline =
List.map2 LineSegment3d.from all rest
-{-| Get the overall length of a polyline (the sum of the lengths of its
-segments).
-
- Polyline3d.length examplePolyline
- --> 6
-
--}
+{-| -}
length : Polyline3d -> Float
length =
segments >> List.map LineSegment3d.length >> List.sum
-{-| Scale a polyline about the given center point by the given scale.
-
- point =
- Point3d.fromCoordinates ( 1, 0, 0 )
-
- Polyline3d.scaleAbout point 2 examplePolyline
- --> Polyline3d.fromVertices
- --> [ Point3d.fromCoordinates ( -1, 0, 0 )
- --> , Point3d.fromCoordinates ( 1, 0, 0 )
- --> , Point3d.fromCoordinates ( 1, 4, 0 )
- --> , Point3d.fromCoordinates ( 1, 4, 6 )
- --> ]
-
--}
+{-| -}
scaleAbout : Point3d -> Float -> Polyline3d -> Polyline3d
scaleAbout point scale =
mapVertices (Point3d.scaleAbout point scale)
-{-| Rotate a polyline around the given axis by the given angle (in radians).
-
- examplePolyline
- |> Polyline3d.rotateAround Axis3d.z (degrees 90)
- --> Polyline3d.fromVertices
- --> [ Point3d.fromCoordinates ( 0, 0, 0 )
- --> , Point3d.fromCoordinates ( 0, 1, 0 )
- --> , Point3d.fromCoordinates ( -2, 1, 0 )
- --> , Point3d.fromCoordinates ( -2, 1, 3 )
- --> ]
-
--}
+{-| -}
rotateAround : Axis3d -> Float -> Polyline3d -> Polyline3d
rotateAround axis angle =
mapVertices (Point3d.rotateAround axis angle)
-{-| Translate a polyline by the given displacement.
-
- displacement =
- Vector3d.fromComponents ( 1, 2, 3 )
-
- Polyline3d.translateBy displacement examplePolyline
- --> Polyline3d.fromVertices
- --> [ Point3d.fromCoordinates ( 1, 2, 3 )
- --> , Point3d.fromCoordinates ( 2, 2, 3 )
- --> , Point3d.fromCoordinates ( 2, 4, 3 )
- --> , Point3d.fromCoordinates ( 2, 4, 6 )
- --> ]
-
--}
+{-| -}
translateBy : Vector3d -> Polyline3d -> Polyline3d
translateBy vector =
mapVertices (Point3d.translateBy vector)
-{-| Translate a polyline in a given direction by a given distance;
-
- Polyline3d.translateIn direction distance
-
-is equivalent to
-
- Polyline3d.translateBy
- (Vector3d.withLength distance direction)
-
--}
+{-| -}
translateIn : Direction3d -> Float -> Polyline3d -> Polyline3d
translateIn direction distance polyline =
translateBy (Vector3d.withLength distance direction) polyline
-{-| Mirror a polyline across the given plane.
-
- Polyline3d.mirrorAcross Plane3d.xz examplePolyline
- --> Polyline3d.fromVertices
- --> [ Point3d.fromCoordinates ( 0, 0, 0 )
- --> , Point3d.fromCoordinates ( 1, 0, 0 )
- --> , Point3d.fromCoordinates ( 1, -2, 0 )
- --> , Point3d.fromCoordinates ( 1, -2, 3 )
- --> ]
-
--}
+{-| -}
mirrorAcross : Plane3d -> Polyline3d -> Polyline3d
mirrorAcross plane =
mapVertices (Point3d.mirrorAcross plane)
-{-| Find the [orthographic projection](https://en.wikipedia.org/wiki/Orthographic_projection)
-of a polyline onto a plane. This will flatten the polyline.
-
- Polyline3d.projectOnto Plane3d.xz examplePolyline
- --> Polyline3d.fromVertices
- --> [ Point3d.fromCoordinates ( 0, 0, 0 )
- --> , Point3d.fromCoordinates ( 1, 0, 0 )
- --> , Point3d.fromCoordinates ( 1, 0, 0 )
- --> , Point3d.fromCoordinates ( 1, 0, 3 )
- --> ]
-
--}
+{-| -}
projectOnto : Plane3d -> Polyline3d -> Polyline3d
projectOnto plane =
mapVertices (Point3d.projectOnto plane)
-{-| Transform each vertex of a polyline by the given function. All other
-transformations can be defined in terms of `mapVertices`; for example,
-
- Polyline3d.mirrorAcross plane
-
-is equivalent to
-
- Polyline3d.mapVertices (Point3d.mirrorAcross plane)
-
--}
+{-| -}
mapVertices : (Point3d -> Point3d) -> Polyline3d -> Polyline3d
mapVertices function =
vertices >> List.map function >> fromVertices
-{-| Take a polyline defined in global coordinates, and return it expressed
-in local coordinates relative to a given reference frame.
-
- localFrame =
- Frame3d.atPoint
- (Point3d.fromCoordinates ( 1, 2, 3 ))
-
- Polyline3d.relativeTo localFrame examplePolyline
- --> Polyline3d.fromVertices
- --> [ Point3d.fromCoordinates ( -1, -2, -3 )
- --> , Point3d.fromCoordinates ( 0, -2, -3 )
- --> , Point3d.fromCoordinates ( 0, 0, -3 )
- --> , Point3d.fromCoordinates ( 0, 0, 0 )
- --> ]
-
--}
+{-| -}
relativeTo : Frame3d -> Polyline3d -> Polyline3d
relativeTo frame =
mapVertices (Point3d.relativeTo frame)
-{-| Take a polyline considered to be defined in local coordinates relative
-to a given reference frame, and return that polyline expressed in global
-coordinates.
-
- localFrame =
- Frame3d.atPoint
- (Point3d.fromCoordinates ( 1, 2, 3 ))
-
- Polyline3d.placeIn localFrame examplePolyline
- --> Polyline3d.fromVertices
- --> [ Point3d.fromCoordinates ( 1, 2, 3 )
- --> , Point3d.fromCoordinates ( 2, 2, 3 )
- --> , Point3d.fromCoordinates ( 2, 4, 3 )
- --> , Point3d.fromCoordinates ( 2, 4, 6 )
- --> ]
-
--}
+{-| -}
placeIn : Frame3d -> Polyline3d -> Polyline3d
placeIn frame =
mapVertices (Point3d.placeIn frame)
-{-| Project a polyline into a given sketch plane. Conceptually, this finds the
-[orthographic projection](https://en.wikipedia.org/wiki/Orthographic_projection)
-of the polyline onto the plane and then expresses the projected polyline in 2D
-sketch coordinates.
-
- Polyline3d.projectInto Plane3d.xy examplePolyline
- --> Polyline2d.fromVertices
- --> [ Point2d.fromCoordinates ( 0, 0 )
- --> , Point2d.fromCoordinates ( 1, 0 )
- --> , Point2d.fromCoordinates ( 1, 2 )
- --> , Point2d.fromCoordinates ( 1, 2 )
- --> ]
-
--}
+{-| -}
projectInto : SketchPlane3d -> Polyline3d -> Polyline2d
projectInto sketchPlane =
vertices
@@ -361,22 +182,7 @@ projectInto sketchPlane =
>> Polyline2d.fromVertices
-{-| Get the minimal bounding box containing a given polyline. Returns `Nothing`
-if the polyline has no vertices.
-
- Polyline3d.boundingBox examplePolyline
- --> Just
- --> (BoundingBox3d.fromExtrema
- --> { minX = 0
- --> , maxX = 1
- --> , minY = 0
- --> , maxY = 2
- --> , minZ = 0
- --> , maxZ = 3
- --> }
- --> )
-
--}
+{-| -}
boundingBox : Polyline3d -> Maybe BoundingBox3d
boundingBox polyline =
BoundingBox3d.containingPoints (vertices polyline)
diff --git a/src/QuadraticSpline2d.elm b/src/QuadraticSpline2d.elm
index ba184e6c..3e1dc107 100644
--- a/src/QuadraticSpline2d.elm
+++ b/src/QuadraticSpline2d.elm
@@ -126,97 +126,45 @@ type alias QuadraticSpline2d =
Types.QuadraticSpline2d
-{-| Construct a spline from its start point, control point and end point:
-
- exampleSpline =
- QuadraticSpline2d.with
- { startPoint =
- Point2d.fromCoordinates ( 1, 1 )
- , controlPoint =
- Point2d.fromCoordinates ( 3, 4 )
- , endPoint =
- Point2d.fromCoordinates ( 5, 1 )
- }
-
--}
+{-| -}
with : { startPoint : Point2d, controlPoint : Point2d, endPoint : Point2d } -> QuadraticSpline2d
with =
Types.QuadraticSpline2d
-{-| Get the start point of a spline.
-
- QuadraticSpline2d.startPoint exampleSpline
- --> Point2d.fromCoordinates ( 1, 1 )
-
--}
+{-| -}
startPoint : QuadraticSpline2d -> Point2d
startPoint (Types.QuadraticSpline2d spline) =
spline.startPoint
-{-| Get the end point of a spline.
-
- QuadraticSpline2d.endPoint exampleSpline
- --> Point2d.fromCoordinates ( 5, 1 )
-
--}
+{-| -}
endPoint : QuadraticSpline2d -> Point2d
endPoint (Types.QuadraticSpline2d spline) =
spline.endPoint
-{-| Get the control point of a spline.
-
- QuadraticSpline2d.controlPoint exampleSpline
- --> Point2d.fromCoordinates ( 3, 4 )
-
--}
+{-| -}
controlPoint : QuadraticSpline2d -> Point2d
controlPoint (Types.QuadraticSpline2d spline) =
spline.controlPoint
-{-| Get the start derivative of a spline. This is equal to twice the vector from
-the spline's first control point to its second.
-
- QuadraticSpline2d.startDerivative exampleSpline
- --> Vector2d.fromComponents ( 4, 6 )
-
--}
+{-| -}
startDerivative : QuadraticSpline2d -> Vector2d
startDerivative spline =
Vector2d.from (startPoint spline) (controlPoint spline)
|> Vector2d.scaleBy 2
-{-| Get the end derivative of a spline. This is equal to twice the vector from
-the spline's second control point to its third.
-
- QuadraticSpline2d.endDerivative exampleSpline
- --> Vector2d.fromComponents ( 4, -6 )
-
--}
+{-| -}
endDerivative : QuadraticSpline2d -> Vector2d
endDerivative spline =
Vector2d.from (controlPoint spline) (endPoint spline)
|> Vector2d.scaleBy 2
-{-| Compute a bounding box for a given spline. It is not guaranteed that the
-result will be the _smallest_ possible bounding box, since for efficiency the
-bounding box is computed from the spline's control points (which cover a larger
-area than the spline itself).
-
- QuadraticSpline2d.boundingBox exampleSpline
- --> BoundingBox2d.fromExtrema
- --> { minX = 1
- --> , maxX = 5
- --> , minY = 1
- --> , maxY = 4
- --> }
-
--}
+{-| -}
boundingBox : QuadraticSpline2d -> BoundingBox2d
boundingBox spline =
let
@@ -237,18 +185,7 @@ boundingBox spline =
}
-{-| Get the point along a spline at a given parameter value:
-
- QuadraticSpline2d.pointOn exampleSpline 0
- --> Point2d.fromCoordinates ( 1, 1 )
-
- QuadraticSpline2d.pointOn exampleSpline 0.5
- --> Point2d.fromCoordinates ( 3, 2.5 )
-
- QuadraticSpline2d.pointOn exampleSpline 1
- --> Point2d.fromCoordinates ( 5, 1 )
-
--}
+{-| -}
pointOn : QuadraticSpline2d -> ParameterValue -> Point2d
pointOn spline parameterValue =
let
@@ -273,39 +210,13 @@ pointOn spline parameterValue =
Point2d.interpolateFrom q1 q2 t
-{-| Get points along a spline at a given set of parameter values:
-
- exampleSpline
- |> QuadraticSpline2d.pointsAt
- (ParameterValue.steps 2)
- --> [ Point2d.fromCoordinates ( 1, 1 )
- --> , Point2d.fromCoordinates ( 3, 2.5 )
- --> , Point2d.fromCoordinates ( 5, 1 )
- --> ]
-
--}
+{-| -}
pointsAt : List ParameterValue -> QuadraticSpline2d -> List Point2d
pointsAt parameterValues spline =
List.map (pointOn spline) parameterValues
-{-| Get the first derivative of a spline at a given parameter value.
-
- QuadraticSpline2d.derivative exampleSpline
- ParameterValue.zero
- --> Vector2d.fromComponents ( 4, 6 )
-
- QuadraticSpline2d.derivative exampleSpline
- ParameterValue.half
- --> Vector2d.fromComponents ( 4, 0 )
-
- QuadraticSpline2d.derivative exampleSpline
- ParameterValue.one
- --> Vector2d.fromComponents ( 4, -6 )
-
-Note that the derivative interpolates linearly from end to end.
-
--}
+{-| -}
firstDerivative : QuadraticSpline2d -> ParameterValue -> Vector2d
firstDerivative spline parameterValue =
let
@@ -330,17 +241,7 @@ firstDerivative spline parameterValue =
Vector2d.interpolateFrom v1 v2 t |> Vector2d.scaleBy 2
-{-| Evaluate the first derivative of a spline at a range of parameter values:
-
- exampleSpline
- |> QuadraticSpline2d.firstDerivativesAt
- (ParameterValue.steps 2)
- --> [ Vector2d.fromComponents ( 4, 6 )
- --> , Vector2d.fromComponents ( 4, 0 )
- --> , Vector2d.fromComponents ( 4, -6 )
- --> ]
-
--}
+{-| -}
firstDerivativesAt : List ParameterValue -> QuadraticSpline2d -> List Vector2d
firstDerivativesAt parameterValues spline =
List.map (firstDerivative spline) parameterValues
@@ -390,28 +291,13 @@ derivativeMagnitude spline =
2 * sqrt (x13 * x13 + y13 * y13)
-{-| If a curve has zero length (consists of just a single point), then we say
-that it is 'degenerate'. Some operations such as computing tangent directions
-are not defined on degenerate curves.
-
-A `Nondegenerate` value represents a spline that is definitely not degenerate.
-It is used as input to functions such as `QuadraticSpline2d.tangentDirection`
-and can be constructed using `QuadraticSpline2d.nondegenerate`.
-
--}
+{-| -}
type Nondegenerate
= NonZeroSecondDerivative QuadraticSpline2d Direction2d
| NonZeroFirstDerivative QuadraticSpline2d Direction2d
-{-| Attempt to construct a nondegenerate spline from a general
-`QuadraticSpline2d`. If the spline is in fact degenerate (consists of a single
-point), returns an `Err` with that point.
-
- QuadraticSpline2d.nondegenerate exampleSpline
- --> Ok nondegenerateExampleSpline
-
--}
+{-| -}
nondegenerate : QuadraticSpline2d -> Result Point2d Nondegenerate
nondegenerate spline =
case Vector2d.direction (secondDerivative spline) of
@@ -433,13 +319,7 @@ nondegenerate spline =
Err (startPoint spline)
-{-| Convert a nondegenerate spline back to a general `QuadraticSpline2d`.
-
- QuadraticSpline2d.fromNondegenerate
- nondegenerateExampleSpline
- --> exampleSpline
-
--}
+{-| -}
fromNondegenerate : Nondegenerate -> QuadraticSpline2d
fromNondegenerate nondegenerateSpline =
case nondegenerateSpline of
@@ -450,25 +330,7 @@ fromNondegenerate nondegenerateSpline =
spline
-{-| Get the tangent direction to a nondegenerate spline at a given parameter
-value:
-
- QuadraticSpline2d.tangentDirection
- nondegenerateExampleSpline
- ParameterValue.zero
- --> Direction2d.fromAngle (degrees 56.31)
-
- QuadraticSpline2d.tangentDirection
- nondegenerateExampleSpline
- ParameterValue.half
- --> Direction2d.x
-
- QuadraticSpline2d.tangentDirection
- nondegenerateExampleSpline
- ParameterValue.one
- --> Direction2d.fromAngle (degrees -56.31)
-
--}
+{-| -}
tangentDirection : Nondegenerate -> ParameterValue -> Direction2d
tangentDirection nondegenerateSpline parameterValue =
case nondegenerateSpline of
@@ -505,33 +367,13 @@ tangentDirection nondegenerateSpline parameterValue =
firstDerivativeDirection
-{-| Get tangent directions to a nondegenerate spline at a given set of parameter
-values:
-
- nondegenerateExampleSpline
- |> QuadraticSpline2d.tangentDirectionsAt
- (ParameterValue.steps 2)
- --> [ Direction2d.fromAngle (degrees 56.31)
- --> , Direction2d.x
- --> , Direction2d.fromAngle (degrees -56.31)
- --> ]
-
--}
+{-| -}
tangentDirectionsAt : List ParameterValue -> Nondegenerate -> List Direction2d
tangentDirectionsAt parameterValues nondegenerateSpline =
List.map (tangentDirection nondegenerateSpline) parameterValues
-{-| Get both the point and tangent direction of a nondegenerate spline at a
-given parameter value:
-
- QuadraticSpline2d.sample nondegenerateExampleSpline
- ParameterValue.half
- --> ( Point2d.fromCoordinates ( 3, 2.5 )
- --> , Direction2d.x
- --> )
-
--}
+{-| -}
sample : Nondegenerate -> ParameterValue -> ( Point2d, Direction2d )
sample nondegenerateSpline parameterValue =
( pointOn (fromNondegenerate nondegenerateSpline) parameterValue
@@ -539,43 +381,13 @@ sample nondegenerateSpline parameterValue =
)
-{-| Get points and tangent directions of a nondegenerate spline at a given set
-of parameter values:
-
- nondegenerateExampleSpline
- |> QuadraticSpline2d.samplesAt
- (ParameterValue.steps 2)
- --> [ ( Point2d.fromCoordinates ( 1, 1 )
- --> , Direction2d.fromAngle (degrees 56.31)
- --> )
- --> , ( Point2d.fromCoordinates ( 3, 2.5 )
- --> , Direction2d.x
- --> )
- --> , ( Point2d.fromCoordinates ( 5, 1 )
- --> , Direction2d.fromAngle (degrees -56.31)
- --> )
- --> ]
-
--}
+{-| -}
samplesAt : List ParameterValue -> Nondegenerate -> List ( Point2d, Direction2d )
samplesAt parameterValues nondegenerateSpline =
List.map (sample nondegenerateSpline) parameterValues
-{-| Reverse a spline so that the start point becomes the end point, and vice
-versa.
-
- QuadraticSpline2d.reverse exampleSpline
- --> QuadraticSpline2d.with
- --> { startPoint =
- --> Point2d.fromCoordinates ( 5, 1 )
- --> , controlPoint =
- --> Point2d.fromCoordinates ( 3, 4 )
- --> , endPoint =
- --> Point2d.fromCoordinates ( 1, 1 )
- --> }
-
--}
+{-| -}
reverse : QuadraticSpline2d -> QuadraticSpline2d
reverse spline =
with
@@ -585,140 +397,43 @@ reverse spline =
}
-{-| Scale a spline about the given center point by the given scale.
-
- examplePolyline
- |> QuadraticSpline2d.scaleAbout Point2d.origin 2
- --> QuadraticSpline2d.with
- --> { startPoint =
- --> Point2d.fromCoordinates ( 2, 2 )
- --> , controlPoint =
- --> Point2d.fromCoordinates ( 6, 8 )
- --> , endPoint =
- --> Point2d.fromCoordinates ( 10, 2 )
- --> }
-
--}
+{-| -}
scaleAbout : Point2d -> Float -> QuadraticSpline2d -> QuadraticSpline2d
scaleAbout point scale =
mapControlPoints (Point2d.scaleAbout point scale)
-{-| Rotate a spline counterclockwise around a given center point by a given
-angle (in radians).
-
- examplePolyline
- |> QuadraticSpline2d.rotateAround Point2d.origin
- (degrees 90)
- --> QuadraticSpline2d.with
- --> { startPoint =
- --> Point2d.fromCoordinates ( -1, 1 )
- --> , controlPoint =
- --> Point2d.fromCoordinates ( -4, 3 )
- --> , endPoint =
- --> Point2d.fromCoordinates ( -1, 5 )
- --> }
-
--}
+{-| -}
rotateAround : Point2d -> Float -> QuadraticSpline2d -> QuadraticSpline2d
rotateAround point angle =
mapControlPoints (Point2d.rotateAround point angle)
-{-| Translate a spline by a given displacement.
-
- displacement =
- Vector2d.fromComponents ( 2, 3 )
-
- exampleSpline
- |> QuadraticSpline2d.translateBy displacement
- --> QuadraticSpline2d.with
- --> { startPoint =
- --> Point2d.fromCoordinates ( 3, 4 )
- --> , controlPoint =
- --> Point2d.fromCoordinates ( 5, 7 )
- --> , endPoint =
- --> Point2d.fromCoordinates ( 7, 4 )
- --> )
-
--}
+{-| -}
translateBy : Vector2d -> QuadraticSpline2d -> QuadraticSpline2d
translateBy displacement =
mapControlPoints (Point2d.translateBy displacement)
-{-| Translate a spline in a given direction by a given distance;
-
- QuadraticSpline2d.translateIn direction distance
-
-is equivalent to
-
- QuadraticSpline2d.translateBy
- (Vector2d.withLength distance direction)
-
--}
+{-| -}
translateIn : Direction2d -> Float -> QuadraticSpline2d -> QuadraticSpline2d
translateIn direction distance spline =
translateBy (Vector2d.withLength distance direction) spline
-{-| Mirror a spline across an axis.
-
- QuadraticSpline2d.mirrorAcross Axis2d.x exampleSpline
- --> QuadraticSpline2d.with
- --> { startPoint =
- --> Point2d.fromCoordinates ( 1, -1 )
- --> , controlPoint =
- --> Point2d.fromCoordinates ( 3, -4 )
- --> , endPoint =
- --> Point2d.fromCoordinates ( 5, -1 )
- --> }
-
--}
+{-| -}
mirrorAcross : Axis2d -> QuadraticSpline2d -> QuadraticSpline2d
mirrorAcross axis =
mapControlPoints (Point2d.mirrorAcross axis)
-{-| Take a spline defined in global coordinates, and return it expressed in
-local coordinates relative to a given reference frame.
-
- localFrame =
- Frame2d.atCoordinates ( 1, 2 )
-
- QuadraticSpline2d.relativeTo localFrame exampleSpline
- --> QuadraticSpline2d.with
- --> { startPoint =
- --> Point2d.fromCoordinates ( 0, -1 )
- --> , controlPoint =
- --> Point2d.fromCoordinates ( 2, 2 )
- --> , endPoint =
- --> Point2d.fromCoordinates ( 4, -1 )
- --> }
-
--}
+{-| -}
relativeTo : Frame2d -> QuadraticSpline2d -> QuadraticSpline2d
relativeTo frame =
mapControlPoints (Point2d.relativeTo frame)
-{-| Take a spline considered to be defined in local coordinates relative to a
-given reference frame, and return that spline expressed in global coordinates.
-
- localFrame =
- Frame2d.atCoordinates ( 1, 2 )
-
- QuadraticSpline2d.placeIn localFrame exampleSpline
- --> QuadraticSpline2d.with
- --> { startPoint =
- --> Point2d.fromCoordinates ( 2, 3 )
- --> , controlPoint =
- --> Point2d.fromCoordinates ( 4, 6 )
- --> , endPoint =
- --> Point2d.fromCoordinates ( 6, 3 )
- --> }
-
--}
+{-| -}
placeIn : Frame2d -> QuadraticSpline2d -> QuadraticSpline2d
placeIn frame =
mapControlPoints (Point2d.placeIn frame)
@@ -733,61 +448,13 @@ mapControlPoints function spline =
}
-{-| Split a spline into two roughly equal halves.
-
- QuadraticSpline2d.bisect exampleSpline
- --> ( QuadraticSpline2d.with
- --> { startPoint =
- --> Point2d.fromCoordinates ( 1, 1 )
- --> , controlPoint =
- --> Point2d.fromCoordinates ( 2, 2.5 )
- --> , endPoint =
- --> Point2d.fromCoordinates ( 3, 2.5 )
- --> }
- --> , QuadraticSpline2d.with
- --> { startPoint =
- --> Point2d.fromCoordinates ( 3, 2.5 )
- --> , controlPoint =
- --> Point2d.fromCoordinates ( 4, 2.5 )
- --> , endPoint =
- --> Point2d.fromCoordinates ( 5, 1 )
- --> }
- --> )
-
-Equivalent to `QuadraticSpline2d.splitAt ParameterValue.half`.
-
--}
+{-| -}
bisect : QuadraticSpline2d -> ( QuadraticSpline2d, QuadraticSpline2d )
bisect =
splitAt ParameterValue.half
-{-| Split a spline at a particular parameter value, resulting in two smaller
-splines.
-
- parameterValue =
- ParameterValue.clamped 0.75
-
- QuadraticSpline2d.splitAt parameterValue exampleSpline
- --> ( QuadraticSpline2d.with
- --> { startPoint =
- --> Point2d.fromCoordinates ( 1, 1 )
- --> , controlPoint =
- --> Point2d.fromCoordinates ( 2.5, 3.25 )
- --> , endPoint =
- --> Point2d.fromCoordinates ( 4, 2.125 )
- --> }
- --> , QuadraticSpline2d.with
- --> { startPoint =
- --> Point2d.fromCoordinates ( 4, 2.125 )
- --> , controlPoint =
- --> Point2d.fromCoordinates ( 4.5, 1.75 )
- --> , endPoint =
- --> Point2d.fromCoordinates ( 5, 1 )
- --> }
- --> )
-
--}
+{-| -}
splitAt : ParameterValue -> QuadraticSpline2d -> ( QuadraticSpline2d, QuadraticSpline2d )
splitAt parameterValue spline =
let
@@ -817,8 +484,7 @@ splitAt parameterValue spline =
)
-{-| A spline that has been parameterized by arc length.
--}
+{-| -}
type ArcLengthParameterized
= ArcLengthParameterized
{ underlyingSpline : QuadraticSpline2d
@@ -827,17 +493,7 @@ type ArcLengthParameterized
}
-{-| Build an arc length parameterization of the given spline, with a given
-accuracy. Generally speaking, all operations on the resulting
-`ArcLengthParameterized` value will be accurate to within the specified maximum
-error.
-
- parameterizedSpline =
- exampleSpline
- |> QuadraticSpline2d.arcLengthParameterized
- { maxError = 1.0e-4 }
-
--}
+{-| -}
arcLengthParameterized : { maxError : Float } -> QuadraticSpline2d -> ArcLengthParameterized
arcLengthParameterized { maxError } spline =
let
@@ -856,37 +512,14 @@ arcLengthParameterized { maxError } spline =
}
-{-| Find the total arc length of a spline:
-
- QuadraticSpline2d.arcLength parameterizedSpline
- --> 5.1986
-
-In this example, the result will be accurate to within `1.0e-4` since that was
-the tolerance used when constructing `parameterizedSpline`.
-
--}
+{-| -}
arcLength : ArcLengthParameterized -> Float
arcLength parameterizedSpline =
arcLengthParameterization parameterizedSpline
|> ArcLengthParameterization.totalArcLength
-{-| Try to get the point along a spline at a given arc length. For example, to
-get the point a quarter of the way along `exampleSpline`:
-
- QuadraticSpline2d.pointAlong parameterizedSpline
- (arcLength / 4)
- --> Just (Point2d.fromCoordinates ( 1.8350, 1.9911 ))
-
-Note that this is not the same as evaulating at a parameter value of 1/4:
-
- QuadraticSpline2d.pointOn exampleSpline 0.25
- --> Point2d.fromCoordinates ( 2, 2.125 )
-
-If the given arc length is less than zero or greater than the arc length of the
-spline, returns `Nothing`.
-
--}
+{-| -}
pointAlong : ArcLengthParameterized -> Float -> Maybe Point2d
pointAlong (ArcLengthParameterized parameterized) distance =
parameterized.parameterization
@@ -894,19 +527,7 @@ pointAlong (ArcLengthParameterized parameterized) distance =
|> Maybe.map (pointOn parameterized.underlyingSpline)
-{-| Try to get the tangent direction along a spline at a given arc length. To
-get the tangent direction a quarter of the way along `exampleSpline`:
-
- QuadraticSpline2d.tangentDirectionAlong
- parameterizedSpline
- (arcLength / 4)
- --> Just (Direction2d.fromAngle (degrees 41.145))
-
-If the given arc length is less than zero or greater than the arc length of the
-spline (or if the derivative of the spline happens to be exactly zero at the
-given arc length), returns `Nothing`.
-
--}
+{-| -}
tangentDirectionAlong : ArcLengthParameterized -> Float -> Maybe Direction2d
tangentDirectionAlong (ArcLengthParameterized parameterized) distance =
case parameterized.nondegenerateSpline of
@@ -919,21 +540,7 @@ tangentDirectionAlong (ArcLengthParameterized parameterized) distance =
Nothing
-{-| Try to get the point and tangent direction along a spline at a given arc
-length. To get the point and tangent direction a quarter of the way along
-`exampleSpline`:
-
- QuadraticSpline2d.sampleAlong parameterizedSpline
- (0.25 * arcLength)
- --> Just
- --> ( Point2d.fromCoordinates ( 1.8350, 1.9911 )
- --> , Direction2d.fromAngle (degrees 41.145)
- --> )
-
-If the given arc length is less than zero or greater than the arc length of the
-spline (or if the spline is degenerate), returns `Nothing`.
-
--}
+{-| -}
sampleAlong : ArcLengthParameterized -> Float -> Maybe ( Point2d, Direction2d )
sampleAlong (ArcLengthParameterized parameterized) distance =
case parameterized.nondegenerateSpline of
@@ -952,17 +559,13 @@ arcLengthParameterization (ArcLengthParameterized parameterized) =
parameterized.parameterization
-{-| Get the original `QuadraticSpline2d` from which an `ArcLengthParameterized`
-value was constructed.
--}
+{-| -}
fromArcLengthParameterized : ArcLengthParameterized -> QuadraticSpline2d
fromArcLengthParameterized (ArcLengthParameterized parameterized) =
parameterized.underlyingSpline
-{-| Get the second derivative of a spline (for a quadratic spline, this is a
-constant).
--}
+{-| -}
secondDerivative : QuadraticSpline2d -> Vector2d
secondDerivative spline =
let
diff --git a/src/QuadraticSpline3d.elm b/src/QuadraticSpline3d.elm
index 8f8934f7..816424dd 100644
--- a/src/QuadraticSpline3d.elm
+++ b/src/QuadraticSpline3d.elm
@@ -137,46 +137,13 @@ type alias QuadraticSpline3d =
Types.QuadraticSpline3d
-{-| Construct a spline from its start point, control point and end point:
-
- exampleSpline =
- QuadraticSpline3d.with
- { startPoint =
- Point3d.fromCoordinates ( 1, 1, 1 )
- , controlPoint =
- Point3d.fromCoordinates ( 3, 2, 1 )
- , endPoint =
- Point3d.fromCoordinates ( 3, 3, 3 )
- }
-
--}
+{-| -}
with : { startPoint : Point3d, controlPoint : Point3d, endPoint : Point3d } -> QuadraticSpline3d
with =
Types.QuadraticSpline3d
-{-| Construct a 3D spline lying _on_ a sketch plane by providing a 2D spline
-specified in XY coordinates _within_ the sketch plane.
-
- QuadraticSpline3d.on SketchPlane3d.xz <|
- QuadraticSpline2d.with
- { startPoint =
- Point2d.fromCoordinates ( 1, 1 )
- , controlPoint =
- Point2d.fromCoordinates ( 3, 4 )
- , endPoint =
- Point2d.fromCoordinates ( 5, 1 )
- }
- --> QuadraticSpline3d.with
- --> { startPoint =
- --> Point3d.fromCoordinates ( 1, 0, 1 )
- --> , controlPoint =
- --> Point3d.fromCoordinates ( 3, 0, 4 )
- --> , endPoint =
- --> Point3d.fromCoordinates ( 5, 0, 1 )
- --> }
-
--}
+{-| -}
on : SketchPlane3d -> QuadraticSpline2d -> QuadraticSpline3d
on sketchPlane spline2d =
with
@@ -189,82 +156,39 @@ on sketchPlane spline2d =
}
-{-| Get the start point of a spline.
-
- QuadraticSpline3d.startPoint exampleSpline
- --> Point3d.fromCoordinates ( 1, 1, 1 )
-
--}
+{-| -}
startPoint : QuadraticSpline3d -> Point3d
startPoint (Types.QuadraticSpline3d spline) =
spline.startPoint
-{-| Get the end point of a spline. This is equal to the spline's last control
-point.
-
- QuadraticSpline3d.endPoint exampleSpline
- --> Point3d.fromCoordinates ( 3, 3, 3 )
-
--}
+{-| -}
endPoint : QuadraticSpline3d -> Point3d
endPoint (Types.QuadraticSpline3d spline) =
spline.endPoint
-{-| Get the control point of a spline.
-
- QuadraticSpline3d.controlPoint exampleSpline
- --> Point3d.fromCoordinates ( 3, 2, 1 )
-
--}
+{-| -}
controlPoint : QuadraticSpline3d -> Point3d
controlPoint (Types.QuadraticSpline3d spline) =
spline.controlPoint
-{-| Get the start derivative of a spline. This is equal to twice the vector from
-the spline's first control point to its second.
-
- QuadraticSpline3d.startDerivative exampleSpline
- --> Vector3d.fromComponents ( 4, 2, 0 )
-
--}
+{-| -}
startDerivative : QuadraticSpline3d -> Vector3d
startDerivative spline =
Vector3d.from (startPoint spline) (controlPoint spline)
|> Vector3d.scaleBy 2
-{-| Get the end derivative of a spline. This is equal to twice the vector from
-the spline's second control point to its third.
-
- QuadraticSpline3d.endDerivative exampleSpline
- --> Vector3d.fromComponents ( 0, 2, 4 )
-
--}
+{-| -}
endDerivative : QuadraticSpline3d -> Vector3d
endDerivative spline =
Vector3d.from (controlPoint spline) (endPoint spline)
|> Vector3d.scaleBy 2
-{-| Compute a bounding box for a given spline. It is not guaranteed that the
-result will be the _smallest_ possible bounding box, since for efficiency the
-bounding box is computed from the spline's control points (which cover a larger
-volume than the spline itself).
-
- QuadraticSpline3d.boundingBox exampleSpline
- --> BoundingBox3d.fromExtrema
- --> { minX = 1
- --> , maxX = 3
- --> , minY = 1
- --> , maxY = 3
- --> , minZ = 1
- --> , maxZ = 3
- --> }
-
--}
+{-| -}
boundingBox : QuadraticSpline3d -> BoundingBox3d
boundingBox spline =
let
@@ -287,18 +211,7 @@ boundingBox spline =
}
-{-| Get the point along a spline at a given parameter value:
-
- QuadraticSpline3d.pointOn exampleSpline 0
- --> Point3d.fromCoordinates ( 1, 1, 1 )
-
- QuadraticSpline3d.pointOn exampleSpline 0.5
- --> Point3d.fromCoordinates ( 2.5, 2, 1.5 )
-
- QuadraticSpline3d.pointOn exampleSpline 1
- --> Point3d.fromCoordinates ( 3, 3, 3 )
-
--}
+{-| -}
pointOn : QuadraticSpline3d -> ParameterValue -> Point3d
pointOn spline parameterValue =
let
@@ -323,39 +236,13 @@ pointOn spline parameterValue =
Point3d.interpolateFrom q1 q2 t
-{-| Get points along a spline at a given set of parameter values:
-
- exampleSpline
- |> QuadraticSpline3d.pointsAt
- (ParameterValue.steps 2)
- --> [ Point3d.fromCoordinates ( 1, 1, 1 )
- --> , Point3d.fromCoordinates ( 2.5, 2, 1.5 )
- --> , Point3d.fromCoordinates ( 3, 3, 3 )
- --> ]
-
--}
+{-| -}
pointsAt : List ParameterValue -> QuadraticSpline3d -> List Point3d
pointsAt parameterValues spline =
List.map (pointOn spline) parameterValues
-{-| Get the first derivative of a spline at a given parameter value:
-
- QuadraticSpline3d.derivative exampleSpline
- ParameterValue.zero
- --> Vector3d.fromComponents ( 4, 2, 0 )
-
- QuadraticSpline3d.derivative exampleSpline
- ParameterValue.half
- --> Vector3d.fromComponents ( 2, 2, 2 )
-
- QuadraticSpline3d.derivative exampleSpline
- ParameterValue.one
- --> Vector3d.fromComponents ( 0, 2, 4 )
-
-Note that the derivative interpolates linearly from end to end.
-
--}
+{-| -}
firstDerivative : QuadraticSpline3d -> ParameterValue -> Vector3d
firstDerivative spline parameterValue =
let
@@ -380,17 +267,7 @@ firstDerivative spline parameterValue =
Vector3d.interpolateFrom v1 v2 t |> Vector3d.scaleBy 2
-{-| Evaluate the first derivative of a spline at a range of parameter values:
-
- exampleSpline
- |> QuadraticSpline3d.firstDerivativesAt
- (ParameterValue.steps 2)
- --> [ Vector3d.fromComponents ( 4, 2, 0 )
- --> , Vector3d.fromComponents ( 2, 2, 2 )
- --> , Vector3d.fromComponents ( 0, 2, 4 )
- --> ]
-
--}
+{-| -}
firstDerivativesAt : List ParameterValue -> QuadraticSpline3d -> List Vector3d
firstDerivativesAt parameterValues spline =
List.map (firstDerivative spline) parameterValues
@@ -452,28 +329,13 @@ derivativeMagnitude spline =
2 * sqrt (x13 * x13 + y13 * y13 + z13 * z13)
-{-| If a curve has zero length (consists of just a single point), then we say
-that it is 'degenerate'. Some operations such as computing tangent directions
-are not defined on degenerate curves.
-
-A `Nondegenerate` value represents a spline that is definitely not degenerate.
-It is used as input to functions such as `QuadraticSpline3d.tangentDirection`
-and can be constructed using `QuadraticSpline3d.nondegenerate`.
-
--}
+{-| -}
type Nondegenerate
= NonZeroSecondDerivative QuadraticSpline3d Direction3d
| NonZeroFirstDerivative QuadraticSpline3d Direction3d
-{-| Attempt to construct a nondegenerate spline from a general
-`QuadraticSpline3d`. If the spline is in fact degenerate (consists of a single
-point), returns an `Err` with that point.
-
- QuadraticSpline3d.nondegenerate exampleSpline
- --> Ok nondegenerateExampleSpline
-
--}
+{-| -}
nondegenerate : QuadraticSpline3d -> Result Point3d Nondegenerate
nondegenerate spline =
case Vector3d.direction (secondDerivative spline) of
@@ -495,13 +357,7 @@ nondegenerate spline =
Err (startPoint spline)
-{-| Convert a nondegenerate spline back to a general `QuadraticSpline3d`.
-
- QuadraticSpline3d.fromNondegenerate
- nondegenerateExampleSpline
- --> exampleSpline
-
--}
+{-| -}
fromNondegenerate : Nondegenerate -> QuadraticSpline3d
fromNondegenerate nondegenerateSpline =
case nondegenerateSpline of
@@ -512,31 +368,7 @@ fromNondegenerate nondegenerateSpline =
spline
-{-| Get the tangent direction to a nondegenerate spline at a given parameter
-value:
-
- QuadraticSpline3d.tangentDirection
- nondegenerateExampleSpline
- ParameterValue.zero
- --> Direction3d.fromAzimuthAndElevation
- --> (degrees 26.57)
- --> (degrees 0)
-
- QuadraticSpline3d.tangentDirection
- nondegenerateExampleSpline
- ParameterValue.half
- --> Direction3d.fromAzimuthAndElevation
- --> (degrees 45)
- --> (degrees 35.26)
-
- QuadraticSpline3d.tangentDirection
- nondegenerateExampleSpline
- ParameterValue.one
- --> Direction3d.fromAzimuthAndElevation
- --> (degrees 90)
- --> (degrees 63.43)
-
--}
+{-| -}
tangentDirection : Nondegenerate -> ParameterValue -> Direction3d
tangentDirection nondegenerateSpline parameterValue =
case nondegenerateSpline of
@@ -573,41 +405,13 @@ tangentDirection nondegenerateSpline parameterValue =
firstDerivativeDirection
-{-| Get tangent directions to a nondegenerate spline at a given set of parameter
-values:
-
- nondegenerateExampleSpline
- |> QuadraticSpline3d.tangentDirectionsAt
- (ParameterValue.steps 2)
- --> [ Direction3d.fromAzimuthAndElevation
- --> (degrees 26.57)
- --> (degrees 0)
- --> , Direction3d.fromAzimuthAndElevation
- --> (degrees 45)
- --> (degrees 35.26)
- --> , Direction3d.fromAzimuthAndElevation
- --> (degrees 90)
- --> (degrees 63.43)
- --> ]
-
--}
+{-| -}
tangentDirectionsAt : List ParameterValue -> Nondegenerate -> List Direction3d
tangentDirectionsAt parameterValues nondegenerateSpline =
List.map (tangentDirection nondegenerateSpline) parameterValues
-{-| Get both the point and tangent direction of a nondegenerate spline at a
-given parameter value:
-
- QuadraticSpline3d.sample nondegenerateExampleSpline
- ParameterValue.half
- --> ( Point3d.fromCoordinates ( 2.5, 2, 1.5 )
- --> , Direction3d.fromAzimuthAndElevation
- --> (degrees 45)
- --> (degrees 35.26)
- --> )
-
--}
+{-| -}
sample : Nondegenerate -> ParameterValue -> ( Point3d, Direction3d )
sample nondegenerateSpline parameterValue =
( pointOn (fromNondegenerate nondegenerateSpline) parameterValue
@@ -615,49 +419,13 @@ sample nondegenerateSpline parameterValue =
)
-{-| Get points and tangent directions of a nondegenerate spline at a given set
-of parameter values:
-
- nondegenerateExampleSpline
- |> QuadraticSpline3d.samplesAt
- (ParameterValue.steps 2)
- --> [ ( Point3d.fromCoordinates ( 1, 1, 1 )
- --> , Direction3d.fromAzimuthAndElevation
- --> (degrees 26.57)
- --> (degrees 0)
- --> )
- --> , ( Point3d.fromCoordinates ( 2.5, 2, 1.5 )
- --> , Direction3d.fromAzimuthAndElevation
- --> (degrees 45)
- --> (degrees 35.26)
- --> )
- --> , ( Point3d.fromCoordinates ( 3, 3, 3 )
- --> , Direction3d.fromAzimuthAndElevation
- --> (degrees 90)
- --> (degrees 63.43)
- --> )
- --> ]
-
--}
+{-| -}
samplesAt : List ParameterValue -> Nondegenerate -> List ( Point3d, Direction3d )
samplesAt parameterValues nondegenerateSpline =
List.map (sample nondegenerateSpline) parameterValues
-{-| Reverse a spline so that the start point becomes the end point, and vice
-versa.
-
- QuadraticSpline3d.reverse exampleSpline
- --> QuadraticSpline3d.with
- --> { startPoint =
- --> Point3d.fromCoordinates ( 3, 3, 3 )
- --> , controlPoint =
- --> Point3d.fromCoordinates ( 3, 2, 1 )
- --> , endPoint =
- --> Point3d.fromCoordinates ( 1, 1, 1 )
- --> }
-
--}
+{-| -}
reverse : QuadraticSpline3d -> QuadraticSpline3d
reverse spline =
with
@@ -667,183 +435,55 @@ reverse spline =
}
-{-| Scale a spline about the given center point by the given scale.
-
- exampleSpline
- |> QuadraticSpline3d.scaleAbout Point3d.origin 2
- --> QuadraticSpline3d.with
- --> { startPoint =
- --> Point3d.fromCoordinates ( 2, 2, 2 )
- --> , controlPoint =
- --> Point3d.fromCoordinates ( 6, 4, 2 )
- --> , endPoint =
- --> Point3d.fromCoordinates ( 6, 6, 6 )
- --> }
-
--}
+{-| -}
scaleAbout : Point3d -> Float -> QuadraticSpline3d -> QuadraticSpline3d
scaleAbout point scale =
mapControlPoints (Point3d.scaleAbout point scale)
-{-| Rotate a spline counterclockwise around a given axis by a given angle (in
-radians).
-
- exampleSpline
- |> QuadraticSpline3d.rotateAround Axis3d.z
- (degrees 90)
- --> QuadraticSpline3d.with
- --> { startPoint =
- --> Point3d.fromCoordinates ( -1, 1, 1 )
- --> , controlPoint =
- --> Point3d.fromCoordinates ( -2, 3, 1 )
- --> , endPoint =
- --> Point3d.fromCoordinates ( -3, 3, 3 )
- --> }
-
--}
+{-| -}
rotateAround : Axis3d -> Float -> QuadraticSpline3d -> QuadraticSpline3d
rotateAround axis angle =
mapControlPoints (Point3d.rotateAround axis angle)
-{-| Translate a spline by a given displacement.
-
- displacement =
- Vector3d.fromComponents ( 2, 3, 1 )
-
- exampleSpline
- |> QuadraticSpline3d.translateBy displacement
- --> QuadraticSpline3d.with
- --> { startPoint =
- --> Point3d.fromCoordinates ( 3, 4, 2 )
- --> , controlPoint =
- --> Point3d.fromCoordinates ( 5, 5, 2 )
- --> , endPoint =
- --> Point3d.fromCoordinates ( 5, 6, 4 )
- --> }
-
--}
+{-| -}
translateBy : Vector3d -> QuadraticSpline3d -> QuadraticSpline3d
translateBy displacement =
mapControlPoints (Point3d.translateBy displacement)
-{-| Translate an arc in a given direction by a given distance;
-
- QuadraticSpline3d.translateIn direction distance
-
-is equivalent to
-
- QuadraticSpline3d.translateBy
- (Vector3d.withLength distance direction)
-
--}
+{-| -}
translateIn : Direction3d -> Float -> QuadraticSpline3d -> QuadraticSpline3d
translateIn direction distance spline =
translateBy (Vector3d.withLength distance direction) spline
-{-| Mirror a spline across a plane.
-
- QuadraticSpline3d.mirrorAcross Plane3d.xy exampleSpline
- --> QuadraticSpline3d.with
- --> { startPoint =
- --> Point3d.fromCoordinates ( 1, 1, -1 )
- --> , controlPoint =
- --> Point3d.fromCoordinates ( 3, 2, -1 )
- --> , endPoint =
- --> Point3d.fromCoordinates ( 3, 3, -3 )
- --> }
-
--}
+{-| -}
mirrorAcross : Plane3d -> QuadraticSpline3d -> QuadraticSpline3d
mirrorAcross plane =
mapControlPoints (Point3d.mirrorAcross plane)
-{-| Find the [orthographic projection](https://en.wikipedia.org/wiki/Orthographic_projection)
-of a spline onto a plane.
-
- QuadraticSpline3d.projectOnto Plane3d.xy exampleSpline
- --> QuadraticSpline3d.with
- --> { startPoint =
- --> Point3d.fromCoordinates ( 1, 1, 0 )
- --> , controlPoint =
- --> Point3d.fromCoordinates ( 3, 2, 0 )
- --> , endPoint =
- --> Point3d.fromCoordinates ( 3, 3, 0 )
- --> }
-
--}
+{-| -}
projectOnto : Plane3d -> QuadraticSpline3d -> QuadraticSpline3d
projectOnto plane =
mapControlPoints (Point3d.projectOnto plane)
-{-| Take a spline defined in global coordinates, and return it expressed in
-local coordinates relative to a given reference frame.
-
- localFrame =
- Frame3d.atPoint
- (Point3d.fromCoordinates ( 1, 2, 3 ))
-
- QuadraticSpline3d.relativeTo localFrame exampleSpline
- --> QuadraticSpline3d.with
- --> { startPoint =
- --> Point3d.fromCoordinates ( 0, -1, -2 )
- --> , controlPoint =
- --> Point3d.fromCoordinates ( 2, 0, -2 )
- --> , endPoint =
- --> Point3d.fromCoordinates ( 2, 1, 0 )
- --> }
-
--}
+{-| -}
relativeTo : Frame3d -> QuadraticSpline3d -> QuadraticSpline3d
relativeTo frame =
mapControlPoints (Point3d.relativeTo frame)
-{-| Take a spline considered to be defined in local coordinates relative to a
-given reference frame, and return that spline expressed in global coordinates.
-
- localFrame =
- Frame3d.atPoint
- (Point3d.fromCoordinates ( 1, 2, 3 ))
-
- QuadraticSpline3d.placeIn localFrame exampleSpline
- --> QuadraticSpline3d.with
- --> { startPoint =
- --> Point3d.fromCoordinates ( 2, 3, 4 )
- --> , controlPoint =
- --> Point3d.fromCoordinates ( 4, 4, 4 )
- --> , endPoint =
- --> Point3d.fromCoordinates ( 4, 5, 6 )
- --> }
-
--}
+{-| -}
placeIn : Frame3d -> QuadraticSpline3d -> QuadraticSpline3d
placeIn frame =
mapControlPoints (Point3d.placeIn frame)
-{-| Project a spline into a given sketch plane. Conceptually, finds the
-[orthographic projection](https://en.wikipedia.org/wiki/Orthographic_projection)
-of the spline onto the plane and then expresses the projected spline in 2D
-sketch coordinates.
-
- exampleSpline
- |> QuadraticSpline3d.projectInto SketchPlane3d.yz
- --> QuadraticSpline2d.with
- --> { startPoint =
- --> Point2d.fromCoordinates ( 1, 1 )
- --> , controlPoint =
- --> Point2d.fromCoordinates ( 2, 1 )
- --> , endPoint =
- --> Point2d.fromCoordinates ( 3, 3 )
- --> }
-
--}
+{-| -}
projectInto : SketchPlane3d -> QuadraticSpline3d -> QuadraticSpline2d
projectInto sketchPlane spline =
QuadraticSpline2d.with
@@ -862,61 +502,13 @@ mapControlPoints function spline =
}
-{-| Split a spline into two roughly equal halves.
-
- QuadraticSpline3d.bisect exampleSpline
- --> ( QuadraticSpline3d.with
- --> { startPoint =
- --> Point3d.fromCoordinates ( 1, 1, 1 )
- --> , controlPoint =
- --> Point3d.fromCoordinates ( 2, 2.5 )
- --> , endPoint =
- --> Point3d.fromCoordinates ( 3, 2.5 )
- --> }
- --> , QuadraticSpline3d.with
- --> { startPoint =
- --> Point3d.fromCoordinates ( 3, 2.5 )
- --> , controlPoint =
- --> Point3d.fromCoordinates ( 4, 2.5 )
- --> , endPoint =
- --> Point3d.fromCoordinates ( 3, 3, 3 )
- --> }
- --> )
-
-Equivalent to `QuadraticSpline3d.splitAt ParameterValue.half`.
-
--}
+{-| -}
bisect : QuadraticSpline3d -> ( QuadraticSpline3d, QuadraticSpline3d )
bisect =
splitAt ParameterValue.half
-{-| Split a spline at a particular parameter value, resulting in two smaller
-splines.
-
- parameterValue =
- ParameterValue.clamped 0.75
-
- QuadraticSpline3d.splitAt parameterValue exampleSpline
- --> ( QuadraticSpline3d.with
- --> { startPoint =
- --> Point3d.fromCoordinates ( 1, 1, 1 )
- --> , controlPoint =
- --> Point3d.fromCoordinates ( 2, 1.5, 1 )
- --> , endPoint =
- --> Point3d.fromCoordinates ( 2.5, 2, 1.5 )
- --> }
- --> , QuadraticSpline3d.with
- --> { startPoint =
- --> Point3d.fromCoordinates ( 2.5, 2, 1.5 )
- --> , controlPoint =
- --> Point3d.fromCoordinates ( 3, 2.5, 2 )
- --> , endPoint =
- --> Point3d.fromCoordinates ( 3, 3, 3 )
- --> }
- --> )
-
--}
+{-| -}
splitAt : ParameterValue -> QuadraticSpline3d -> ( QuadraticSpline3d, QuadraticSpline3d )
splitAt parameterValue spline =
let
@@ -946,8 +538,7 @@ splitAt parameterValue spline =
)
-{-| A spline that has been parameterized by arc length.
--}
+{-| -}
type ArcLengthParameterized
= ArcLengthParameterized
{ underlyingSpline : QuadraticSpline3d
@@ -956,17 +547,7 @@ type ArcLengthParameterized
}
-{-| Build an arc length parameterization of the given spline, with a given
-accuracy. Generally speaking, all operations on the resulting
-`ArcLengthParameterized` value will be accurate to within the specified maximum
-error.
-
- parameterizedSpline =
- exampleSpline
- |> QuadraticSpline3d.arcLengthParameterized
- { maxError = 1.0e-4 }
-
--}
+{-| -}
arcLengthParameterized : { maxError : Float } -> QuadraticSpline3d -> ArcLengthParameterized
arcLengthParameterized { maxError } spline =
let
@@ -985,39 +566,14 @@ arcLengthParameterized { maxError } spline =
}
-{-| Find the total arc length of a spline.
-
- QuadraticSpline3d.arcLength parameterizedSpline
- --> 3.8175
-
-In this example, the result will be accurate to within `1.0e-4` since that was
-the tolerance used when constructing `parameterizedSpline`.
-
--}
+{-| -}
arcLength : ArcLengthParameterized -> Float
arcLength parameterizedSpline =
arcLengthParameterization parameterizedSpline
|> ArcLengthParameterization.totalArcLength
-{-| Try to get the point along a spline at a given arc length. For example, to
-get the point a quarter of the way along `exampleSpline`:
-
- QuadraticSpline3d.pointAlong parameterizedSpline
- (arcLength / 4)
- --> Just <|
- --> Point3d.fromCoordinates
- --> ( 1.8227, 1.4655, 1.1083 )
-
-Note that this is not the same as evaulating at a parameter value of 1/4:
-
- QuadraticSpline3d.pointOn exampleSpline 0.25
- --> Point3d.fromCoordinates ( 1.875, 1.5, 1.125 )
-
-If the given arc length is less than zero or greater than the arc length of the
-spline, returns `Nothing`.
-
--}
+{-| -}
pointAlong : ArcLengthParameterized -> Float -> Maybe Point3d
pointAlong (ArcLengthParameterized parameterized) distance =
parameterized.parameterization
@@ -1025,21 +581,7 @@ pointAlong (ArcLengthParameterized parameterized) distance =
|> Maybe.map (pointOn parameterized.underlyingSpline)
-{-| Try to get the tangent direction along a spline at a given arc length. To
-get the tangent direction a quarter of the way along `exampleSpline`:
-
- QuadraticSpline3d.tangentDirectionAlong
- parameterizedSpline
- (arcLength / 4)
- --> Just <|
- --> Direction3d.fromAzimuthAndElevation
- --> (degrees 33.09)
- --> (degrees 14.26)
-
-If the given arc length is less than zero or greater than the arc length of the
-spline (or if the spline is degenerate), returns `Nothing`.
-
--}
+{-| -}
tangentDirectionAlong : ArcLengthParameterized -> Float -> Maybe Direction3d
tangentDirectionAlong (ArcLengthParameterized parameterized) distance =
case parameterized.nondegenerateSpline of
@@ -1052,24 +594,7 @@ tangentDirectionAlong (ArcLengthParameterized parameterized) distance =
Nothing
-{-| Try to get the point and tangent direction along a spline at a given arc
-length. To get the point and tangent direction a quarter of the way along
-`exampleSpline`:
-
- QuadraticSpline3d.sampleAlong parameterizedSpline
- (0.25 * arcLength)
- --> Just
- --> ( Point3d.fromCoordinates
- --> ( 1.8227, 1.4655, 1.1083 )
- --> , Direction3d.fromAzimuthAndElevation
- --> (degrees 33.09)
- --> (degrees 14.26)
- --> )
-
-If the given arc length is less than zero or greater than the arc length of the
-spline (or if the spline is degenerate), `Nothing` is returned.
-
--}
+{-| -}
sampleAlong : ArcLengthParameterized -> Float -> Maybe ( Point3d, Direction3d )
sampleAlong (ArcLengthParameterized parameterized) distance =
case parameterized.nondegenerateSpline of
@@ -1088,17 +613,13 @@ arcLengthParameterization (ArcLengthParameterized parameterized) =
parameterized.parameterization
-{-| Get the original `QuadraticSpline3d` from which an `ArcLengthParameterized`
-value was constructed.
--}
+{-| -}
fromArcLengthParameterized : ArcLengthParameterized -> QuadraticSpline3d
fromArcLengthParameterized (ArcLengthParameterized parameterized) =
parameterized.underlyingSpline
-{-| Get the second derivative of a spline (for a quadratic spline, this is a
-constant).
--}
+{-| -}
secondDerivative : QuadraticSpline3d -> Vector3d
secondDerivative spline =
let
diff --git a/src/Rectangle2d.elm b/src/Rectangle2d.elm
index 8a41201e..d3232fe2 100644
--- a/src/Rectangle2d.elm
+++ b/src/Rectangle2d.elm
@@ -360,16 +360,7 @@ translateBy displacement rectangle =
}
-{-| Translate a rectangle in a given direction by a given distance;
-
- Rectangle2d.translateIn direction distance
-
-is equivalent to
-
- Rectangle2d.translateBy
- (Vector2d.withLength distance direction)
-
--}
+{-| -}
translateIn : Direction2d -> Float -> Rectangle2d -> Rectangle2d
translateIn direction distance rectangle =
translateBy (Vector2d.withLength distance direction) rectangle
diff --git a/src/SketchPlane3d.elm b/src/SketchPlane3d.elm
index 4488eed5..2cdb30f5 100644
--- a/src/SketchPlane3d.elm
+++ b/src/SketchPlane3d.elm
@@ -67,24 +67,7 @@ calculations in 2D, then convert the result back to 3D.
Many 3D data types have `projectInto` functions that return the corresponding 2D
data type, and `on` functions for converting back to 3D. For example,
[`Triangle3d.projectInto`](Triangle3d#projectInto) returns a `Triangle2d` and
-[`Triangle3d.on`](Triangle3d#on) returns a `Triangle3d`. These pairs of
-functions are almost, but not quite, inverses of each other:
-
- triangle2d
- |> Triangle3d.on sketchPlane
- |> Triangle3d.projectInto sketchPlane
-
-will just return the original `triangle2d` value (within roundoff error), while
-
- triangle3d
- |> Triangle3d.projectInto sketchPlane
- |> Triangle3d.on sketchPlane
-
-is equivalent to
-
- triangle3d
- |> Triangle3d.projectOnto
- (SketchPlane3d.toPlane sketchPlane)
+[`Triangle3d.on`](Triangle3d#on) returns a `Triangle3d`.
@docs SketchPlane3d
@@ -92,16 +75,7 @@ is equivalent to
# Constants
These predefined sketch planes all have the global origin point as their origin
-point, and use the two indicated global axes as their X and Y axes. For example,
-
- SketchPlane3d.originPoint SketchPlane3d.yz
- --> Point3d.origin
-
- SketchPlane3d.xDirection SketchPlane3d.yz
- --> Direction3d.y
-
- SketchPlane3d.yDirection SketchPlane3d.yz
- --> Direction3d.z
+point, and use the two indicated global axes as their X and Y axes.
@docs xy, yx, yz, zy, zx, xz
@@ -149,8 +123,7 @@ type alias SketchPlane3d =
Types.SketchPlane3d
-{-| A sketch plane formed from the global X and Y axes.
--}
+{-| -}
xy : SketchPlane3d
xy =
unsafe
@@ -160,8 +133,7 @@ xy =
}
-{-| A sketch plane formed from the global Y and X axes.
--}
+{-| -}
yx : SketchPlane3d
yx =
unsafe
@@ -171,8 +143,7 @@ yx =
}
-{-| A sketch plane formed from the global Y and Z axes.
--}
+{-| -}
yz : SketchPlane3d
yz =
unsafe
@@ -182,8 +153,7 @@ yz =
}
-{-| A sketch plane formed from the global Z and Y axes.
--}
+{-| -}
zy : SketchPlane3d
zy =
unsafe
@@ -193,8 +163,7 @@ zy =
}
-{-| A sketch plane formed from the global Z and X axes.
--}
+{-| -}
zx : SketchPlane3d
zx =
unsafe
@@ -204,8 +173,7 @@ zx =
}
-{-| A sketch plane formed from the global X and Z axes.
--}
+{-| -}
xz : SketchPlane3d
xz =
unsafe
@@ -215,36 +183,7 @@ xz =
}
-{-| Construct a sketch plane with the given normal direction, having the given
-origin point. The X and Y basis directions of the sketch plane will:
-
- - be perpendicular to each other,
- - both be perpendicular to the given normal direction, and
- - have a cross product equal to the given normal direction.
-
-This is useful when constructing 'scratch' sketch planes where the specific X/Y
-directions are unimportant.
-
- sketchPlane =
- SketchPlane3d.withNormalDirection
- (Direction3d.fromAzimuthAndElevation
- (degrees 0)
- (degrees 60)
- )
- Point3d.origin
-
- SketchPlane3d.originPoint sketchPlane
- --> Point3d.origin
-
- SketchPlane3d.xDirection sketchPlane
- --> Direction3d.fromAzimuthAndElevation
- --> (degrees 0)
- --> (degrees -30)
-
- SketchPlane3d.yDirection sketchPlane
- --> Direction3d.y
-
--}
+{-| -}
withNormalDirection : Direction3d -> Point3d -> SketchPlane3d
withNormalDirection normalDirection_ originPoint_ =
let
@@ -258,32 +197,7 @@ withNormalDirection normalDirection_ originPoint_ =
}
-{-| Construct one sketch plane lying on another sketch plane, but with a
-different origin point and X/Y directions. To do this, a `Frame2d` must be
-provided that specifies the origin point and X/Y directions of the new sketch
-plane, in 2D coordinates within the existing sketch plane. Whew!
-
- frame2d =
- Frame2d.atPoint (Point2d.fromCoordinates ( 2, 3 ))
- |> Frame2d.rotateBy (degrees -30)
-
- sketchPlane =
- SketchPlane3d.on SketchPlane3d.yz frame2d
-
- SketchPlane3d.originPoint sketchPlane
- --> Point3d.fromCoordinates ( 0, 2, 3 )
-
- SketchPlane3d.xDirection sketchPlane
- --> Direction3d.fromAzimuthAndElevation
- --> (degrees 90)
- --> (degrees -30)
-
- SketchPlane3d.yDirection sketchPlane
- --> Direction3d.fromAzimuthAndElevation
- --> (degrees 90)
- --> (degrees 60)
-
--}
+{-| -}
on : SketchPlane3d -> Frame2d -> SketchPlane3d
on sketchPlane frame =
unsafe
@@ -293,98 +207,20 @@ on sketchPlane frame =
}
-{-| Construct a SketchPlane3d from the given plane;
-
- SketchPlane3d.fromPlane plane
-
-is equivalent to
-
- SketchPlane3d.withNormalDirection
- (Plane3d.normalDirection plane)
- (Plane3d.originPoint plane)
-
-Note that because the X and Y directions of the resulting sketch plane are
-chosen arbitrarily, conversions may not work exactly as you expect. For example,
-in the current implementation,
-
- sketchPlane =
- SketchPlane3d.fromPlane Plane3d.xy
-
-is not equal to `SketchPlane3d.xy` (although the two sketch planes have the same
-origin point and are coplanar):
-
- SketchPlane3d.originPoint sketchPlane
- --> Point3d.origin
-
- SketchPlane3d.xDirection sketchPlane
- --> Direction3d.negativeY
-
- SketchPlane3d.yDirection sketchPlane
- --> Direction3d.positiveX
-
--}
+{-| -}
fromPlane : Plane3d -> SketchPlane3d
fromPlane plane =
withNormalDirection (Plane3d.normalDirection plane)
(Plane3d.originPoint plane)
-{-| Construct a sketch plane directly from its origin point and X and Y
-directions:
-
- sketchPlane =
- SketchPlane3d.unsafe
- { originPoint =
- Point3d.fromCoordinates ( 2, 1, 3 )
- , xDirection = Direction3d.positiveY
- , yDirection = Direction3d.negativeZ
- }
-
-If you construct a `SketchPlane3d` this way, **you must ensure that the X and Y
-basis directions are perpendicular to each other**.
-
--}
+{-| -}
unsafe : { originPoint : Point3d, xDirection : Direction3d, yDirection : Direction3d } -> SketchPlane3d
unsafe =
Types.SketchPlane3d
-{-| Attempt to construct a sketch plane that passes through the three given
-points. Returns a sketch plane where:
-
- - The origin point is the first given point
- - The X direction is equal to the direction from the first given point to the
- second
- - The Y direction is chosen such that the third given point lies on the sketch
- plane and has a positive Y coordinate within the sketch plane (that is, it
- is on the positive Y side of the sketch plane's X axis)
-
-If the three given points are collinear, returns `Nothing`.
-
- SketchPlane3d.throughPoints
- (Point3d.fromCoordinates ( 2, 0, 0 ))
- (Point3d.fromCoordinates ( 3, 0, 0 ))
- (Point3d.fromCoordinates ( 4, 1, 1 ))
- --> Just sketchPlane
-
- SketchPlane3d.originPoint sketchPlane
- --> Point3d.fromCoordinates ( 2, 0, 0 )
-
- SketchPlane3d.xDirection sketchPlane
- --> Direction3d.x
-
- SketchPlane3d.yDirection sketchPlane
- --> Direction3d.fromAzimuthAndElevation
- --> (degrees 90)
- --> (degrees 45)
-
- SketchPlane3d.throughPoints
- (Point3d.fromCoordinates ( 2, 0, 0 ))
- (Point3d.fromCoordinates ( 3, 0, 0 ))
- (Point3d.fromCoordinates ( 4, 0, 0 ))
- --> Nothing
-
--}
+{-| -}
throughPoints : Point3d -> Point3d -> Point3d -> Maybe SketchPlane3d
throughPoints firstPoint secondPoint thirdPoint =
Direction3d.from firstPoint secondPoint
@@ -430,51 +266,25 @@ throughPoints firstPoint secondPoint thirdPoint =
)
-{-| Get the origin point of a sketch plane.
-
- SketchPlane3d.originPoint SketchPlane3d.xy
- --> Point3d.origin
-
--}
+{-| -}
originPoint : SketchPlane3d -> Point3d
originPoint (Types.SketchPlane3d properties) =
properties.originPoint
-{-| Get the X direction of a sketch plane (the direction of the sketch plane's
-X axis).
-
- SketchPlane3d.xDirection SketchPlane3d.zx
- --> Direction3d.z
-
--}
+{-| -}
xDirection : SketchPlane3d -> Direction3d
xDirection (Types.SketchPlane3d properties) =
properties.xDirection
-{-| Get the Y direction of a sketch plane (the direction of the sketch plane's
-Y axis).
-
- SketchPlane3d.yDirection SketchPlane3d.zx
- --> Direction3d.x
-
--}
+{-| -}
yDirection : SketchPlane3d -> Direction3d
yDirection (Types.SketchPlane3d properties) =
properties.yDirection
-{-| Get the normal direction to a sketch plane. This is equal to the cross
-product of the sketch plane's X and Y directions.
-
- SketchPlane3d.normalDirection SketchPlane3d.xy
- --> Direction3d.z
-
- SketchPlane3d.normalDirection SketchPlane3d.xz
- --> Direction3d.negativeY
-
--}
+{-| -}
normalDirection : SketchPlane3d -> Direction3d
normalDirection sketchPlane =
let
@@ -486,72 +296,31 @@ normalDirection sketchPlane =
Direction3d.unsafe (Vector3d.components normalVector)
-{-| Get the X axis of a sketch plane. A 2D X coordinate within the sketch plane
-corresponds to a distance along this axis in 3D.
-
- SketchPlane3d.xAxis SketchPlane3d.zx
- --> Axis3d.z
-
--}
+{-| -}
xAxis : SketchPlane3d -> Axis3d
xAxis (Types.SketchPlane3d sketchPlane) =
Axis3d.through sketchPlane.originPoint sketchPlane.xDirection
-{-| Get the Y axis of a sketch plane. A 2D Y coordinate within the sketch plane
-corresponds to a distance along this axis in 3D.
-
- SketchPlane3d.yAxis SketchPlane3d.zx
- --> Axis3d.x
-
--}
+{-| -}
yAxis : SketchPlane3d -> Axis3d
yAxis (Types.SketchPlane3d sketchPlane) =
Axis3d.through sketchPlane.originPoint sketchPlane.yDirection
-{-| Get the normal axis to a sketch plane (the axis formed from the sketch
-plane's origin point and normal direction).
-
- SketchPlane3d.normalAxis SketchPlane3d.xy
- --> Axis3d.z
-
- SketchPlane3d.normalAxis SketchPlane3d.xz
- --> Axis3d.reverse Axis3d.y
-
--}
+{-| -}
normalAxis : SketchPlane3d -> Axis3d
normalAxis sketchPlane =
Axis3d.through (originPoint sketchPlane) (normalDirection sketchPlane)
-{-| Convert a `SketchPlane3d` to a `Plane3d` with the same origin point and
-normal direction.
-
- SketchPlane3d.toPlane SketchPlane3d.xy
- --> Plane3d.xy
-
- SketchPlane3d.toPlane SketchPlane3d.yx
- --> Plane3d.reverseNormal Plane3d.xy
-
--}
+{-| -}
toPlane : SketchPlane3d -> Plane3d
toPlane sketchPlane =
Plane3d.through (originPoint sketchPlane) (normalDirection sketchPlane)
-{-| Shift a sketch plane in its own normal direction by the given (signed)
-distance.
-
- SketchPlane3d.offsetBy -2.0 SketchPlane3d.xy
- |> SketchPlane3d.originPoint
- --> Point3d.fromCoordinates ( 0, 0, -2 )
-
- SketchPlane3d.offsetBy 1.0 SketchPlane3d.zx
- |> SketchPlane3d.originPoint
- --> Point3d.fromCoordinates ( 0, 1, 0 )
-
--}
+{-| -}
offsetBy : Float -> SketchPlane3d -> SketchPlane3d
offsetBy distance sketchPlane =
let
@@ -561,22 +330,7 @@ offsetBy distance sketchPlane =
translateBy displacement sketchPlane
-{-| Reverse the X direction of a sketch plane, leaving its Y direction and
-origin point unchanged.
-
- sketchPlane =
- SketchPlane3d.reverseX SketchPlane3d.yz
-
- SketchPlane3d.originPoint sketchPlane
- --> Point3d.origin
-
- SketchPlane3d.xDirection sketchPlane
- --> Direction3d.negativeY
-
- SketchPlane3d.yDirection sketchPlane
- --> Direction3d.z
-
--}
+{-| -}
reverseX : SketchPlane3d -> SketchPlane3d
reverseX sketchPlane =
unsafe
@@ -586,22 +340,7 @@ reverseX sketchPlane =
}
-{-| Reverse the Y direction of a sketch plane, leaving its X direction and
-origin point unchanged.
-
- sketchPlane =
- SketchPlane3d.reverseY SketchPlane3d.yz
-
- SketchPlane3d.originPoint sketchPlane
- --> Point3d.origin
-
- SketchPlane3d.xDirection sketchPlane
- --> Direction3d.y
-
- SketchPlane3d.yDirection sketchPlane
- --> Direction3d.negativeZ
-
--}
+{-| -}
reverseY : SketchPlane3d -> SketchPlane3d
reverseY sketchPlane =
unsafe
@@ -611,25 +350,7 @@ reverseY sketchPlane =
}
-{-| Set the origin point of the given sketch plane to the given point, leaving
-its X and Y directions unchanged.
-
- newOrigin =
- Point3d.fromCoordinates ( 2, 1, 3 )
-
- sketchPlane =
- SketchPlane3d.moveTo newOrigin SketchPlane3d.yz
-
- SketchPlane3d.originPoint sketchPlane
- --> newOrigin
-
- SketchPlane3d.xDirection sketchPlane
- --> Direction3d.y
-
- SketchPlane3d.yDirection sketchPlane
- --> Direction3d.z
-
--}
+{-| -}
moveTo : Point3d -> SketchPlane3d -> SketchPlane3d
moveTo newOrigin sketchPlane =
unsafe
@@ -639,15 +360,7 @@ moveTo newOrigin sketchPlane =
}
-{-| Rotate a sketch plane around an axis by a given angle (in radians). The
-sketch plane's origin point and X and Y directions will all be rotated around
-the given axis.
-
- SketchPlane3d.xy
- |> SketchPlane3d.rotateAround Axis3d.x (degrees 90)
- --> SketchPlane3d.xz
-
--}
+{-| -}
rotateAround : Axis3d -> Float -> SketchPlane3d -> SketchPlane3d
rotateAround axis angle =
let
@@ -665,64 +378,13 @@ rotateAround axis angle =
}
-{-| Rotate a sketch plane around one of its own axes by a given angle (in
-radians).
-
-The first argument is a function that returns the axis to rotate around, given
-the current sketch plane. The majority of the time this will be either
-`SketchPlane3d.xAxis` or `SketchPlane3d.yAxis`.
-
-This function is convenient when constructing sketch planes via a series of
-transformations. For example,
-
- sketchPlane =
- SketchPlane3d.xy
- |> SketchPlane3d.translateBy
- (Vector3d.fromComponents ( 1, 0, 0 ))
- |> SketchPlane3d.rotateAroundOwn
- SketchPlane3d.yAxis
- (degrees -45)
-
- SketchPlane3d.originPoint sketchPlane
- --> Point3d.fromCoordinates ( 1, 0, 0 )
-
- SketchPlane3d.xDirection sketchPlane
- --> Direction3d.fromAzimuthAndElevation
- --> (degrees 0)
- --> (degrees 45)
-
- SketchPlane3d.yDirection sketchPlane
- --> Direction3d.y
-
-Note that since the rotation was around the sketch plane's own Y axis (which
-passes through the sketch plane's origin point) instead of the global Y axis,
-the origin point itself was not affected by the rotation.
-
--}
+{-| -}
rotateAroundOwn : (SketchPlane3d -> Axis3d) -> Float -> SketchPlane3d -> SketchPlane3d
rotateAroundOwn axis angle sketchPlane =
rotateAround (axis sketchPlane) angle sketchPlane
-{-| Translate a sketch plane by a given displacement.
-
- displacement =
- Vector3d.fromComponents ( 2, 1, 3 )
-
- sketchPlane =
- SketchPlane3d.xy
- |> SketchPlane3d.translateBy displacement
-
- SketchPlane3d.originPoint sketchPlane
- --> Point3d.fromCoordinates ( 2, 1, 3 )
-
- SketchPlane3d.xDirection sketchPlane
- --> Direction3d.x
-
- SketchPlane3d.yDirection sketchPlane
- --> Direction3d.y
-
--}
+{-| -}
translateBy : Vector3d -> SketchPlane3d -> SketchPlane3d
translateBy vector sketchPlane =
unsafe
@@ -732,55 +394,13 @@ translateBy vector sketchPlane =
}
-{-| Translate a sketch plane in a given direction by a given distance;
-
- SketchPlane3d.translateIn direction distance
-
-is equivalent to
-
- SketchPlane3d.translateBy
- (Vector3d.withLength distance direction)
-
--}
+{-| -}
translateIn : Direction3d -> Float -> SketchPlane3d -> SketchPlane3d
translateIn direction distance sketchPlane =
translateBy (Vector3d.withLength distance direction) sketchPlane
-{-| Translate a sketch plane along one of its own axes by a given distance.
-
-The first argument is a function that returns the axis to translate along, given
-the current sketch plane. The majority of the time this will be either
-`SketchPlane3d.xAxis` or `SketchPlane3d.yAxis`.
-
-This function is convenient when constructing frames via a series of
-transformations. For example,
-
- sketchPlane =
- SketchPlane3d.xy
- |> SketchPlane3d.rotateAround
- Axis3d.x
- (degrees 45)
- |> SketchPlane3d.translateAlongOwn
- SketchPlane3d.yAxis
- 2
-
-means 'take the global XY sketch plane, rotate it around the global X axis by
-45 degrees, then translate the result 2 units along its own (rotated) Y axis',
-resulting in
-
- SketchPlane3d.originPoint sketchPlane
- --> Point3d.fromCoordinates ( 0, 1.4142, 1.4142 )
-
- SketchPlane3d.xDirection sketchPlane
- --> Direction3d.x
-
- SketchPlane3d.yDirection sketchPlane
- --> Direction3d.fromAzimuthAndElevation
- --> (degrees 90)
- --> (degrees 45)
-
--}
+{-| -}
translateAlongOwn : (SketchPlane3d -> Axis3d) -> Float -> SketchPlane3d -> SketchPlane3d
translateAlongOwn axis distance frame =
let
@@ -790,26 +410,7 @@ translateAlongOwn axis distance frame =
translateBy displacement frame
-{-| Mirror a sketch plane across a plane.
-
- sketchPlane =
- SketchPlane3d.yz
- |> SketchPlane3d.moveTo
- (Point2d.fromCoordinates ( 2, 1, 3 ))
-
- mirroredSketchPlane =
- SketchPlane3d.mirrorAcross Plane3d.xy sketchPlane
-
- SketchPlane3d.originPoint sketchPlane
- --> Point2d.fromCoordinates ( 2, 1, -3 )
-
- SketchPlane3d.xDirection sketchPlane
- --> Direction3d.y
-
- SketchPlane3d.yDirection sketchPlane
- --> Direction3d.negativeZ
-
--}
+{-| -}
mirrorAcross : Plane3d -> SketchPlane3d -> SketchPlane3d
mirrorAcross plane =
let
@@ -827,9 +428,7 @@ mirrorAcross plane =
}
-{-| Take a sketch plane defined in global coordinates, and return it expressed
-in local coordinates relative to a given reference frame.
--}
+{-| -}
relativeTo : Frame3d -> SketchPlane3d -> SketchPlane3d
relativeTo frame =
let
@@ -847,9 +446,7 @@ relativeTo frame =
}
-{-| Take a sketch plane defined in local coordinates relative to a given
-reference frame, and return that sketch plane expressed in global coordinates.
--}
+{-| -}
placeIn : Frame3d -> SketchPlane3d -> SketchPlane3d
placeIn frame =
let
diff --git a/src/Sphere3d.elm b/src/Sphere3d.elm
index 5857e433..17c9ffd1 100644
--- a/src/Sphere3d.elm
+++ b/src/Sphere3d.elm
@@ -104,26 +104,13 @@ type alias Sphere3d =
Types.Sphere3d
-{-| The unit sphere, centered on the origin with a radius of 1.
-
- Sphere3d.unit
- --> Sphere3d.withRadius 1 Point3d.origin
-
--}
+{-| -}
unit : Sphere3d
unit =
withRadius 1 Point3d.origin
-{-| Construct a sphere from its radius and center point:
-
- exampleSphere =
- Sphere3d.withRadius 3
- (Point3d.fromCoordinates ( 1, 2, 1 ))
-
-If you pass a negative radius, the absolute value will be used.
-
--}
+{-| -}
withRadius : Float -> Point3d -> Sphere3d
withRadius radius_ centerPoint_ =
Types.Sphere3d
@@ -132,27 +119,7 @@ withRadius radius_ centerPoint_ =
}
-{-| Attempt to construct a sphere that passes through the four given points.
-Returns `Nothing` if four given points are coplanar.
-
- Sphere3d.throughPoints
- (Point3d.fromCoordinates ( 1, 0, 0 ))
- (Point3d.fromCoordinates ( -1, 0, 0 ))
- (Point3d.fromCoordinates ( 0, 1, 0 ))
- (Point3d.fromCoordinates ( 0, 0, 0.5 ))
- --> Just
- --> (Sphere3d.withRadius 1.25
- --> (Point3d.fromCoordinates ( 0, 0, -0.75 ))
- --> )
-
- Sphere3d.throughPoints
- (Point3d.fromCoordinates ( 1, 0, 0 ))
- (Point3d.fromCoordinates ( -1, 0, 0 ))
- (Point3d.fromCoordinates ( 0, 1, 0 ))
- (Point3d.fromCoordinates ( 0, -1, 0 ))
- --> Nothing
-
--}
+{-| -}
throughPoints : Point3d -> Point3d -> Point3d -> Point3d -> Maybe Sphere3d
throughPoints p1 p2 p3 p4 =
Circle3d.throughPoints p1 p2 p3
@@ -190,57 +157,31 @@ throughPoints p1 p2 p3 p4 =
)
-{-| Get the center point of a sphere.
-
- Sphere3d.centerPoint exampleSphere
- --> Point3d.fromCoordinates ( 1, 2, 1 )
-
--}
+{-| -}
centerPoint : Sphere3d -> Point3d
centerPoint (Types.Sphere3d properties) =
properties.centerPoint
-{-| Get the radius of a sphere.
-
- Sphere3d.radius exampleSphere
- --> 3
-
--}
+{-| -}
radius : Sphere3d -> Float
radius (Types.Sphere3d properties) =
properties.radius
-{-| Get the diameter of a sphere.
-
- Sphere3d.diameter exampleSphere
- --> 6
-
--}
+{-| -}
diameter : Sphere3d -> Float
diameter sphere =
2 * radius sphere
-{-| Get the circumference of a sphere (the circumference of a [great circle](https://en.wikipedia.org/wiki/Great_circle)
-of the sphere).
-
- Sphere3d.circumference exampleSphere
- --> 18.8496
-
--}
+{-| -}
circumference : Sphere3d -> Float
circumference sphere =
2 * pi * radius sphere
-{-| Get the surface area of a sphere.
-
- Sphere3d.surfaceArea exampleSphere
- --> 113.0973
-
--}
+{-| -}
surfaceArea : Sphere3d -> Float
surfaceArea sphere =
let
@@ -250,12 +191,7 @@ surfaceArea sphere =
4 * pi * r * r
-{-| Get the volume of a sphere.
-
- Sphere3d.volume exampleSphere
- --> 113.0973
-
--}
+{-| -}
volume : Sphere3d -> Float
volume sphere =
let
@@ -265,27 +201,14 @@ volume sphere =
4 / 3 * pi * r * r * r
-{-| Scale a sphere around a given point by a given scale.
-
- Sphere3d.scaleAbout Point3d.origin 3 exampleSphere
- --> Sphere3d.withRadius 9
- --> (Point3d.fromCoordinates ( 3, 6, 3 ))
-
--}
+{-| -}
scaleAbout : Point3d -> Float -> Sphere3d -> Sphere3d
scaleAbout point scale sphere =
withRadius (abs scale * radius sphere)
(Point3d.scaleAbout point scale (centerPoint sphere))
-{-| Rotate a sphere around a given axis by a given angle (in radians).
-
- exampleSphere
- |> Sphere3d.rotateAround Axis3d.y (degrees 90)
- --> Sphere3d.withRadius 3
- --> (Point3d.fromCoordinates ( 1, 2, -1 ))
-
--}
+{-| -}
rotateAround : Axis3d -> Float -> Sphere3d -> Sphere3d
rotateAround axis angle =
let
@@ -297,98 +220,41 @@ rotateAround axis angle =
(rotatePoint (centerPoint sphere))
-{-| Translate a sphere by a given displacement.
-
- exampleSphere
- |> Sphere3d.translateBy
- (Vector3d.fromComponents ( 2, 1, 3 ))
- --> Sphere3d.withRadius 3
- --> (Point3d.fromCoordinates ( 3, 3, 4 ))
-
--}
+{-| -}
translateBy : Vector3d -> Sphere3d -> Sphere3d
translateBy displacement sphere =
withRadius (radius sphere)
(Point3d.translateBy displacement (centerPoint sphere))
-{-| Translate a sphere in a given direction by a given distance;
-
- Sphere3d.translateIn direction distance
-
-is equivalent to
-
- Sphere3d.translateBy
- (Vector3d.withLength distance direction)
-
--}
+{-| -}
translateIn : Direction3d -> Float -> Sphere3d -> Sphere3d
translateIn direction distance sphere =
translateBy (Vector3d.withLength distance direction) sphere
-{-| Mirror a sphere across a given plane.
-
- Sphere3d.mirrorAcross Plane3d.xy exampleSphere
- --> Sphere3d.withRadius 3
- --> (Point3d.fromCoordinates ( 1, 2, -1 ))
-
--}
+{-| -}
mirrorAcross : Plane3d -> Sphere3d -> Sphere3d
mirrorAcross plane sphere =
withRadius (radius sphere)
(Point3d.mirrorAcross plane (centerPoint sphere))
-{-| Take a sphere defined in global coordinates, and return it expressed in
-local coordinates relative to a given reference frame.
-
- exampleSphere
- |> Sphere3d.relativeTo
- (Frame3d.atPoint
- (Point3d.fromCoordinates ( 1, 2, 3 ))
- )
- --> Sphere3d.withRadius 3
- --> (Point3d.fromCoordinates ( 0, 0, -2 ))
-
--}
+{-| -}
relativeTo : Frame3d -> Sphere3d -> Sphere3d
relativeTo frame sphere =
withRadius (radius sphere)
(Point3d.relativeTo frame (centerPoint sphere))
-{-| Take a sphere considered to be defined in local coordinates relative to a
-given reference frame, and return that sphere expressed in global coordinates.
-
- exampleSphere
- |> Sphere3d.placeIn
- (Frame3d.atPoint
- (Point3d.fromCoordinates ( 1, 2, 3 ))
- )
- --> Sphere3d.withRadius 3
- --> (Point3d.fromCoordinates ( 2, 4, 4 ))
-
--}
+{-| -}
placeIn : Frame3d -> Sphere3d -> Sphere3d
placeIn frame sphere =
withRadius (radius sphere)
(Point3d.placeIn frame (centerPoint sphere))
-{-| Get the minimal bounding box containing a given sphere.
-
- Sphere3d.boundingBox exampleSphere
- --> BoundingBox3d.fromExtrema
- --> { minX = -2
- --> , maxX = 4
- --> , minY = -1
- --> , maxY = 5
- --> , minZ = -2
- --> , maxZ = 4
- --> }
-
--}
+{-| -}
boundingBox : Sphere3d -> BoundingBox3d
boundingBox sphere =
let
@@ -408,19 +274,7 @@ boundingBox sphere =
}
-{-| Check if a sphere contains a given point.
-
- Sphere3d.contains
- (Point3d.fromCoordinates ( 4, 2, 1 ))
- exampleSphere
- --> True
-
- Sphere3d.contains
- (Point3d.fromCoordinates ( 4.00001, 2, 1 ))
- exampleSphere
- --> False
-
--}
+{-| -}
contains : Point3d -> Sphere3d -> Bool
contains point sphere =
let
@@ -430,15 +284,7 @@ contains point sphere =
Point3d.squaredDistanceFrom (centerPoint sphere) point <= r * r
-{-| Find the [orthographic projection](https://en.wikipedia.org/wiki/Orthographic_projection)
-of a sphere onto a plane.
-
- Sphere3d.projectOnto Plane3d.xy exampleSphere
- --> Circle3d.withRadius 3
- --> Direction3d.z
- --> (Point3d.fromCoordinates ( 1, 2, 0 ))
-
--}
+{-| -}
projectOnto : Plane3d -> Sphere3d -> Circle3d
projectOnto plane sphere =
Circle3d.withRadius (radius sphere)
@@ -446,14 +292,7 @@ projectOnto plane sphere =
(Point3d.projectOnto plane (centerPoint sphere))
-{-| Find the [orthographic projection](https://en.wikipedia.org/wiki/Orthographic_projection)
-of a sphere into a sketch plane.
-
- Sphere3d.projectInto SketchPlane3d.xy exampleSphere
- --> Circle2d.withRadius 3
- --> (Point2d.fromCoordinates ( 1, 2 ))
-
--}
+{-| -}
projectInto : SketchPlane3d -> Sphere3d -> Circle2d
projectInto sketchPlane sphere =
Circle2d.withRadius (radius sphere)
diff --git a/src/Triangle2d.elm b/src/Triangle2d.elm
index 12bf4474..63627144 100644
--- a/src/Triangle2d.elm
+++ b/src/Triangle2d.elm
@@ -69,9 +69,6 @@ Transforming a triangle is equivalent to transforming its vertices.
# Coordinate conversions
-Functions for transforming triangles between local and global coordinates in
-different coordinate frames.
-
@docs relativeTo, placeIn
-}
@@ -92,63 +89,19 @@ type alias Triangle2d =
Types.Triangle2d
-{-| Construct a triangle from its three vertices:
-
- exampleTriangle =
- Triangle2d.fromVertices
- ( Point2d.fromCoordinates ( 1, 1 )
- , Point2d.fromCoordinates ( 2, 1 )
- , Point2d.fromCoordinates ( 1, 3 )
- )
-
--}
+{-| -}
fromVertices : ( Point2d, Point2d, Point2d ) -> Triangle2d
fromVertices =
Types.Triangle2d
-{-| Get the vertices of a triangle.
-
- ( p1, p2, p3 ) =
- Triangle2d.vertices exampleTriangle
-
-
- --> p1 = Point2d.fromCoordinates ( 1, 1 )
- --> p2 = Point2d.fromCoordinates ( 2, 1 )
- --> p3 = Point2d.fromCoordinates ( 1, 3 )
-
--}
+{-| -}
vertices : Triangle2d -> ( Point2d, Point2d, Point2d )
vertices (Types.Triangle2d vertices_) =
vertices_
-{-| Get the edges of a triangle: from the first vertex to the second, from the
-second to the third, and from the third back to the first.
-
- ( e1, e2, e3 ) =
- Triangle2d.edges exampleTriangle
-
-
- --> e1 =
- --> LineSegment2d.fromEndpoints
- --> ( Point2d.fromCoordinates ( 1, 1 )
- --> , Point2d.fromCoordinates ( 2, 1 )
- --> )
- -->
- --> e2 =
- --> LineSegment2d.fromEndpoints
- --> ( Point2d.fromCoordinates ( 2, 1 )
- --> , Point2d.fromCoordinates ( 1, 3 )
- --> )
- -->
- --> e3 =
- --> LineSegment2d.fromEndpoints
- --> ( Point2d.fromCoordinates ( 1, 3 )
- --> , Point2d.fromCoordinates ( 1, 1 )
- --> )
-
--}
+{-| -}
edges : Triangle2d -> ( LineSegment2d, LineSegment2d, LineSegment2d )
edges triangle =
let
@@ -161,12 +114,7 @@ edges triangle =
)
-{-| Get the centroid (center of mass) of a triangle.
-
- Triangle2d.centroid exampleTriangle
- --> Point2d.fromCoordinates ( 1.3333, 1.6667 )
-
--}
+{-| -}
centroid : Triangle2d -> Point2d
centroid triangle =
let
@@ -185,21 +133,7 @@ centroid triangle =
Point2d.translateBy displacement p1
-{-| Check whether a given point is inside a given triangle.
-
- interiorPoint =
- Point2d.fromCoordinates ( 1.5, 1.5 )
-
- Triangle2d.contains interiorPoint exampleTriangle
- --> True
-
- Triangle2d.contains Point2d.origin exampleTriangle
- --> False
-
-It does not matter whether the triangle's vertices are in clockwise or
-counterclockwise order.
-
--}
+{-| -}
contains : Point2d -> Triangle2d -> Bool
contains point triangle =
let
@@ -229,26 +163,13 @@ contains point triangle =
|| (firstProduct <= 0 && secondProduct <= 0 && thirdProduct <= 0)
-{-| Get the area of a triangle. The result will always be positive regardless of
-whether the triangle's vertices are in clockwise or counterclockwise order.
-
- Triangle2d.area exampleTriangle
- --> 1.0
-
--}
+{-| -}
area : Triangle2d -> Float
area =
counterclockwiseArea >> abs
-{-| Get the signed area of a triangle, returning a positive value if the
-triangle's vertices are in counterclockwise order and a negative value
-otherwise.
-
- Triangle2d.counterclockwiseArea exampleTriangle
- --> 1.0
-
--}
+{-| -}
counterclockwiseArea : Triangle2d -> Float
counterclockwiseArea triangle =
let
@@ -264,118 +185,43 @@ counterclockwiseArea triangle =
0.5 * Vector2d.crossProduct firstVector secondVector
-{-| Get the signed area of a triangle, returning a positive value if the
-triangle's vertices are in clockwise order and a negative value otherwise.
-
- Triangle2d.clockwiseArea exampleTriangle
- --> -1.0
-
--}
+{-| -}
clockwiseArea : Triangle2d -> Float
clockwiseArea triangle =
-(counterclockwiseArea triangle)
-{-| Scale a triangle about a given point by a given scale.
-
- Triangle2d.scaleAbout Point2d.origin 2 exampleTriangle
- --> Triangle2d.fromVertices
- --> ( Point2d.fromCoordinates ( 2, 2 )
- --> , Point2d.fromCoordinates ( 4, 2 )
- --> , Point2d.fromCoordinates ( 2, 6 )
- --> )
-
-Note that scaling by a negative value will result in the 'winding direction' of
-the triangle being flipped - if the triangle's vertices were in counterclockwise
-order before the negative scaling, they will be in clockwise order afterwards
-and vice versa.
-
--}
+{-| -}
scaleAbout : Point2d -> Float -> Triangle2d -> Triangle2d
scaleAbout point scale =
mapVertices (Point2d.scaleAbout point scale)
-{-| Rotate a triangle around a given point by a given angle (in radians).
-
- exampleTriangle
- |> Triangle2d.rotateAround Point2d.origin
- (degrees 90)
- --> Triangle2d.fromVertices
- --> ( Point2d.fromCoordinates ( -1, 1 )
- --> , Point2d.fromCoordinates ( -1, 2 )
- --> , Point2d.fromCoordinates ( -3, 1 )
- --> )
-
--}
+{-| -}
rotateAround : Point2d -> Float -> Triangle2d -> Triangle2d
rotateAround centerPoint angle =
mapVertices (Point2d.rotateAround centerPoint angle)
-{-| Translate a triangle by a given displacement.
-
- displacement =
- Vector2d.fromComponents ( 2, -3 )
-
- Triangle2d.translateBy displacement exampleTriangle
- --> Triangle2d.fromVertices
- --> ( Point2d.fromCoordinates ( 3, -2 )
- --> , Point2d.fromCoordinates ( 4, -2 )
- --> , Point2d.fromCoordinates ( 3, 0 )
- --> )
-
--}
+{-| -}
translateBy : Vector2d -> Triangle2d -> Triangle2d
translateBy vector =
mapVertices (Point2d.translateBy vector)
-{-| Translate a triangle in a given direction by a given distance;
-
- Triangle2d.translateIn direction distance
-
-is equivalent to
-
- Triangle2d.translateBy
- (Vector2d.withLength distance direction)
-
--}
+{-| -}
translateIn : Direction2d -> Float -> Triangle2d -> Triangle2d
translateIn direction distance triangle =
translateBy (Vector2d.withLength distance direction) triangle
-{-| Mirror a triangle across a given axis.
-
- Triangle2d.mirrorAcross Axis2d.y exampleTriangle
- --> Triangle2d.fromVertices
- --> ( Point2d.fromCoordinates ( -1, 1 )
- --> , Point2d.fromCoordinates ( -2, 1 )
- --> , Point2d.fromCoordinates ( -1, 3 )
- --> )
-
-Note that mirroring a triangle will result in its 'winding direction' being
-flipped - if the triangle's vertices were in counterclockwise order before
-mirroring, they will be in clockwise order afterwards and vice versa.
-
--}
+{-| -}
mirrorAcross : Axis2d -> Triangle2d -> Triangle2d
mirrorAcross axis =
mapVertices (Point2d.mirrorAcross axis)
-{-| Transform each vertex of a triangle by a given function and create a new
-triangle from the resulting points. Most other transformation functions can be
-defined in terms of `mapVertices`; for example,
-
- Triangle2d.mirrorAcross axis
-
-is equivalent to
-
- Triangle2d.mapVertices (Point2d.mirrorAcross axis)
-
--}
+{-| -}
mapVertices : (Point2d -> Point2d) -> Triangle2d -> Triangle2d
mapVertices function triangle =
let
@@ -385,55 +231,19 @@ mapVertices function triangle =
fromVertices ( function p1, function p2, function p3 )
-{-| Take a triangle defined in global coordinates, and return it expressed
-in local coordinates relative to a given reference frame.
-
- localFrame =
- Frame2d.atPoint (Point2d.fromCoordinates ( 1, 2 ))
-
- Triangle2d.relativeTo localFrame exampleTriangle
- --> Triangle2d.fromVertices
- --> ( Point2d.fromCoordinates ( 0, -1 )
- --> , Point2d.fromCoordinates ( 1, -1 )
- --> , Point2d.fromCoordinates ( 0, 1 )
- --> )
-
--}
+{-| -}
relativeTo : Frame2d -> Triangle2d -> Triangle2d
relativeTo frame =
mapVertices (Point2d.relativeTo frame)
-{-| Take a triangle considered to be defined in local coordinates relative to a
-given reference frame, and return that triangle expressed in global coordinates.
-
- localFrame =
- Frame2d.atPoint (Point2d.fromCoordinates ( 1, 2 ))
-
- Triangle2d.placeIn localFrame exampleTriangle
- --> Triangle2d.fromVertices
- --> ( Point2d.fromCoordinates ( 2, 3 )
- --> , Point2d.fromCoordinates ( 3, 3 )
- --> , Point2d.fromCoordinates ( 2, 5 )
- --> )
-
--}
+{-| -}
placeIn : Frame2d -> Triangle2d -> Triangle2d
placeIn frame =
mapVertices (Point2d.placeIn frame)
-{-| Get the minimal bounding box containing a given triangle.
-
- Triangle2d.boundingBox exampleTriangle
- --> BoundingBox2d.fromExtrema
- --> { minX = 1
- --> , maxX = 2
- --> , minY = 1
- --> , maxY = 3
- --> }
-
--}
+{-| -}
boundingBox : Triangle2d -> BoundingBox2d
boundingBox triangle =
let
@@ -457,22 +267,7 @@ boundingBox triangle =
}
-{-| Attempt to find the circumcircle of a triangle, a circle that passes through
-each of the triangle's vertices;
-
- Triangle2d.circumcircle triangle
-
-is equivalent to
-
- ( p1, p2, p3 ) =
- Triangle2d.vertices triangle
-
- Circle2d.throughPoints p1 p2 p3
-
-If the triangle is degenerate (its three vertices are collinear), returns
-`Nothing`.
-
--}
+{-| -}
circumcircle : Triangle2d -> Maybe Circle2d
circumcircle triangle =
let
diff --git a/src/Triangle3d.elm b/src/Triangle3d.elm
index 45c731c6..f4d17c14 100644
--- a/src/Triangle3d.elm
+++ b/src/Triangle3d.elm
@@ -65,9 +65,6 @@ Transforming a triangle is equivalent to transforming its vertices.
# Coordinate conversions
-Functions for transforming triangles between local and global coordinates in
-different coordinate frames.
-
@docs relativeTo, placeIn, projectInto
-}
@@ -91,37 +88,13 @@ type alias Triangle3d =
Types.Triangle3d
-{-| Construct a triangle from its three vertices:
-
- exampleTriangle =
- Triangle3d.fromVertices
- ( Point3d.fromCoordinates ( 1, 0, 0 )
- , Point3d.fromCoordinates ( 2, 0, 0 )
- , Point3d.fromCoordinates ( 2, 1, 3 )
- )
-
--}
+{-| -}
fromVertices : ( Point3d, Point3d, Point3d ) -> Triangle3d
fromVertices =
Types.Triangle3d
-{-| Construct a 3D triangle lying _on_ a sketch plane by providing a 2D triangle
-specified in XY coordinates _within_ the sketch plane.
-
- Triangle3d.on SketchPlane3d.xz <|
- Triangle2d.fromVertices
- ( Point2d.fromCoordinates ( 1, 1 )
- , Point2d.fromCoordinates ( 2, 1 )
- , Point2d.fromCoordinates ( 1, 3 )
- )
- --> Triangle3d.fromVertices
- --> ( Point3d.fromCoordinates ( 1, 0, 1 )
- --> , Point3d.fromCoordinates ( 2, 0, 1 )
- --> , Point3d.fromCoordinates ( 1, 0, 3 )
- --> )
-
--}
+{-| -}
on : SketchPlane3d -> Triangle2d -> Triangle3d
on sketchPlane triangle2d =
let
@@ -135,48 +108,13 @@ on sketchPlane triangle2d =
)
-{-| Get the vertices of a triangle.
-
- ( p1, p2, p3 ) =
- Triangle3d.vertices exampleTriangle
-
-
- --> p1 = Point3d.fromCoordinates ( 1, 0, 0 )
- --> p2 = Point3d.fromCoordinates ( 2, 0, 0 )
- --> p3 = Point3d.fromCoordinates ( 2, 1, 3 )
-
--}
+{-| -}
vertices : Triangle3d -> ( Point3d, Point3d, Point3d )
vertices (Types.Triangle3d vertices_) =
vertices_
-{-| Get the edges of a triangle: from the first vertex to the second, from the
-second to the third, and from the third back to the first.
-
- ( e1, e2, e3 ) =
- Triangle3d.edges exampleTriangle
-
-
- --> e1 =
- --> LineSegment3d.fromEndpoints
- --> ( Point3d.fromCoordinates ( 1, 0, 0 )
- --> , Point3d.fromCoordinates ( 2, 0, 0 )
- --> )
- -->
- --> e2 =
- --> LineSegment3d.fromEndpoints
- --> ( Point3d.fromCoordinates ( 2, 0, 0 )
- --> , Point3d.fromCoordinates ( 2, 1, 3 )
- --> )
- -->
- --> e3 =
- --> LineSegment3d.fromEndpoints
- --> ( Point3d.fromCoordinates ( 2, 1, 3 )
- --> , Point3d.fromCoordinates ( 1, 0, 0 )
- --> )
-
--}
+{-| -}
edges : Triangle3d -> ( LineSegment3d, LineSegment3d, LineSegment3d )
edges triangle =
let
@@ -189,12 +127,7 @@ edges triangle =
)
-{-| Get the centroid (center of mass) of a triangle.
-
- Triangle3d.centroid exampleTriangle
- --> Point3d.fromCoordinates ( 1.6667, 0.6667, 1 )
-
--}
+{-| -}
centroid : Triangle3d -> Point3d
centroid triangle =
let
@@ -213,12 +146,7 @@ centroid triangle =
Point3d.translateBy displacement p1
-{-| Get the area of a triangle. This value is always positive.
-
- Triangle3d.area exampleTriangle
- --> 1.5811
-
--}
+{-| -}
area : Triangle3d -> Float
area triangle =
let
@@ -234,19 +162,7 @@ area triangle =
0.5 * Vector3d.length (Vector3d.crossProduct firstVector secondVector)
-{-| Attempt to find the normal direction to a triangle. The resulting direction
-will be oriented such that the triangle vertices are in counterclockwise order
-around it according to the right-hand rule. If the triangle is degenerate (its
-three vertices are collinear), returns `Nothing`.
-
- Triangle3d.normalDirection exampleTriangle
- --> Just
- --> (Direction3d.fromAzimuthAndElevation
- --> (degrees -90)
- --> (degrees 18.43)
- --> )
-
--}
+{-| -}
normalDirection : Triangle3d -> Maybe Direction3d
normalDirection triangle =
let
@@ -262,119 +178,43 @@ normalDirection triangle =
Vector3d.direction (Vector3d.crossProduct v1 v2)
-{-| Scale a triangle about a given point by a given scale.
-
- Triangle3d.scaleAbout Point3d.origin 2 exampleTriangle
- --> Triangle3d.fromVertices
- --> ( Point3d.fromCoordinates ( 2, 0, 0 )
- --> , Point3d.fromCoordinates ( 4, 0, 0 )
- --> , Point3d.fromCoordinates ( 4, 2, 6 )
- --> )
-
--}
+{-| -}
scaleAbout : Point3d -> Float -> Triangle3d -> Triangle3d
scaleAbout centerPoint scale =
mapVertices (Point3d.scaleAbout centerPoint scale)
-{-| Rotate a triangle around a given axis by a given angle (in radians).
-
- exampleTriangle
- |> Triangle3d.rotateAround Axis3d.z (degrees 90)
- --> Triangle3d.fromVertices
- --> ( Point3d.fromCoordinates ( 0, 1, 0 )
- --> , Point3d.fromCoordinates ( 0, 2, 0 )
- --> , Point3d.fromCoordinates ( -1, 2, 3 )
- --> )
-
--}
+{-| -}
rotateAround : Axis3d -> Float -> Triangle3d -> Triangle3d
rotateAround axis angle =
mapVertices (Point3d.rotateAround axis angle)
-{-| Translate a triangle by a given displacement.
-
- displacement =
- Vector3d.fromComponents ( 2, -1, 3 )
-
- Triangle3d.translateBy displacement exampleTriangle
- --> Triangle3d.fromVertices
- --> ( Point3d.fromCoordinates ( 3, -1, 3 )
- --> , Point3d.fromCoordinates ( 4, -1, 3 )
- --> , Point3d.fromCoordinates ( 4, 0, 6 )
- --> )
-
--}
+{-| -}
translateBy : Vector3d -> Triangle3d -> Triangle3d
translateBy vector =
mapVertices (Point3d.translateBy vector)
-{-| Translate a triangle in a given direction by a given distance;
-
- Triangle3d.translateIn direction distance
-
-is equivalent to
-
- Triangle3d.translateBy
- (Vector3d.withLength distance direction)
-
--}
+{-| -}
translateIn : Direction3d -> Float -> Triangle3d -> Triangle3d
translateIn direction distance triangle =
translateBy (Vector3d.withLength distance direction) triangle
-{-| Mirror a triangle across a given plane.
-
- Triangle3d.mirrorAcross Plane3d.yz exampleTriangle
- --> Triangle3d.fromVertices
- --> ( Point3d.fromCoordinates ( -1, 0, 0 )
- --> ( Point3d.fromCoordinates ( -2, 0, 0 )
- --> ( Point3d.fromCoordinates ( -2, 1, 3 )
- --> )
-
--}
+{-| -}
mirrorAcross : Plane3d -> Triangle3d -> Triangle3d
mirrorAcross plane =
mapVertices (Point3d.mirrorAcross plane)
-{-| Find the [orthographic projection](https://en.wikipedia.org/wiki/Orthographic_projection)
-of a triangle onto a plane.
-
- Triangle3d.projectOnto Plane3d.xy exampleTriangle
- --> Triangle3d.fromVertices
- --> ( Point3d.fromCoordinates ( 1, 0, 0 )
- --> , Point3d.fromCoordinates ( 2, 0, 0 )
- --> , Point3d.fromCoordinates ( 2, 1, 0 )
- --> )
-
- Triangle3d.projectOnto Plane3d.xz exampleTriangle
- --> Triangle3d.fromVertices
- --> ( Point3d.fromCoordinates ( 1, 0, 0 )
- --> , Point3d.fromCoordinates ( 2, 0, 0 )
- --> , Point3d.fromCoordinates ( 2, 0, 3 )
- --> )
-
--}
+{-| -}
projectOnto : Plane3d -> Triangle3d -> Triangle3d
projectOnto plane =
mapVertices (Point3d.projectOnto plane)
-{-| Transform each vertex of a triangle by a given function and create a new
-triangle from the resulting points. Most other transformation functions can be
-defined in terms of `mapVertices`; for example,
-
- Triangle3d.projectOnto plane
-
-is equivalent to
-
- Triangle3d.mapVertices (Point3d.projectOnto plane)
-
--}
+{-| -}
mapVertices : (Point3d -> Point3d) -> Triangle3d -> Triangle3d
mapVertices function triangle =
let
@@ -384,66 +224,19 @@ mapVertices function triangle =
fromVertices ( function p1, function p2, function p3 )
-{-| Take a triangle defined in global coordinates, and return it expressed
-in local coordinates relative to a given reference frame.
-
- localFrame =
- Frame3d.atPoint
- (Point3d.fromCoordinates ( 2, 1, 3 ))
-
- Triangle3d.relativeTo localFrame exampleTriangle
- --> Triangle3d.fromVertices
- --> ( Point3d.fromCoordinates ( -1, -1, -3 )
- --> , Point3d.fromCoordinates ( 0, -1, -3 )
- --> , Point3d.fromCoordinates ( 0, 0, 0 )
- --> )
-
--}
+{-| -}
relativeTo : Frame3d -> Triangle3d -> Triangle3d
relativeTo frame =
mapVertices (Point3d.relativeTo frame)
-{-| Take a triangle considered to be defined in local coordinates relative to a
-given reference frame, and return that triangle expressed in global coordinates.
-
- localFrame =
- Frame3d.atPoint
- (Point3d.fromCoordinates ( 2, 1, 3 ))
-
- Triangle3d.placeIn localFrame exampleTriangle
- --> Triangle3d.fromVertices
- --> ( Point3d.fromCoordinates ( 3, 1, 3 )
- --> , Point3d.fromCoordinates ( 4, 1, 3 )
- --> , Point3d.fromCoordinates ( 4, 2, 6 )
- --> )
-
--}
+{-| -}
placeIn : Frame3d -> Triangle3d -> Triangle3d
placeIn frame =
mapVertices (Point3d.placeIn frame)
-{-| Project a triangle into a given sketch plane. Conceptually, this finds the
-[orthographic projection](https://en.wikipedia.org/wiki/Orthographic_projection)
-of the triangle onto the plane and then expresses the projected triangle in 2D
-sketch coordinates.
-
- Triangle3d.projectInto SketchPlane3d.xy exampleTriangle
- --> Triangle2d.fromVertices
- --> ( Point2d.fromCoordinates ( 1, 0 )
- --> , Point2d.fromCoordinates ( 2, 0 )
- --> , Point2d.fromCoordinates ( 2, 1 )
- --> )
-
- Triangle3d.projectInto SketchPlane3d.zx exampleTriangle
- --> Triangle2d.fromVertices
- --> ( Point2d.fromCoordinates ( 0, 1 )
- --> , Point2d.fromCoordinates ( 0, 2 )
- --> , Point2d.fromCoordinates ( 3, 2 )
- --> )
-
--}
+{-| -}
projectInto : SketchPlane3d -> Triangle3d -> Triangle2d
projectInto sketchPlane triangle =
let
@@ -456,19 +249,7 @@ projectInto sketchPlane triangle =
Triangle2d.fromVertices ( project p1, project p2, project p3 )
-{-| Get the minimal bounding box containing a given triangle.
-
- Triangle3d.boundingBox exampleTriangle
- --> BoundingBox3d.fromExtrema
- --> { minX = 1
- --> , maxX = 2
- --> , minY = 0
- --> , maxY = 1
- --> , minZ = 0
- --> , maxZ = 3
- --> }
-
--}
+{-| -}
boundingBox : Triangle3d -> BoundingBox3d
boundingBox triangle =
let
@@ -494,22 +275,7 @@ boundingBox triangle =
}
-{-| Attempt to find the circumcircle of a triangle, a circle that passes through
-each of the triangle's vertices;
-
- Triangle3d.circumcircle triangle
-
-is equivalent to
-
- ( p1, p2, p3 ) =
- Triangle3d.vertices triangle
-
- Circle3d.throughPoints p1 p2 p3
-
-If the triangle is degenerate (its three vertices are collinear), returns
-`Nothing`.
-
--}
+{-| -}
circumcircle : Triangle3d -> Maybe Circle3d
circumcircle triangle =
let
diff --git a/src/Vector2d.elm b/src/Vector2d.elm
index 9bfdd72d..c66fcaa4 100644
--- a/src/Vector2d.elm
+++ b/src/Vector2d.elm
@@ -113,15 +113,8 @@ tail is on the axis, then mirroring/projecting its tip across/onto the axis.
# Coordinate conversions
-Functions for transforming vectors between local and global coordinates in
-different coordinate frames. Like other transformations, coordinate conversions
-of vectors depend only on the orientations of the relevant frames, not the
-positions of their origin points.
-
-For the examples, assume the following frame has been defined:
-
- rotatedFrame =
- Frame2d.rotateBy (degrees 30) Frame2d.xy
+Like other transformations, coordinate conversions of vectors depend only on the
+orientations of the relevant frames, not the positions of their origin points.
@docs relativeTo, placeIn
@@ -140,52 +133,25 @@ type alias Vector2d =
Types.Vector2d
-{-| The zero vector.
-
- Vector2d.zero
- --> Vector2d.fromComponents ( 0, 0 )
-
--}
+{-| -}
zero : Vector2d
zero =
fromComponents ( 0, 0 )
-{-| Construct a vector from its X and Y components.
-
- vector =
- Vector2d.fromComponents ( 2, 3 )
-
--}
+{-| -}
fromComponents : ( Float, Float ) -> Vector2d
fromComponents =
Types.Vector2d
-{-| Construct a vector from a length and angle. The angle is measured
-counterclockwise from the positive X direction.
-
- Vector2d.fromPolarComponents ( 2, degrees 135 )
- -->Vector2d.fromComponents ( -1.4142, 1.4142 )
-
--}
+{-| -}
fromPolarComponents : ( Float, Float ) -> Vector2d
fromPolarComponents polarComponents_ =
fromComponents (fromPolar polarComponents_)
-{-| Construct a vector from the first given point to the second.
-
- startPoint =
- Point2d.fromCoordinates ( 1, 1 )
-
- endPoint =
- Point2d.fromCoordinates ( 4, 5 )
-
- Vector2d.from startPoint endPoint
- --> Vector2d.fromComponents ( 3, 4 )
-
--}
+{-| -}
from : Point2d -> Point2d -> Vector2d
from firstPoint secondPoint =
let
@@ -198,12 +164,7 @@ from firstPoint secondPoint =
fromComponents ( x2 - x1, y2 - y1 )
-{-| Construct a vector with the given length in the given direction.
-
- Vector2d.withLength 5 Direction2d.y
- --> Vector2d.fromComponents ( 0, 5 )
-
--}
+{-| -}
withLength : Float -> Direction2d -> Vector2d
withLength length_ direction_ =
let
@@ -213,64 +174,13 @@ withLength length_ direction_ =
fromComponents ( length_ * dx, length_ * dy )
-{-| Construct a vector perpendicular to the given vector, by rotating the given
-vector 90 degrees counterclockwise. The constructed vector will have the same
-length as the given vector. Alias for `Vector2d.rotateCounterclockwise`.
-
- Vector2d.perpendicularTo
- (Vector2d.fromComponents ( 1, 0 ))
- --> Vector2d.fromComponents ( 0, 1 )
-
- Vector2d.perpendicularTo
- (Vector2d.fromComponents ( 0, 2 ))
- --> Vector2d.fromComponents ( -2, 0 )
-
- Vector2d.perpendicularTo
- (Vector2d.fromComponents ( 3, 1 ))
- --> Vector2d.fromComponents ( -1, 3 )
-
- Vector2d.perpendicularTo Vector2d.zero
- --> Vector2d.zero
-
--}
+{-| -}
perpendicularTo : Vector2d -> Vector2d
perpendicularTo vector =
rotateCounterclockwise vector
-{-| Construct a vector by interpolating from the first given vector to the
-second, based on a parameter that ranges from zero to one.
-
- startVector =
- Vector2d.zero
-
- endVector =
- Vector2d.fromComponents ( 8, 12 )
-
- Vector2d.interpolateFrom startVector endVector 0.25
- --> Vector2d.fromComponents ( 2, 3 )
-
-Partial application may be useful:
-
- interpolatedVector : Float -> Vector2d
- interpolatedVector =
- Vector2d.interpolateFrom startVector endVector
-
- List.map interpolatedVector [ 0, 0.5, 1 ]
- --> [ Vector2d.fromComponents ( 0, 0 )
- --> , Vector2d.fromComponents ( 4, 6 )
- --> , Vector2d.fromComponents ( 8, 12 )
- --> ]
-
-You can pass values less than zero or greater than one to extrapolate:
-
- interpolatedVector -0.5
- --> Vector2d.fromComponents ( -4, -6 )
-
- interpolatedVector 1.25
- --> Vector2d.fromComponents ( 10, 15 )
-
--}
+{-| -}
interpolateFrom : Vector2d -> Vector2d -> Float -> Vector2d
interpolateFrom v1 v2 t =
let
@@ -286,60 +196,25 @@ interpolateFrom v1 v2 t =
)
-{-| Extract the components of a vector.
-
- Vector2d.components (Vector2d.fromComponents ( 2, 3 ))
- --> ( 2, 3 )
-
-This combined with Elm's built-in tuple destructuring provides a convenient way
-to extract both the X and Y components of a vector in one line of code:
-
- ( x, y ) =
- Vector2d.components vector
-
--}
+{-| -}
components : Vector2d -> ( Float, Float )
components (Types.Vector2d components_) =
components_
-{-| Get the X component of a vector.
-
- Vector2d.xComponent (Vector2d.fromComponents ( 2, 3 ))
- --> 2
-
--}
+{-| -}
xComponent : Vector2d -> Float
xComponent (Types.Vector2d ( x, _ )) =
x
-{-| Get the Y component of a vector.
-
- Vector2d.yComponent (Vector2d.fromComponents ( 2, 3 ))
- --> 3
-
--}
+{-| -}
yComponent : Vector2d -> Float
yComponent (Types.Vector2d ( _, y )) =
y
-{-| Find the component of a vector in an arbitrary direction, for example
-
- forwardSpeed =
- Vector2d.componentIn forwardDirection velocity
-
-This is more general and flexible than using `xComponent` or `yComponent`, both
-of which can be expressed in terms of `componentIn`; for example,
-
- Vector2d.xComponent vector
-
-is equivalent to
-
- Vector2d.componentIn Direction2d.x vector
-
--}
+{-| -}
componentIn : Direction2d -> Vector2d -> Float
componentIn direction_ vector =
let
@@ -352,64 +227,25 @@ componentIn direction_ vector =
vx * dx + vy * dy
-{-| Get the polar components (length, polar angle) of a vector.
-
- Vector2d.polarComponents
- (Vector2d.fromComponents ( 1, 1 ))
- --> ( 1.4142, degrees 45 )
-
--}
+{-| -}
polarComponents : Vector2d -> ( Float, Float )
polarComponents vector =
toPolar (components vector)
-{-| Compare two vectors within a tolerance. Returns true if the difference
-between the two given vectors has magnitude less than the given tolerance.
-
- firstVector =
- Vector2d.fromComponents ( 1, 2 )
-
- secondVector =
- Vector2d.fromComponents ( 0.9999, 2.0002 )
-
- Vector2d.equalWithin 1e-3 firstVector secondVector
- --> True
-
- Vector2d.equalWithin 1e-6 firstVector secondVector
- --> False
-
--}
+{-| -}
equalWithin : Float -> Vector2d -> Vector2d -> Bool
equalWithin tolerance firstVector secondVector =
squaredLength (difference firstVector secondVector) <= tolerance * tolerance
-{-| Get the length (magnitude) of a vector.
-
- Vector2d.length (Vector2d.fromComponents ( 3, 4 ))
- --> 5
-
--}
+{-| -}
length : Vector2d -> Float
length vector =
sqrt (squaredLength vector)
-{-| Get the squared length of a vector. `squaredLength` is slightly faster than
-`length`, so for example
-
- Vector2d.squaredLength vector > tolerance * tolerance
-
-is equivalent to but slightly more efficient than
-
- Vector2d.length vector > tolerance
-
-since the latter requires a square root under the hood. In many cases, however,
-the speed difference will be negligible and using `length` is much more
-readable!
-
--}
+{-| -}
squaredLength : Vector2d -> Float
squaredLength vector =
let
@@ -419,16 +255,7 @@ squaredLength vector =
x * x + y * y
-{-| Attempt to find the direction of a vector. In the case of a zero vector,
-return `Nothing`.
-
- Vector2d.direction (Vector2d.fromComponents ( 3, 3 ))
- --> Just (Direction2d.fromAngle (degrees 45))
-
- Vector2d.direction Vector2d.zero
- --> Nothing
-
--}
+{-| -}
direction : Vector2d -> Maybe Direction2d
direction vector =
if vector == zero then
@@ -441,22 +268,7 @@ direction vector =
Just (Direction2d.unsafe (components normalizedVector))
-{-| Attempt to find the length and direction of a vector. In the case of a zero
-vector, returns `Nothing`.
-
- vector =
- Vector2d.fromComponents ( 1, 1 )
-
- Vector2d.lengthAndDirection vector
- --> Just
- --> ( 1.4142
- --> , Direction2d.fromAngle (degrees 45)
- --> )
-
- Vector2d.lengthAndDirection Vector2d.zero
- --> Nothing
-
--}
+{-| -}
lengthAndDirection : Vector2d -> Maybe ( Float, Direction2d )
lengthAndDirection vector =
let
@@ -476,30 +288,7 @@ lengthAndDirection vector =
Just ( vectorLength, vectorDirection )
-{-| Normalize a vector to have a length of one. Zero vectors are left as-is.
-
- vector =
- Vector2d.fromComponents ( 3, 4 )
-
- Vector2d.normalize vector
- --> Vector2d.fromComponents ( 0.6, 0.8 )
-
- Vector2d.normalize Vector2d.zero
- --> Vector2d.zero
-
-**Warning**: `Vector2d.direction` is safer since it forces you to explicitly
-consider the case where the given vector is zero. `Vector2d.normalize` is
-primarily useful for cases like generating WebGL meshes, where defaulting to a
-zero vector for degenerate cases is acceptable, and the overhead of something
-like
-
- Vector2d.direction vector
- |> Maybe.map Direction2d.toVector
- |> Maybe.withDefault Vector2d.zero
-
-(which is functionally equivalent to `Vector2d.normalize vector`) is too high.
-
--}
+{-| -}
normalize : Vector2d -> Vector2d
normalize vector =
if vector == zero then
@@ -508,18 +297,7 @@ normalize vector =
scaleBy (1 / length vector) vector
-{-| Find the sum of two vectors.
-
- firstVector =
- Vector2d.fromComponents ( 1, 2 )
-
- secondVector =
- Vector2d.fromComponents ( 3, 4 )
-
- Vector2d.sum firstVector secondVector
- --> Vector2d.fromComponents ( 4, 6 )
-
--}
+{-| -}
sum : Vector2d -> Vector2d -> Vector2d
sum firstVector secondVector =
let
@@ -532,18 +310,7 @@ sum firstVector secondVector =
fromComponents ( x1 + x2, y1 + y2 )
-{-| Find the difference between two vectors (the first vector minus the second).
-
- firstVector =
- Vector2d.fromComponents ( 5, 6 )
-
- secondVector =
- Vector2d.fromComponents ( 1, 3 )
-
- Vector2d.difference firstVector secondVector
- --> Vector2d.fromComponents ( 4, 3 )
-
--}
+{-| -}
difference : Vector2d -> Vector2d -> Vector2d
difference firstVector secondVector =
let
@@ -556,18 +323,7 @@ difference firstVector secondVector =
fromComponents ( x1 - x2, y1 - y2 )
-{-| Find the dot product of two vectors.
-
- firstVector =
- Vector2d.fromComponents ( 1, 2 )
-
- secondVector =
- Vector2d.fromComponents ( 3, 4 )
-
- Vector2d.dotProduct firstVector secondVector
- --> 11
-
--}
+{-| -}
dotProduct : Vector2d -> Vector2d -> Float
dotProduct firstVector secondVector =
let
@@ -580,46 +336,7 @@ dotProduct firstVector secondVector =
x1 * x2 + y1 * y2
-{-| Find the scalar 'cross product' of two vectors in 2D. This is defined as
-
- crossProduct firstVector secondVector =
- let
- ( x1, y1 ) =
- components firstVector
-
- ( x2, y2 ) =
- components secondVector
- in
- x1 * y2 - y1 * x2
-
-and is useful in many of the same ways as the 3D cross product:
-
- - Its length is equal to the product of the lengths of the two given vectors
- and the sine of the angle between them, so it can be used as a metric to
- determine if two vectors are nearly parallel.
- - The sign of the result indicates the direction of rotation from the first
- vector to the second (positive indicates a counterclockwise rotation and
- negative indicates a clockwise rotation), similar to how the direction of
- the 3D cross product indicates the direction of rotation.
-
-Some examples:
-
- firstVector =
- Vector2d.fromComponents ( 2, 0 )
-
- secondVector =
- Vector2d.fromComponents ( 0, 3 )
-
- Vector2d.crossProduct firstVector secondVector
- --> 6
-
- Vector2d.crossProduct secondVector firstVector
- --> -6
-
- Vector2d.crossProduct firstVector firstVector
- --> 0
-
--}
+{-| -}
crossProduct : Vector2d -> Vector2d -> Float
crossProduct firstVector secondVector =
let
@@ -632,12 +349,7 @@ crossProduct firstVector secondVector =
x1 * y2 - y1 * x2
-{-| Reverse the direction of a vector, negating its components.
-
- Vector2d.reverse (Vector2d.fromComponents ( -1, 2 ))
- --> Vector2d.fromComponents ( 1, -2 )
-
--}
+{-| -}
reverse : Vector2d -> Vector2d
reverse vector =
let
@@ -647,12 +359,7 @@ reverse vector =
fromComponents ( -x, -y )
-{-| Scale the length of a vector by a given scale.
-
- Vector2d.scaleBy 3 (Vector2d.fromComponents ( 1, 2 ))
- --> Vector2d.fromComponents ( 3, 6 )
-
--}
+{-| -}
scaleBy : Float -> Vector2d -> Vector2d
scaleBy scale vector =
let
@@ -662,17 +369,7 @@ scaleBy scale vector =
fromComponents ( x * scale, y * scale )
-{-| Rotate a vector counterclockwise by a given angle (in radians).
-
- Vector2d.fromComponents ( 1, 1 )
- |> Vector2d.rotateBy (degrees 45)
- --> Vector2d.fromComponents ( 0, 1.4142 )
-
- Vector2d.fromComponents ( 1, 0 )
- |> Vector2d.rotateBy pi
- --> Vector2d.fromComponents ( -1, 0 )
-
--}
+{-| -}
rotateBy : Float -> Vector2d -> Vector2d
rotateBy angle =
let
@@ -690,17 +387,7 @@ rotateBy angle =
fromComponents ( x * cosine - y * sine, y * cosine + x * sine )
-{-| Rotate the given vector 90 degrees counterclockwise;
-
- Vector2d.rotateCounterclockwise vector
-
-is equivalent to
-
- Vector2d.rotateBy (degrees 90) vector
-
-but is more efficient.
-
--}
+{-| -}
rotateCounterclockwise : Vector2d -> Vector2d
rotateCounterclockwise vector =
let
@@ -710,17 +397,7 @@ rotateCounterclockwise vector =
fromComponents ( -y, x )
-{-| Rotate the given vector 90 degrees clockwise;
-
- Vector2d.rotateClockwise vector
-
-is equivalent to
-
- Vector2d.rotateBy (degrees -90) vector
-
-but is more efficient.
-
--}
+{-| -}
rotateClockwise : Vector2d -> Vector2d
rotateClockwise vector =
let
@@ -730,24 +407,7 @@ rotateClockwise vector =
fromComponents ( y, -x )
-{-| Mirror a vector across a given axis.
-
- vector =
- Vector2d.fromComponents ( 2, 3 )
-
- Vector2d.mirrorAcross Axis2d.y vector
- --> Vector2d.fromComponents ( -2, 3 )
-
-The position of the axis doesn't matter, only its orientation:
-
- horizontalAxis =
- Axis2d.withDirection Direction2d.x
- (Point2d.fromCoordinates ( 100, 200 ))
-
- Vector2d.mirrorAcross horizontalAxis vector
- --> Vector2d.fromComponents ( 2, -3 )
-
--}
+{-| -}
mirrorAcross : Axis2d -> Vector2d -> Vector2d
mirrorAcross axis =
let
@@ -771,52 +431,19 @@ mirrorAcross axis =
fromComponents ( a * vx + b * vy, c * vy + b * vx )
-{-| Find the projection of a vector in a particular direction. Conceptually,
-this means splitting the original vector into a portion parallel to the given
-direction and a portion perpendicular to it, then returning the parallel
-portion.
-
- vector =
- Vector2d.fromComponents ( 2, 3 )
-
- Vector2d.projectionIn Direction2d.x vector
- --> Vector2d.fromComponents ( 2, 0 )
-
- Vector2d.projectionIn Direction2d.y vector
- --> Vector2d.fromComponents ( 0, 3 )
-
--}
+{-| -}
projectionIn : Direction2d -> Vector2d -> Vector2d
projectionIn direction_ vector =
direction_ |> withLength (vector |> componentIn direction_)
-{-| Project a vector onto an axis.
-
- Vector2d.projectOnto Axis2d.y
- (Vector2d.fromComponents ( 3, 4 ))
- --> Vector2d.fromComponents ( 0, 4 )
-
- Vector2d.projectOnto Axis2d.x
- (Vector2d.fromComponents ( -1, 2 ))
- --> Vector2d.fromComponents ( -1, 0 )
-
-This is equivalent to finding the projection in the axis' direction.
-
--}
+{-| -}
projectOnto : Axis2d -> Vector2d -> Vector2d
projectOnto axis vector =
projectionIn (Axis2d.direction axis) vector
-{-| Take a vector defined in global coordinates, and return it expressed in
-local coordinates relative to a given reference frame.
-
- Vector2d.fromComponents ( 2, 0 )
- |> Vector2d.relativeTo rotatedFrame
- --> Vector2d.fromComponents ( 1.732, -1 )
-
--}
+{-| -}
relativeTo : Frame2d -> Vector2d -> Vector2d
relativeTo frame vector =
fromComponents
@@ -825,14 +452,7 @@ relativeTo frame vector =
)
-{-| Take a vector defined in local coordinates relative to a given reference
-frame, and return that vector expressed in global coordinates.
-
- Vector2d.fromComponents ( 2, 0 )
- |> Vector2d.placeIn rotatedFrame
- --> Vector2d.fromComponents ( 1.732, 1 )
-
--}
+{-| -}
placeIn : Frame2d -> Vector2d -> Vector2d
placeIn frame =
let
diff --git a/src/Vector3d.elm b/src/Vector3d.elm
index b538044d..9c1784cc 100644
--- a/src/Vector3d.elm
+++ b/src/Vector3d.elm
@@ -113,17 +113,8 @@ its tip.
# Coordinate conversions
-Functions for transforming vectors between local and global coordinates in
-different coordinate frames. Like other transformations, coordinate
-transformations of vectors depend only on the orientations of the relevant
-frames/sketch planes, 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.xyz
+Like other transformations, coordinate transformations of vectors depend only on
+the orientations of the relevant frames/sketch planes, not their positions.
@docs relativeTo, placeIn, projectInto
@@ -144,40 +135,19 @@ type alias Vector3d =
Types.Vector3d
-{-| The zero vector.
-
- Vector3d.zero
- --> Vector3d.fromComponents ( 0, 0, 0 )
-
--}
+{-| -}
zero : Vector3d
zero =
fromComponents ( 0, 0, 0 )
-{-| Construct a vector from its X, Y and Z components.
-
- vector =
- Vector3d.fromComponents ( 2, 1, 3 )
-
--}
+{-| -}
fromComponents : ( Float, Float, Float ) -> Vector3d
fromComponents =
Types.Vector3d
-{-| Construct a vector from the first given point to the second.
-
- startPoint =
- Point3d.fromCoordinates ( 1, 1, 1 )
-
- endPoint =
- Point3d.fromCoordinates ( 4, 5, 6 )
-
- Vector3d.from startPoint endPoint
- --> Vector3d.fromComponents ( 3, 4, 5 )
-
--}
+{-| -}
from : Point3d -> Point3d -> Vector3d
from firstPoint secondPoint =
let
@@ -190,12 +160,7 @@ from firstPoint secondPoint =
fromComponents ( x2 - x1, y2 - y1, z2 - z1 )
-{-| Construct a vector with the given length in the given direction.
-
- Vector3d.withLength 5 Direction3d.y
- --> Vector3d.fromComponents ( 0, 5, 0 )
-
--}
+{-| -}
withLength : Float -> Direction3d -> Vector3d
withLength length_ direction_ =
let
@@ -205,33 +170,7 @@ withLength length_ direction_ =
fromComponents ( length_ * dx, length_ * dy, length_ * dz )
-{-| Construct a 3D vector lying _on_ a sketch plane by providing a 2D vector
-specified in XY coordinates _within_ the sketch plane.
-
- vector2d =
- Vector2d.fromComponents ( 2, 3 )
-
- Vector3d.on SketchPlane3d.xy vector2d
- --> Vector3d.fromComponents ( 2, 3, 0 )
-
- Vector3d.on SketchPlane3d.yz vector2d
- --> Vector3d.fromComponents ( 0, 2, 3 )
-
- Vector3d.on SketchPlane3d.zx vector2d
- --> Vector3d.fromComponents ( 3, 0, 2 )
-
-A slightly more complex example:
-
- tiltedSketchPlane =
- SketchPlane3d.xy
- |> SketchPlane3d.rotateAround Axis3d.x
- (degrees 45)
-
- Vector3d.on tiltedSketchPlane <|
- Vector2d.fromComponents ( 1, 1 )
- --> Vector3d.fromComponents ( 1, 0.7071, 0.7071 )
-
--}
+{-| -}
on : SketchPlane3d -> Vector2d -> Vector3d
on sketchPlane vector2d =
let
@@ -251,23 +190,7 @@ on sketchPlane vector2d =
)
-{-| Construct an arbitrary vector perpendicular to the given vector. The exact
-length and direction of the resulting vector are not specified, but it is
-guaranteed to be perpendicular to the given vector and non-zero (unless the
-given vector is itself zero).
-
- Vector3d.perpendicularTo
- (Vector3d.fromComponents ( 3, 0, 0 ))
- --> Vector3d.fromComponents ( 0, 0, -3 )
-
- Vector3d.perpendicularTo
- (Vector3d.fromComponents ( 1, 2, 3 ))
- --> Vector3d.fromComponents ( 0, -3, 2 )
-
- Vector3d.perpendicularTo Vector3d.zero
- --> Vector3d.zero
-
--}
+{-| -}
perpendicularTo : Vector3d -> Vector3d
perpendicularTo vector =
let
@@ -294,39 +217,7 @@ perpendicularTo vector =
fromComponents ( -y, x, 0 )
-{-| Construct a vector by interpolating from the first given vector to the
-second, based on a parameter that ranges from zero to one.
-
- startVector =
- Vector3d.fromComponents ( 1, 2, 4 )
-
- endVector =
- Vector3d.fromComponents ( 1, 3, 8 )
-
- Vector3d.interpolateFrom startVector endVector 0.25
- --> Vector3d.fromComponents ( 1, 2.25, 5 )
-
-Partial application may be useful:
-
- interpolatedVector : Float -> Vector3d
- interpolatedVector =
- Vector3d.interpolateFrom startVector endVector
-
- List.map interpolatedVector [ 0, 0.5, 1 ]
- --> [ Vector3d.fromComponents ( 1, 2, 4 )
- --> , Vector3d.fromComponents ( 1, 2, 6 )
- --> , Vector3d.fromComponents ( 1, 2, 8 )
- --> ]
-
-You can pass values less than zero or greater than one to extrapolate:
-
- interpolatedVector -0.5
- --> Vector3d.fromComponents ( 1, 2, 2 )
-
- interpolatedVector 1.25
- --> Vector3d.fromComponents ( 1, 2, 9 )
-
--}
+{-| -}
interpolateFrom : Vector3d -> Vector3d -> Float -> Vector3d
interpolateFrom v1 v2 t =
let
@@ -343,76 +234,31 @@ interpolateFrom v1 v2 t =
)
-{-| Extract the components of a vector.
-
- Vector3d.fromComponents ( 2, 3, 4 )
- |> Vector3d.components
- --> ( 2, 3, 4 )
-
-This combined with Elm's built-in tuple destructuring provides a convenient way
-to extract the X, Y and Z components of a vector in one line of code:
-
- ( x, y, z ) =
- Vector3d.components vector
-
--}
+{-| -}
components : Vector3d -> ( Float, Float, Float )
components (Types.Vector3d components_) =
components_
-{-| Get the X component of a vector.
-
- Vector3d.fromComponents ( 1, 2, 3 )
- |> Vector3d.xComponent
- --> 1
-
--}
+{-| -}
xComponent : Vector3d -> Float
xComponent (Types.Vector3d ( x, _, _ )) =
x
-{-| Get the Y component of a vector.
-
- Vector3d.fromComponents ( 1, 2, 3 )
- |> Vector3d.yComponent
- --> 2
-
--}
+{-| -}
yComponent : Vector3d -> Float
yComponent (Types.Vector3d ( _, y, _ )) =
y
-{-| Get the Z component of a vector.
-
- Vector3d.fromComponents ( 1, 2, 3 )
- |> Vector3d.zComponent
- --> 3
-
--}
+{-| -}
zComponent : Vector3d -> Float
zComponent (Types.Vector3d ( _, _, z )) =
z
-{-| Find the component of a vector in an arbitrary direction, for example
-
- verticalSpeed =
- Vector3d.componentIn upDirection velocity
-
-This is more general and flexible than using `xComponent`, `yComponent` or
-`zComponent`, all of which can be expressed in terms of `componentIn`; for
-example,
-
- Vector3d.zComponent vector
-
-is equivalent to
-
- Vector3d.componentIn Direction3d.z vector
-
--}
+{-| -}
componentIn : Direction3d -> Vector3d -> Float
componentIn direction_ vector =
let
@@ -425,52 +271,19 @@ componentIn direction_ vector =
vx * dx + vy * dy + vz * dz
-{-| Compare two vectors within a tolerance. Returns true if the difference
-between the two given vectors has magnitude less than the given tolerance.
-
- firstVector =
- Vector3d.fromComponents ( 2, 1, 3 )
-
- secondVector =
- Vector3d.fromComponents ( 2.0002, 0.9999, 3.0001 )
-
- Vector3d.equalWithin 1e-3 firstVector secondVector
- --> True
-
- Vector3d.equalWithin 1e-6 firstVector secondVector
- --> False
-
--}
+{-| -}
equalWithin : Float -> Vector3d -> Vector3d -> Bool
equalWithin tolerance firstVector secondVector =
squaredLength (difference firstVector secondVector) <= tolerance * tolerance
-{-| Get the length (magnitude) of a vector.
-
- Vector3d.length (Vector3d.fromComponents ( 2, 1, 2 ))
- --> 3
-
--}
+{-| -}
length : Vector3d -> Float
length vector =
sqrt (squaredLength vector)
-{-| Get the squared length of a vector. `squaredLength` is slightly faster than
-`length`, so for example
-
- Vector3d.squaredLength vector > tolerance * tolerance
-
-is equivalent to but slightly more efficient than
-
- Vector3d.length vector > tolerance
-
-since the latter requires a square root under the hood. In many cases, however,
-the speed difference will be negligible and using `length` is much more
-readable!
-
--}
+{-| -}
squaredLength : Vector3d -> Float
squaredLength vector =
let
@@ -480,21 +293,7 @@ squaredLength vector =
x * x + y * y + z * z
-{-| Attempt to find the direction of a vector. In the case of a zero vector,
-returns `Nothing`.
-
- Vector3d.fromComponents ( 3, 0, 3 )
- |> Vector3d.direction
- --> Just
- --> (Direction3d.fromAzimuthAndElevation
- --> (degrees 0)
- --> (degrees 45)
- --> )
-
- Vector3d.direction Vector3d.zero
- --> Nothing
-
--}
+{-| -}
direction : Vector3d -> Maybe Direction3d
direction vector =
if vector == zero then
@@ -507,24 +306,7 @@ direction vector =
Just (Direction3d.unsafe (components normalizedVector))
-{-| Attempt to find the length and direction of a vector. In the case of a zero
-vector, returns `Nothing`.
-
- vector =
- Vector3d.fromComponents ( 3, 0, 3 )
-
- Vector3d.lengthAndDirection vector
- --> Just
- --> ( 4.2426
- --> , Direction3d.fromAzimuthAndElevation
- --> (degrees 0)
- --> (degrees 45)
- --> )
-
- Vector3d.lengthAndDirection Vector3d.zero
- --> Nothing
-
--}
+{-| -}
lengthAndDirection : Vector3d -> Maybe ( Float, Direction3d )
lengthAndDirection vector =
let
@@ -544,30 +326,7 @@ lengthAndDirection vector =
Just ( vectorLength, vectorDirection )
-{-| Normalize a vector to have a length of one. Zero vectors are left as-is.
-
- vector =
- Vector3d.fromComponents ( 3, 0, 4 )
-
- Vector3d.normalize vector
- --> Vector3d.fromComponents ( 0.6, 0, 0.8 )
-
- Vector3d.normalize Vector3d.zero
- --> Vector3d.zero
-
-**Warning**: `Vector3d.direction` is safer since it forces you to explicitly
-consider the case where the given vector is zero. `Vector3d.normalize` is
-primarily useful for cases like generating WebGL meshes, where defaulting to a
-zero vector for degenerate cases is acceptable, and the overhead of something
-like
-
- Vector3d.direction vector
- |> Maybe.map Direction3d.toVector
- |> Maybe.withDefault Vector3d.zero
-
-(which is functionally equivalent to `Vector3d.normalize vector`) is too high.
-
--}
+{-| -}
normalize : Vector3d -> Vector3d
normalize vector =
if vector == zero then
@@ -576,18 +335,7 @@ normalize vector =
scaleBy (1 / length vector) vector
-{-| Find the sum of two vectors.
-
- firstVector =
- Vector3d.fromComponents ( 1, 2, 3 )
-
- secondVector =
- Vector3d.fromComponents ( 4, 5, 6 )
-
- Vector3d.sum firstVector secondVector
- --> Vector3d.fromComponents ( 5, 7, 9 )
-
--}
+{-| -}
sum : Vector3d -> Vector3d -> Vector3d
sum firstVector secondVector =
let
@@ -600,18 +348,7 @@ sum firstVector secondVector =
fromComponents ( x1 + x2, y1 + y2, z1 + z2 )
-{-| Find the difference between two vectors (the first vector minus the second).
-
- firstVector =
- Vector3d.fromComponents ( 5, 6, 7 )
-
- secondVector =
- Vector3d.fromComponents ( 1, 1, 1 )
-
- Vector3d.difference firstVector secondVector
- --> Vector3d.fromComponents ( 4, 5, 6 )
-
--}
+{-| -}
difference : Vector3d -> Vector3d -> Vector3d
difference firstVector secondVector =
let
@@ -624,18 +361,7 @@ difference firstVector secondVector =
fromComponents ( x1 - x2, y1 - y2, z1 - z2 )
-{-| Find the dot product of two vectors.
-
- firstVector =
- Vector3d.fromComponents ( 1, 0, 2 )
-
- secondVector =
- Vector3d.fromComponents ( 3, 4, 5 )
-
- Vector3d.dotProduct firstVector secondVector
- --> 13
-
--}
+{-| -}
dotProduct : Vector3d -> Vector3d -> Float
dotProduct firstVector secondVector =
let
@@ -648,18 +374,7 @@ dotProduct firstVector secondVector =
x1 * x2 + y1 * y2 + z1 * z2
-{-| Find the cross product of two vectors.
-
- firstVector =
- Vector3d.fromComponents ( 2, 0, 0 )
-
- secondVector =
- Vector3d.fromComponents ( 0, 3, 0 )
-
- Vector3d.crossProduct firstVector secondVector
- --> Vector3d.fromComponents ( 0, 0, 6 )
-
--}
+{-| -}
crossProduct : Vector3d -> Vector3d -> Vector3d
crossProduct firstVector secondVector =
let
@@ -676,12 +391,7 @@ crossProduct firstVector secondVector =
)
-{-| Reverse the direction of a vector, negating its components.
-
- Vector3d.reverse (Vector3d.fromComponents ( 1, -3, 2 ))
- --> Vector3d.fromComponents ( -1, 3, -2 )
-
--}
+{-| -}
reverse : Vector3d -> Vector3d
reverse vector =
let
@@ -691,13 +401,7 @@ reverse vector =
fromComponents ( -x, -y, -z )
-{-| Scale the length of a vector by a given scale.
-
- Vector3d.fromComponents ( 1, 2, 3 )
- |> Vector3d.scaleBy 3
- --> Vector3d.fromComponents ( 3, 6, 9 )
-
--}
+{-| -}
scaleBy : Float -> Vector3d -> Vector3d
scaleBy scale vector =
let
@@ -707,18 +411,7 @@ scaleBy scale vector =
fromComponents ( x * scale, y * scale, z * scale )
-{-| Rotate a vector around a given axis by a given angle (in radians).
-
- vector =
- Vector3d.fromComponents ( 2, 0, 1 )
-
- Vector3d.rotateAround Axis3d.x (degrees 90) vector
- --> Vector3d.fromComponents ( 2, -1, 0 )
-
- Vector3d.rotateAround Axis3d.z (degrees 45) vector
- --> Vector3d.fromComponents ( 1.4142, 1.4142, 1 )
-
--}
+{-| -}
rotateAround : Axis3d -> Float -> Vector3d -> Vector3d
rotateAround (Types.Axis3d axis) angle =
let
@@ -809,18 +502,7 @@ rotateAround (Types.Axis3d axis) angle =
)
-{-| Mirror a vector across a plane.
-
- vector =
- Vector3d.fromComponents ( 1, 2, 3 )
-
- Vector3d.mirrorAcross Plane3d.xy vector
- --> Vector3d.fromComponents ( 1, 2, -3 )
-
- Vector3d.mirrorAcross Plane3d.yz vector
- --> Vector3d.fromComponents ( -1, 2, 3 )
-
--}
+{-| -}
mirrorAcross : Plane3d -> Vector3d -> Vector3d
mirrorAcross plane =
let
@@ -857,57 +539,19 @@ mirrorAcross plane =
)
-{-| Find the projection of a vector in a particular direction. Conceptually,
-this means splitting the original vector into a portion parallel to the given
-direction and a portion perpendicular to it, then returning the parallel
-portion.
-
- vector =
- Vector3d.fromComponents ( 1, 2, 3 )
-
- Vector3d.projectionIn Direction3d.x vector
- --> Vector3d.fromComponents ( 1, 0, 0 )
-
- Vector3d.projectionIn Direction3d.z vector
- --> Vector3d.fromComponents ( 0, 0, 3 )
-
--}
+{-| -}
projectionIn : Direction3d -> Vector3d -> Vector3d
projectionIn direction_ vector =
direction_ |> withLength (vector |> componentIn direction_)
-{-| Project a vector [orthographically](https://en.wikipedia.org/wiki/Orthographic_projection)
-onto a plane. Conceptually, this means splitting the original vector into a
-portion parallel to the plane (perpendicular to the plane's normal direction)
-and a portion perpendicular to it (parallel to its normal direction), then
-returning the parallel (in-plane) portion.
-
- vector =
- Vector3d.fromComponents ( 2, 1, 3 )
-
- Vector3d.projectOnto Plane3d.xy vector
- --> Vector3d.fromComponents ( 2, 1, 0 )
-
- Vector3d.projectOnto Plane3d.xz vector
- --> Vector3d.fromComponents ( 2, 0, 3 )
-
--}
+{-| -}
projectOnto : Plane3d -> Vector3d -> Vector3d
projectOnto plane vector =
difference vector (projectionIn (Plane3d.normalDirection plane) vector)
-{-| Take a vector defined in global coordinates, and return it expressed in
-local coordinates relative to a given reference frame.
-
- vector =
- Vector3d.fromComponents ( 2, 0, 3 )
-
- Vector3d.relativeTo rotatedFrame vector
- --> Vector3d.fromComponents ( 1.732, -1, 3 )
-
--}
+{-| -}
relativeTo : Frame3d -> Vector3d -> Vector3d
relativeTo frame vector =
fromComponents
@@ -917,16 +561,7 @@ relativeTo frame vector =
)
-{-| Take a vector defined in local coordinates relative to a given reference
-frame, and return that vector expressed in global coordinates.
-
- vector =
- Vector3d.fromComponents ( 2, 0, 3 )
-
- Vector3d.placeIn rotatedFrame vector
- --> Vector3d.fromComponents ( 1.732, 1, 3 )
-
--}
+{-| -}
placeIn : Frame3d -> Vector3d -> Vector3d
placeIn frame vector =
let
@@ -949,24 +584,7 @@ placeIn frame vector =
)
-{-| Project a vector into a given sketch plane. Conceptually, this finds the
-[orthographic projection](https://en.wikipedia.org/wiki/Orthographic_projection)
-of the vector onto the plane and then expresses the projected vector in 2D
-sketch coordinates.
-
- vector =
- Vector3d.fromComponents ( 2, 1, 3 )
-
- Vector3d.projectInto SketchPlane3d.xy vector
- --> Vector2d.fromComponents ( 2, 1 )
-
- Vector3d.projectInto SketchPlane3d.yz vector
- --> Vector2d.fromComponents ( 1, 3 )
-
- Vector3d.projectInto SketchPlane3d.zx vector
- --> Vector2d.fromComponents ( 3, 2 )
-
--}
+{-| -}
projectInto : SketchPlane3d -> Vector3d -> Vector2d
projectInto sketchPlane vector =
Vector2d.fromComponents