folkertdev / one-true-path-experiment / Curve

Construct curves from a set of points.

The problem of drawing a line through a set of points is actually quite tricky. Should the curve be smooth? Should the ends be connected? This module gives many options for drawing lines through points.

Supports all the curves defined by D3 Shape.

Linear

Draw a straight line connecting the data points. The closed variant repeats the final point to create a closed curve.

linear : List ( Basics.Float, Basics.Float ) -> SubPath

Draw straigt lines between the data points

linear

linearClosed : List ( Basics.Float, Basics.Float ) -> SubPath

Draw a straigt line between the data points, connecting the ends.

linear-closed

Bezier

Helpers for bezier curves. Quadratic bezier segments have a start and end point, and 1 control point. Cubic beziers have 2 control points. The smooth variants can use the previous control point to draw the next segment.

The first argument is the starting point, the second argument a list of extensions.

cubicBezier : ( Basics.Float, Basics.Float ) -> List ( ( Basics.Float, Basics.Float ), ( Basics.Float, Basics.Float ), ( Basics.Float, Basics.Float ) ) -> SubPath

Shorthand to draw a sequence of cubic bezier segments

smoothCubicBezier : ( Basics.Float, Basics.Float ) -> ( ( Basics.Float, Basics.Float ), ( Basics.Float, Basics.Float ), ( Basics.Float, Basics.Float ) ) -> List ( ( Basics.Float, Basics.Float ), ( Basics.Float, Basics.Float ) ) -> SubPath

Shorthand to draw a sequence of smooth cubic bezier segments

quadraticBezier : ( Basics.Float, Basics.Float ) -> List ( ( Basics.Float, Basics.Float ), ( Basics.Float, Basics.Float ) ) -> SubPath

Shorthand to draw a sequence of quadratic bezier segments

smoothQuadraticBezier : ( Basics.Float, Basics.Float ) -> ( ( Basics.Float, Basics.Float ), ( Basics.Float, Basics.Float ) ) -> List ( Basics.Float, Basics.Float ) -> SubPath

Shorthand to draw a sequence of smooth quadratic bezier segments

Step

Step goes some distance to the right, then to the y-coordinate of the next data point, and then draws to the next point.

The first argument determines where the step is.

step : Basics.Float -> List ( Basics.Float, Basics.Float ) -> SubPath

step

stepBefore : List ( Basics.Float, Basics.Float ) -> SubPath

step before

stepAfter : List ( Basics.Float, Basics.Float ) -> SubPath

step after

Catmull-Rom

Catmull-Rom is perfect for animation, because data points are hit exactly and the curve is smooth.

catmullRom : Basics.Float -> List ( Basics.Float, Basics.Float ) -> SubPath

catmull rom

catmullRomClosed : Basics.Float -> List ( Basics.Float, Basics.Float ) -> SubPath

catmull rom closed

catmullRomOpen : Basics.Float -> List ( Basics.Float, Basics.Float ) -> SubPath

catmull rom open

Monotone

The monotone curves can only be increasing (staying flat or becoming higher) or decreasing (staying flat or becoming lower) between any two adjacent points. It cannot first go down and then go up.

monotone curve illustration

Around 0.45, the cubic interpolation dives below the y-coordinate of the next point, whereas the monotone interpolation does not.

A nice consequence is that there are no weird bumps in the curve between the data points.

monotoneX : List ( Basics.Float, Basics.Float ) -> SubPath

monotone in x

monotoneY : List ( Basics.Float, Basics.Float ) -> SubPath

monotone in y

Natural

natural : List ( Basics.Float, Basics.Float ) -> SubPath

natural

Basis

basis : List ( Basics.Float, Basics.Float ) -> SubPath

Basis interpolation (also known as B-spline)

basis

basisClosed : List ( Basics.Float, Basics.Float ) -> SubPath

Closed Basis interpolation (also known as B-spline)

basis closed

basisOpen : List ( Basics.Float, Basics.Float ) -> SubPath

basis open

bundle : Basics.Float -> List ( Basics.Float, Basics.Float ) -> SubPath

bundle

Cardinal

cardinal : Basics.Float -> List ( Basics.Float, Basics.Float ) -> SubPath

cardinal

cardinalClosed : Basics.Float -> List ( Basics.Float, Basics.Float ) -> SubPath

cardinal closed

cardinalOpen : Basics.Float -> List ( Basics.Float, Basics.Float ) -> SubPath

cardinal open

Transformations

repeatFirstPoint : List a -> List a

Repeat the first element of a list

This is sometimes useful for curves that don't go through their first control point (catmullRom, cardinal). Repeating the first point makes the curve actually hit the first control point.

repeatFinalPoint : List a -> List a

Repeat the final element of a list

Similar to repeatFirstPoint, this can be used to make some curves hit their final control point.

radial : ( Basics.Float, Basics.Float ) -> List ( Basics.Float, Basics.Float ) -> SubPath

Interpret a 2D vector as a (angle, radius) pair. The angle is in radians. The first argument is the center.

radial

toPolarWithCenter : ( Basics.Float, Basics.Float ) -> List ( Basics.Float, Basics.Float ) -> List ( Basics.Float, Basics.Float )

Convert (angle, radius) pairs to (x, y) coordinates, relative to the given vector.

This function is used by radial and can be used to use radial with different interpolations, for instance.

radialNatural : ( Float, Float ) -> List ( Float, Float ) -> SubPath
radialNatural ( x, y ) =
    natural << toPolarWithCenter ( x, y )