An EllipticalArc2d is a section of an Ellipse2d with a start and end point.
This module includes functionality for
The startAngle and sweptAngle values referred to below are not actually
proper angles but instead refer to values of the ellipse parameter.
However, in simple cases you don't need to worry about the difference - if
startAngle and sweptAngle are both multiples of 90 degrees, then you can
treat them as actual angles and everything will work out.
Construct an elliptical arc from its center point, X direction, X and Y
radii, start angle and swept angle. Any negative sign on xRadius or yRadius
will be ignored (the absolute values 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
}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.
https://opensolid.github.io/geometry/2.1.0/doc/interactive/EllipticalArc2d/fromEndpoints.html
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,
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.
Argument type used in fromEndpoints.
Flag used as argument to fromEndpoints.
Flag used as argument to fromEndpoints.
Flag used as argument to fromEndpoints.
Flag used as argument to fromEndpoints.
The start angle of an elliptical arc is the value of the ellipse parameter at the start point of the arc.
EllipticalArc2d.startAngle exampleArc
--> 0The swept angle of an elliptical arc is the difference between values of the ellipse parameter at the start and end points of the arc.
EllipticalArc2d.sweptAngle exampleArc
--> degrees 90Get the start point of an elliptical arc.
EllipticalArc2d.startPoint exampleArc
--> Point2d.fromCoordinates ( 2, 0 )Get the end point of an elliptical arc.
EllipticalArc2d.endPoint exampleArc
--> Point2d.fromCoordinates ( 0, 1 )All remaining properties of elliptical arcs are actually just properties of the underlying ellipse; check out the Ellipse2d module for details.
Get a point along an elliptical arc, based on a parameter that ranges from 0 to 1. A parameter value of 0 corresponds to the start point of the arc and a value of 1 corresponds to the end point.
EllipticalArc2d.pointOn exampleArc 0
--> Point2d.fromCoordinates ( 2, 0 )
EllipticalArc2d.pointOn exampleArc 0.5
--> Point2d.fromCoordinates ( 1.4142, 0.7071 )
EllipticalArc2d.pointOn exampleArc 1
--> Point2d.fromCoordinates ( 0, 1 )Get the deriative value at a point along an elliptical arc, based on a parameter that ranges from 0 to 1. A parameter value of 0 corresponds to the derivative at the start point of the arc and a value of 1 corresponds to the derivative at the end point.
EllipticalArc2d.derivative exampleArc 0
--> Vector2d.fromComponents ( 0, 1.5708 )
EllipticalArc2d.derivative exampleArc 0.5
--> Vector2d.fromComponents ( -2.2214, 1.1107 )
EllipticalArc2d.derivative exampleArc 1
--> Vector2d.fromComponents ( -3.1416, 0 )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
--> }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
--> }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
--> }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
--> }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 )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
--> }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
--> }An elliptical arc that has been parameterized by arc length.
Build an arc length parameterization of the given elliptical arc, within
a given tolerance. Generally speaking, all operations on the resulting
ArcLengthParameterized value will be accurate to within the given arc length
tolerance.
tolerance =
1.0e-4
parameterizedArc =
EllipticalArc2d.arcLengthParameterized
tolerance
exampleArcFind 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.4221Try 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 0.5
--> Point2d.fromCoordinates ( 1.4142, 0.7071 )If the given arc length is less than zero or greater than the arc length of the
arc, Nothing is returned.
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.tangentAlong parameterizedArc
(arcLength / 2)
--> Just (Direction2d.fromAngle (degrees 159.71))If the given arc length is less than zero or greater than the arc length of the
arc (or if the derivative of the arc happens to be exactly zero at the given arc
length), Nothing is returned.
Try to get the parameter value along an elliptical arc at a given arc
length. If the given arc length is less than zero or greater than the arc length
of the arc, returns Nothing.
EllipticalArc2d.arcLengthToParameterValue
parameterizedArc
(arcLength / 2)
--> Just 0.5947Get the arc length along an elliptical arc at a given parameter value. If
the given parameter value is less than zero or greater than one, returns
Nothing.
EllipticalArc2d.parameterValueToArcLength
parameterizedArc
0.5
--> Just 0.9657Low level functionality that you are unlikely to need to use directly.
An elliptical arc in 2D.