opensolid/geometry/2.0.0

NOTE: this package is not compatible with Elm 0.19.1

OpenSolid.CubicSpline2d

CubicSpline2d

A CubicSpline2d is a cubic Bézier curve in 2D defined by four control points. This module contains functionality for

  • Evaluating points and derivatives along a spline
  • Scaling, rotating, translating or mirroring a spline
  • Converting a spline between local and global coordinates in different reference frames
type alias CubicSpline2d =
CubicSpline2d

Constructors

fromControlPoints : ( Point2d, Point2d, Point2d, Point2d ) -> CubicSpline2d

Construct a spline from its four control points:

exampleSpline =
    CubicSpline2d.fromControlPoints
        ( Point2d.fromCoordinates ( 1, 1 )
        , Point2d.fromCoordinates ( 3, 4 )
        , Point2d.fromCoordinates ( 5, 1 )
        , Point2d.fromCoordinates ( 7, 4 )
        )
hermite : ( Point2d, Vector2d ) -> ( Point2d, Vector2d ) -> CubicSpline2d

Construct a spline in Hermite form, from the position and derivative values at its start and end points, like so:

Hermite cubic spline

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.

Properties

controlPoints : CubicSpline2d -> ( Point2d, Point2d, Point2d, Point2d )

Get the control points of a spline as a tuple.

( p1, p2, p3, p4 ) =
    CubicSpline2d.controlPoints exampleSpline




--> p1 = Point2d.fromCoordinates ( 1, 1 )
--> p2 = Point2d.fromCoordinates ( 3, 4 )
--> p3 = Point2d.fromCoordinates ( 5, 1 )
--> p4 = Point2d.fromCoordinates ( 7, 4 )
startPoint : CubicSpline2d -> Point2d

Get the start point of a spline. This is equal to the spline's first control point.

CubicSpline2d.startPoint exampleSpline
--> Point2d.fromCoordinates ( 1, 1 )
endPoint : CubicSpline2d -> Point2d

Get the end point of a spline. This is equal to the spline's last control point.

CubicSpline2d.endPoint exampleSpline
--> Point2d.fromCoordinates ( 7, 4 )
startDerivative : CubicSpline2d -> Vector2d

Get the start derivative of a spline. This is equal to three times the vector from the spline's first control point to its second.

CubicSpline2d.startDerivative exampleSpline
--> Vector2d.fromComponents ( 6, 9 )
endDerivative : CubicSpline2d -> Vector2d

Get the end derivative of a spline. This is equal to three times the vector from the spline's third control point to its fourth.

CubicSpline2d.endDerivative exampleSpline
--> Vector2d.fromComponents ( 6, 9 )

Evaluation

pointOn : CubicSpline2d -> Float -> Point2d

Get a point along a spline, based on a parameter that ranges from 0 to 1. A parameter value of 0 corresponds to the start point of the spline and a value of 1 corresponds to the end point.

CubicSpline2d.pointOn exampleSpline 0
--> Point2d.fromCoordinates ( 1, 1 )


CubicSpline2d.pointOn exampleSpline 0.5
--> Point2d.fromCoordinates ( 4, 2.5 )


CubicSpline2d.pointOn exampleSpline 1
--> Point2d.fromCoordinates ( 7, 4 )
derivative : CubicSpline2d -> Float -> Vector2d

Get the deriative 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 derivative of the spline and a value of 1 corresponds to the end derivative.

CubicSpline2d.derivative exampleSpline 0
--> Vector2d.fromComponents ( 6, 9 )


CubicSpline2d.derivative exampleSpline 0.5
--> Vector2d.fromComponents ( 6, 0 )


CubicSpline2d.derivative exampleSpline 1
--> Vector2d.fromComponents ( 6, 9 )
evaluate : CubicSpline2d -> Float -> ( Point2d, Vector2d )

Evaluate a spline at a given parameter value, returning the point on the spline at that parameter value and the derivative with respect to that parameter value;

CubicSpline2d.evaluate spline t

is equivalent to

( CubicSpline2d.pointOn spline t
, CubicSpline2d.derivative spline t
)

but is more efficient.

Transformations

reverse : CubicSpline2d -> CubicSpline2d

Reverse a spline so that the start point becomes the end point, and vice versa.

CubicSpline2d.reverse exampleSpline
--> CubicSpline2d.fromControlPoints
-->     ( Point2d.fromCoordinates ( 7, 4 )
-->     , Point2d.fromCoordinates ( 5, 1 )
-->     , Point2d.fromCoordinates ( 3, 4 )
-->     , Point2d.fromCoordinates ( 1, 1 )
-->     )
scaleAbout : Point2d -> Float -> CubicSpline2d -> CubicSpline2d

Scale a spline about the given center point by the given scale.

