How do bezier handles work? - c++

On Wikipedia I found information about bezier curves and made a function to generate the inbetween points for a bezier polygon. I noticed that Expression Design uses bezier handles. This allows a circle to be made with 4 points each with a bezier handle.
I'm just not sure mathematically how this works in relation with the formula for bezier point at time T. How do these handle vectors work to modify the shape? Basically what's there relation to the bezier formula?
Thanks

Basically, the 4 points used in the cubic bezier formula are the 2 points the curve is between, plus the two points of the handles on that "side" of the first two points (1 handle from each of the first points). If there are double handles on each point, the handles on the "opposite" side of the points from the curve currently being calculated are ignored (they're used for generating the curve that comes out of the opposite side).
The actual generation method used for cubic bezier curves is outlined on the Wikipedia page you linked in your question.

The 4 points of a Bezier segment are the two endpoints of the segment and two handles, one per endpoint. The handles determine the initial direction of the line as it leaves the endpoint. The distance from the handle to the endpoint determines the amount of "pull" that the handle exerts on the path.
Often you will find multiple Beziers connected end to end, with the endpoint of one being shared as the starting point of the next. This guarantees an unbroken curve. If the handles on either side of a point are directly across from each other, the angle at the joint will match up; if the handles are also the same distance from the point, the angle will be completely smooth and there will not be a visible discontinuity at the point.
An interesting property of Bezier segments is that the curve will fit entirely within the parallelogram defined by the 4 points.
What I have been describing is the most common form of Bezier, the cubic. There is also a quadratic which only has a single handle between the two endpoints; the most common application is TrueType fonts.

Related

Deconstruct Bezier Curve into Line Segments with Equally Spaced Slopes

I'm currently working on a program that takes a scale SVG file of a race track and uses the data to approximate the track as an array of points. Ideally, the absolute value of the slopes between any two consecutive points would be identical, as this would allow me to approximate the angle, arc length and radius to a known accuracy for use in calculating the maximum velocity around the curve.
The SVG uses a Bezier approximation with 2 control points. I have a function that takes a start point, 2 control points and an end point as well as the parametric variable t. I found the code for this here:
Drawing Bezier curves using De Casteljau Algorithm in C++ , OpenGL
The result I'd like is that straights would consist of very few line segments (slope changes very little), while sharp turns would consist of many line segments (slope changes sharply). This would keep a constant accuracy in the calculations.
Using a constant step for t doesn't provide a constant slope between two points, which is a huge issue for the calculations. Is there any way to find the correct t value knowing the desired slope of the resulting line segment?
After much searching and refining of terms, I've found a site that explains in depth the answer to my problem. Turns out that my problem is the same faced by rendering engines for drawing Bezier curves, and the Anti-Grain Rendering Engine has a wonderful tutorial on subdividing Bezier curves to approximate all kinds of twists and turns.
https://web.archive.org/web/20180307160123/http://antigrain.com/research/adaptive_bezier/index.html

Create smooth line to join N points in 3 dimensions

I have N points in 3-dimensional space. I need to join them using a line. However, if I do that using a simple line, it is not smooth and looks ugly.
My current approach is to use a Bezier curve, using the DeCasteljau algorithm for 4 points, and running that for each group of 4 points in my data set. However, the problem with this is that since I run it on say points 1-4, 5-8, 9-12, etc., separately, the line is not smooth between 4-5, 8-9, etc.
I also looked for other approaches; specifically I found this article about Catmull-Rom splines, which seem even better suited for my purpose, because the curve passes through all control points, unlike the Bezier curve. So I almost started implementing that, but then, I saw on that site that the formula works "assuming uniform spacing of control points". That is not the case for my problem.
So, my question is, what approach should I use -- Bezier, Catmull-Rom, or something completely different? If Bezier, then how to fix the non-smoothness between 4-5, 8-9, etc.? If Catmull-Rom, why won't the formula work if points are not evenly spaced, and what do I need instead?
EDIT: I am now pretty sure I want the Catmull-Rom spline, as it passes every control point which is an advantage for my application. Therefore, the main question I would like answered is why won't the formula on the link I provided work for non-uniformly spaced control points?
Thanks.
A couple of solutions:
Use a B-spline. This is a generalization of Bezier curves (a Bezier curve is a B-spline with no internal knot points.)
Use a cubic spline. Cubic splines are particularly easy to calculate. A cubic spline is continuous in the zero, first, and second derivatives across the control points. The third derivative, the cubic term, suffers a discontinuity at the control points, but it is very hard to see those discontinuities.
One key difference between a B-spline and a cubic spline is that the cubic spline will pass through all of the control points, while a B-spline does not. One way to think about it: Those internal control points are just suggestions for a B-spline but are mandatory for a cubic spline.
A meaningful line (although not the simplest to evaluate) can be found via Gaussian Processes. You set (or infer) the lengthscale over which you wish the line to vary (i.e. the smoothness of the line) and then the GP line is the most probable line through the data given the lengthscale. You can add noise to the model if you don't mind the line not passing through the data points.
Its a nice interpolation method because you can also obtain the standard deviation of your line. The line becomes more uncertain when you don't have much data in the vacinity.
You can read about them in chapter 45 of David MacKay's Information Theory, Inference, and Learning Algorithms - which you can download from the author's website here.
one solution is the following page in wikipedia: http://en.wikipedia.org/wiki/Bézier_curve, check the generalized approach for N control points.

Draw a bezier curve(s) with a set of points from a vector

I was wondering what would be the best and less complicated way of drawing a bezier curve in c++ with a set of points (roughly 100+ points) that are stored inside a vector
From my understanding:
-Bezier curves consist of 4 control points, the points in the middle dictate the direction/tangent of the curve
Would one possible method be to breakdown the points into different segments and from each segment determine the control points and tangents?
It is called a cubic spline and if you search you might find some C++ code for it. I used the free Fortran code from Numerical Recipes Online and ported it to C# with no problems.
Would one possible method be to
breakdown the points into different
segments and from each segment
determine the control points and
tangents?
Yes, basically one connects the line segments end-to-end such that the slope approaching the end of the line segment is equal on both sides of the connection point. This is called a cubic spline. You can find algorithms for this here.

how to interpret a freetype glyph outline when the first point on the contour is off curve

I'm actually working on a renderer that converts freetype glyphs into polylines to control a laser marking system. The problem I have is that I don't know how to handle correctly a contour beginning with an off curve point (99.9% begin with on curve points!). I've searched quite a while now for informations but I couldn't find anything useful.
Thanks for your help
FreeType uses three types of points: on-curve, quadratic control points (also known as 'conic') and cubic control points. The quadratic control points are grouped with on-curve points on either side of them to form the three points needed to define a quadratic Bézier spline. The cubic control points must occur in pairs, and are grouped with on-curve points on either side to make up the four points needed for a cubic Bézier spline.
However, there is a short-hand notation for quadratic points only. Where quadratic points occur next to each other, an on-curve control point is interpolated between them. And there is another convention, that if a closed path starts with a quadratic point, the last point of the path is examined, and if it is quadratic, an on-curve point is interpolated between them, and the path is taken to start with that on-curve point; if the last point is not a quadratic control point, it is itself used for the start point.
If you want to see exactly how this is done, please look at the FreeType source code. The function FT_Outline_Decompose traverses a path and converts it into a series of lines and curves of both types. It's in this file:
http://git.savannah.gnu.org/cgit/freetype/freetype2.git/tree/src/base/ftoutln.c
The part of especial interest starts with this comment (note again that 'conic' means the same as 'quadratic' in this context):
/* first point is conic control. Yes, this happens. */

Connecting Catmull-Rom splines together and calculating its length?

I'm trying to create a class which takes in any number of points (position and control) and creates a catmull-rom spline based on the information given.
What I'm doing - and I'm really unsure if this is the right way to do it - is storing each individual point in a class like so:
class Point
{
public:
Vector3 position;
Vector3 control;
}
Where obviously position is the position of the point and control is the control point.
My issue is connecting up the splines - obviously given the above class holding a point in the spline array indicates that any given position can only have one control point. So when having three or more points in a catmull rom spline the various individual catmull-rom splines which are being connected share one position and one control with another such spline.
Now with position being the same is required - since I want to create splines which are continuous between themselves. However I really wonder, should the control points also be the same between the two splines? With a bit of fiddling of the control points I can make it appear to be transitioning smoothly from one spline to another however I must emphasize that I'm not sure if the way they are transitioning is consistent with how catmull-rom splines form their shape. I'd much rather do it correctly than sit on my hands and rationalize that it's good enough.
Obviously the second part of my question is self explanatory: Given two control and position points how do I calculate the length of a catmull-rom spline?
To define the spline between two control points, the Catmull-Rom spline needs the control points and the tangent vector at each control point. However, the tangent vector at internal (i.e. non-endpoint) control points is defined by the control points on either side of it:
T(Pn) = (Pn+1 - Pn-1) / 2. For closed curves, the spline is completely defined by the set of control points. For non-closed curves, you need to also supply the tangent vector at the first and last control point. This is commonly done: T(P0) = P1 - P0 and T(Pn) = Pn - Pn-1.
Thus, for closed curves, your data structure is just a list of control points. For general splines, it's a list of points plus the first and last normal vector.
If you want to have a cardinal spline, then you can add a weighting factor to the tangent vector calculation as in the Wikipedia article.
To calculate the length of such a spline, one approach would be to approximate it by evaluating the spline at many points and then calculating the linear distance between each neighboring pair of points.
With regards to measuring the lengths, you can do this with calculus since its a polynomial spline. You need to do integrate the distance function across the line. Its described quite well on Wikipedia...