Approximate length of a cubic bezier curve
This C code gives the approximate length of a cubic Bezier curve. There are two data structures,/* A point in two-dimensional space. */ typedef struct { double x, y; } point; /* The control points (0 and 1) and end point (2) of a cubic Bezier curve. */ typedef struct { point pt[3]; } curve;This calculates the length by breaking the curve into
STEPS
straight-line segments, then adding the length
of each of these to get the final length.
/* Calculate parametric value of x or y given t and the four point coordinates of a cubic bezier curve. This is a separate function because we need it for both x and y values. */ double _bezier_point (double t, double start, double control_1, double control_2, double end) { /* Formula from Wikipedia article on Bezier curves. */ return start * (1.0 - t) * (1.0 - t) * (1.0 - t) + 3.0 * control_1 * (1.0 - t) * (1.0 - t) * t + 3.0 * control_2 * (1.0 - t) * t * t + end * t * t * t; } #define STEPS 10 /* Approximate length of the Bezier curve which starts at "start" and is defined by "c". According to Computing the Arc Length of Cubic Bezier Curves there is no closed form integral for it. */ double bezier_length (point start, curve * c) { double t; int i; int steps; point dot; point previous_dot; double length = 0.0; steps = STEPS; for (i = 0; i <= steps; i++) { t = (double) i / (double) steps; dot.x = _bezier_point (t, start.x, c->pt[0].x, c->pt[1].x, c->pt[2].x); dot.y = _bezier_point (t, start.y, c->pt[0].y, c->pt[1].y, c->pt[2].y); if (i > 0) { double x_diff = dot.x - previous_dot.x; double y_diff = dot.y - previous_dot.y; length += sqrt (x_diff * x_diff + y_diff * y_diff); } previous_dot = dot; } return length; }Ten steps is enough to get a fairly good approximation. Computing the Arc Length of Cubic Bezier Curves contains several other C implementations of curve length functions.
Web links
Copyright © Ben Bullock 2009-2024. All
rights reserved.
For comments, questions, and corrections, please email
Ben Bullock
(benkasminbullock@gmail.com).
/
Privacy /
Disclaimer