In the previous post I wrote a couple of equations displaying how to calculate acceleration on a planar curve (equation #1) and curvature radius for Bezier curve (equation #2). In this post I’ll also show how to get the first and the second derivatives of Bezier polynomial.
Let’s implement it using C#.Net.
First of all let’s see implementation of Bezier polynomial. The following method gets 2D coordinate of curve point described by parameter t.
/// <summary> /// Gets coordinate of Bezier curve point by parameter 't'. /// </summary> /// <param name="t">Parameter [0..1]</param> /// <returns>Point of a curve.</returns> public PointDouble2D GetPointByParameter(double t) { checkParameterT(t); double cx = 3 * (p[1].X - p[0].X); double bx = 3 * (p[2].X - p[1].X) - cx; double ax = p[3].X - p[0].X - cx - bx; double cy = 3 * (p[1].Y - p[0].Y); double by = 3 * (p[2].Y - p[1].Y) - cy; double ay = p[3].Y - p[0].Y - cy - by; double tSquared = t * t; double tCubed = tSquared * t; double resultX = (ax * tCubed) + (bx * tSquared) + (cx * t) + p[0].X; double resultY = (ay * tCubed) + (by * tSquared) + (cy * t) + p[0].Y; return new PointDouble2D(resultX, resultY); }
The CheckParameter() method is used to check whether value of t is in range from 0 to 1. Array p[i] is private field storing four Bezier control points.
As I previously mentioned, Bezier curve is polynomial, so its derivatives can be easily calculated. Let’s see how the 1st and the 2nd derivatives of Bezier are implemented using C#:
/// <summary> /// Gets 1st derivate of a Bezier curve in a point specified by parameter t. /// </summary> /// <param name="t">Parameter [0..1].</param> /// <returns>Vector of 1st Bezier curve derivate in a specified point.</returns> public VectorDouble2D GetDerivate(double t) { checkParameterT(t); double tSquared = t * t; double s0 = -3 + 6 * t - 3 * tSquared; double s1 = 3 - 12 * t + 9 * tSquared; double s2 = 6 * t - 9 * tSquared; double s3 = 3 * tSquared; double resultX = p[0].X * s0 + p[1].X * s1 + p[2].X * s2 + p[3].X * s3; double resultY = p[0].Y * s0 + p[1].Y * s1 + p[2].Y * s2 + p[3].Y * s3; return new VectorDouble2D(resultX, resultY); } /// <summary> /// Gets 2nd derivate of a Bezier curve in a point specified by parameter t. /// </summary> /// <param name="t">Parameter [0..1].</param> /// <returns>Vector of 2nd Bezier curve derivate in a specified point.</returns> public VectorDouble2D GetSecondDerivate(double t) { checkParameterT(t); double s0 = 6 - 6 * t; double s1 = -12 + 18 * t; double s2 = 6 - 18 * t; double s3 = 6 * t; double resultX = p[0].X * s0 + p[1].X * s1 + p[2].X * s2 + p[3].X * s3; double resultY = p[0].Y * s0 + p[1].Y * s1 + p[2].Y * s2 + p[3].Y * s3; return new VectorDouble2D(resultX, resultY); }
As one can see, the equations should be very simple. And finally, let’s write a method for getting curvature radius:
/// <summary> /// Gets curvature radius of a Bezier curve in specified point. /// </summary> /// <param name="t">Parameter [0..1].</param> /// <returns>Curvature radius.</returns> /// <remarks>Curvature = 1/CurvatureRadius.</remarks> public double GetCurvatureRadius(double t) { checkParameterT(t); VectorDouble2D d1 = GetDerivate(t); VectorDouble2D d2 = GetSecondDerivate(t); double r1 = System.Math.Sqrt(System.Math.Pow(d1.X * d1.X + d1.Y * d1.Y, 3)); double r2 = System.Math.Abs(d1.X * d2.Y - d2.X * d1.Y); return r1 / r2; }
This method follows the equation described in the previous post.
Now let’s use the methods above to visualize acceleration (I’ll assume that speed is constant):

Acceleration on Bezier curve
As one can see the largest acceleration is on segments where radius R is minimal. On the ends of the curve, where radius of the osculating circle is infinite, there is no centripetal acceleration.

Curvature radius