In calculus, we are taught that the slope of the tangent to a curve, y = f(x) at some point x=c is f'(c). What about a parameteric curve? The curve is parameterized on t, not on x. We do have derivative information, but the derivatives are with respect to the curve’s parameter.
Fortunately, the chain rule provides the necessary result; dy/dx = [dy/dt]/[dx/dt]. All Singularity parametric curves (including composite curves) return position and derivative at a parameter value. This information can be used to compute the slope of a tangent to a spline such as Catmull-Rom, as shown below.
If dx/dt is sufficiently small, the tangent slope approaches infinity and this should be tested and compensated for in application code. The demo from which the above screenshot was taken allows an arbitrary number of points to be defined in the drawing area. A Catmull-Rom spline is fit to those points. Move the slider to watch a 40px segment drawn tangent to the curve as the parameter varies from 0 to 1.
To compute the tangent segment, the slope of the spline at the specified parameter along with a small positive and negative perturbation in x is used to generate two points on the tangent in opposite directions. Unit vectors in each direction are created. Two points, each 20px along each unit vector, are generated to create the line segment.
The demo is contained in a single MXML file and may be obtained from the Downloads section in this blog. Or, you can download the .zip file here along with Singularity here. You need to have Singularity on your computer in order to build a Flex project from the supplied MXML file.
If we have a well-defined tangent to a curve at a point, not only can we orient sprites along the curve, we know the angle the tangent makes with horizontal. That information, combined with arc-length parameterization allows sprites to be distributed uniformly along the curve with orientation control. Stay tuned for a new demo in a few days illustrating these observations.
One thought on “Spline Tangents”
Comments are closed.