CubicSpline2d.scaleAbout Point2d.origin 2 exampleSpline
--> CubicSpline2d.fromControlPoints
-->     ( Point2d.fromCoordinates ( 2, 2 )
-->     , Point2d.fromCoordinates ( 6, 8 )
-->     , Point2d.fromCoordinates ( 10, 2 )
-->     , Point2d.fromCoordinates ( 14, 8 )
-->     )
rotateAround : Point2d -> Float -> CubicSpline2d -> CubicSpline2d

Rotate a spline counterclockwise around a given center point by a given angle (in radians).

exampleSpline
    |> CubicSpline2d.rotateAround Point2d.origin
        (degrees 90)
--> CubicSpline2d.fromControlPoints
-->     ( Point2d.fromCoordinates ( -1, 1 )
-->     , Point2d.fromCoordinates ( -4, 3 )
-->     , Point2d.fromCoordinates ( -1, 5 )
-->     , Point2d.fromCoordinates ( -4, 7 )
-->     )
translateBy : Vector2d -> CubicSpline2d -> CubicSpline2d

Translate a spline by a given displacement.

displacement =
    Vector2d.fromComponents ( 2, 3 )


CubicSpline2d.translateBy displacement exampleSpline
--> CubicSpline2d.fromControlPoints
-->     ( Point2d.fromCoordinates ( 3, 4 )
-->     , Point2d.fromCoordinates ( 5, 7 )
-->     , Point2d.fromCoordinates ( 7, 4 )
-->     , Point2d.fromCoordinates ( 9, 7 )
-->     )
mirrorAcross : Axis2d -> CubicSpline2d -> CubicSpline2d

Mirror a spline across an axis.

CubicSpline2d.mirrorAcross Axis2d.x exampleSpline
--> CubicSpline2d.fromControlPoints
-->     ( Point2d.fromCoordinates ( 1, -1 )
-->     , Point2d.fromCoordinates ( 3, -4 )
-->     , Point2d.fromCoordinates ( 5, -1 )
-->     , Point2d.fromCoordinates ( 7, -4 )
-->     )

Coordinate conversions

relativeTo : Frame2d -> CubicSpline2d -> CubicSpline2d

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.fromControlPoints
-->     ( Point2d.fromCoordinates ( 0, -1 )
-->     , Point2d.fromCoordinates ( 2, 2 )
-->     , Point2d.fromCoordinates ( 4, -1 )
-->     , Point2d.fromCoordinates ( 6, 2 )
-->     )
placeIn : Frame2d -> CubicSpline2d -> CubicSpline2d

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.fromControlPoints
-->     ( Point2d.fromCoordinates ( 2, 3 )
-->     , Point2d.fromCoordinates ( 4, 6 )
-->     , Point2d.fromCoordinates ( 6, 3 )
-->     , Point2d.fromCoordinates ( 8, 6 )
-->     )

Subdivision

bisect : CubicSpline2d -> ( CubicSpline2d, CubicSpline2d )

Split a spline into two roughly equal halves. Equivalent to splitAt 0.5.

CubicSpline2d.bisect exampleSpline
--> ( CubicSpline2d.fromControlPoints
-->     ( Point2d.fromCoordinates ( 1, 1 )
-->     , Point2d.fromCoordinates ( 2, 2.5 )
-->     , Point2d.fromCoordinates ( 3, 2.5 )
-->     , Point2d.fromCoordinates ( 4, 2.5 )
-->     )
--> , CubicSpline2d.fromControlPoints
-->     ( Point2d.fromCoordinates ( 4, 2.5 )
-->     , Point2d.fromCoordinates ( 5, 2.5 )
-->     , Point2d.fromCoordinates ( 6, 2.5 )
-->     , Point2d.fromCoordinates ( 7, 4 )
-->     )
--> )
splitAt : Float -> CubicSpline2d -> ( CubicSpline2d, CubicSpline2d )

Split a spline at a particular parameter value (in the range 0 to 1), resulting in two smaller splines.

CubicSpline2d.splitAt 0.75 exampleSpline
--> ( CubicSpline2d.fromControlPoints
-->     ( Point2d.fromCoordinates ( 1, 1 )
-->     , Point2d.fromCoordinates ( 2.5, 3.25 )
-->     , Point2d.fromCoordinates ( 4, 2.125 )
-->     , Point2d.fromCoordinates ( 5.5, 2.6875 )
-->     )
--> , CubicSpline2d.fromControlPoints
-->     ( Point2d.fromCoordinates ( 5.5, 2.6875 )
-->     , Point2d.fromCoordinates ( 6, 2.875 )
-->     , Point2d.fromCoordinates ( 6.5, 3.25 )
-->     , Point2d.fromCoordinates ( 7, 4 )
-->     )
--> )