Compose rational bezier curve - curve

i need compose rational bezier curve with different weight
Curves
At the moment I have Curve1
a,b,c,d,e,f,g - controll points
q1,q2,q3,q4 - controll mid point (q1= b+c/2)
q3 e q4 - weighted rational curve
nice, but if two control point are close, it look like Curve2
they form two lines. But I want to have Curve3
all control points can change the weight
how can i get the curve 3?

This looks like a rational quadratic Bezier curve. To achieve the shape as Curve 3, you can
add a control point a1 which is where you want the smooth join to start (it should lie on line(ab)).
move control point c to where you want the smooth join to end (as indicated by b1 as shown in the following picture).

Related

How do I calculate pairs of Bezier S-curves such that the space between them has constant thickness?

Using SVG and cubic beziers, I'm attempting to generate the outline of S-curve shapes of various thicknesses, widths and heights, such as these:
I'm stuck on figuring out where the Bezier handle for each of the four corner nodes should be positioned in order to give the curve formed by their in-between area a constant thickness (or at least approximately).
I can see that the horizontal distance between the inner and outer handle at each end is dependent on the thickness of the curve and the overall curve width and height, but I'm stumped trying to get something that links them all together.
Is there a formula that would give me the horizontal position for each of the handles?
(I'm using d3js, so if there's a plugin or function I've missed that would help with this, that'd be even better).
I recommend the Tiller-Hanson algorithm used in FreeType's ftstroke module. It is normally used for converting a zero-width line into a stroke with some finite width; you can use the way it creates one of the two envelope lines (one on either side of the original line) to get your parallel curve. It handles any line made from straight segments and quadratic and cubic Bézier splines.
For more information see my answer to this question: How to get the outline of a stroke?.
Unfortunately, unless your curve has a uniform curvature, you can't get a fixed distance offset curve simply by linear scaling the original curve.
In order to get an offset curve for a Bezier, you have to do a bit of calculus to figure out how to split up the curve into "safe" segments, which can be offset by scaling, and then scale each piece.
More details over on http://pomax.github.io/bezierinfo/#offsetting, but basically what you want is something that usually you have someone else implement for you because it's a chore to get right.
You can actually offset the control polygon of one cubic Bezier curve to generate the control polygon for the "offset" curve, which will still be a cubic Bezier curve.
The following picture shall make it clear about what does "offset control polygon" mean. Given the cubic Bezier curve defined by P0, P1, P2 and P3, we can offset the 3 infinite lines L01 (defined by P0 and P1), L12 (defined by P1 and P2) and L23 (defined by P2 and P3). The resulting lines are denoted as L01*, L12* and L23*. The intersection points of L01* and L12* will be Q1 and that between L12* and L23* will be Q2. Q0 and Q3 will be the direct projected point of P0 and P3 onto L01* and L23*. The offset curve will be the cubic Bezier curve defined by Q0, Q1, Q2 and Q3.
Of course, the "offset" curve created in this way is not the exact offset but just an approximation. But as long as the offset distance is not too big and you are not too picky about the accuracy, the result is generally good enough. There are two advantages of this approach (besides its simplicity):
the approximate offset curve will honor the true offset curve's tangent direction at the start and end of the curve.
if you offset the offset curve in the opposite direction by the same distance, you will get back the original cubic Bezier curve.

How can I simulate a Bezier curve out of an image?

If I have a set of points from a black-white image I scanned.
It looks like a curve and I want to simulate a smooth curve using cubic Bezier curve from those points.
How can I figure out the start point, 2 control points and the end point?
From the image, there are several cubic Bezier curves that can be simulated but I don't know how to figure out the control points.
I have found the solution for my problems and I want to share it.
First, I write a python program to trace the curve and tell me all x,y of the points on the line.
Now, I have one curve.
I then create a line from start to end point and compare the distance between the perpendicular points on those 2 lines. If the distance is not low enough I will move the control point up, down, left, right and find which direction has the least distance. Do this multiple time and I will get a curve that is similar to the curve I have.

How to connect two fitted B-spline curve?

I use B-spline curve fitting to obtain one smooth curve. If I obtain two smooth B-spline , how can I connect then smoothly. For example, I have 59 points((x0,y0,z0),...,(x58, y58, z58)) and I have two fitted B spline. One B-spline is for the first 30 points, another is for the next 30 points and the two point set share one common point((x29,y29,z29)). The point (x29,y29,z29) will be modified twice due to curve fitting and will have two new positions. If I just connect the two new positions, the final curve will not be smooth at the point (x29,y29,z29). Currently I perform curve fitting for all data together but that will modify the smooth curve for the first 30 points entirely. I hope to only modify the connecting part of the first smooth curve. I know I need to impose derivatives need to be equal at the joint. I don't know how to do that.
It looks like you are doing LS fitting with B-spline curves or something similar and in general the B-spline obtained this way will not pass any of the data points. This is why the two B-splines do not meet at the common point.
To solve this problem, you can enhance your LS fitting function to take constraints as part of the input. In your cases, these constraints are linear and therefore your problem will still be linear. Once this step is done, you can pre-calculate the slope at the common point and constrain both B-spline fitting to the common point and common slope. This way the two B-splines obtained will at least be G1 continuous at the common point.
Having said this, to implement a constrained LS fitting is not a trivial task, which cannot be easily elaborated here either. So, you will have to do some "googling" yourself. An alternative solution will be to "tweak" your two B-splines to make them connected in a G1 manner. But doing so will certainly increase the fitting error as the sense of least squared error is destroyed. By "tweaking", I meant to change the B-spline's control points locally. In the following I will give more details.
Supposed you have two B-splines C1(t) and C2(t) and the last two control points of C1(t) are P(n-2) and P(n-1) and the first two control points of C2(t) are Q(0) and Q(1). P(n-1) and Q(0) are supposed to be close to the common point (x29, y29, z29) of the two data set. Tweaking the B-spline curves simply means changing the location of P(n-2), P(n-1), Q(0) and Q(1) so that these two B-spline curves will meet in a G1 manner. To do this,
1) we first make them G0 by moving both P(n-1) and Q(0) to the same location, which can be (x29, y29, z29) or simply the midpoint between P(n-1) and Q(0). Let's denote this new location as R.
2) Now, check if P(n-2), R and Q(1) are collinear. If they happens to be collinear, then the two B-spline curves will be G1 as well and you are done. If they are not collinear, find the best approximating line passing thru R from P(n-2) and Q(1), then project P(n-2) and Q(1) onto this line and use the projected points as the new location of P(n-2) and Q(1).
After these two steps, these two B-spline curves should be connected in G1 manner. But the error to the original data points around the common joint will become bigger.

Reverse engineering a bezier curve

Given a few sample points on a bézier curve, is it possible to work out the set of possible curves these points may lie on?
In my specific application there is a limited set of endpoints the curve may have, so I want to generate the set of possible curves, enumerate all of them and pick out all the ones which may end on a valid end point.
Some people have asked for more detail.
I have a set of points which I know are on a quadratic bezier curve, I want to calculate the formula of the curve and be able to extrapolate new points on the curve.
Bezier curves will always go through starting and ending control points.
If the degree of the curve is equal to the number of sample points then there will be only one curve that will pass through all your points (in a normal case, where all points are different and they don't lie on a bezier curve of a lesser degree).
If the degree of a curve is less then the number of the sample points then, in general case, you will not be able to make the curve go through all the points (in a normal case).
If the degree of a curve is higher then the number of the sample points then, in general case, you will be able to draw infinite number of curves.
In the wiki article you will find references to control points only, but still I believe that I remember the above properties correctly and that they hold for the points on the curves as well.
I think you need to redefine your question and exactly define what type of curves (and of which degree) do you need. Also as Georg pointed out you might be looking for paths - a combination of curves.
EDIT:
First a correction - curve is defined with degree plus one number of control points points (quadratic need three). Control points are not the same as points on the curve - and for three points on the curve and quadratic curve you could have infinite number of solutions (see this for quadratic curve and four points)
As for the solution (but still under assumption that you are looking at a single curve):
For an equation for single quadratic curve you have
B(t) = (1-t)^2*P0 + 2*(1-t)*t*P1 + t^2*P2
Capital letters above are vectors, and P0 corresponds to starting control point (first point), P2 corresponds to ending control point (last point), so you still need to find P1. The variable t is scalar that ranges from 0 to 1.
If working with 2D curves the above vector equation gives two scalar equations for each point on the curve.
Still there is t as an unknown, so you should take 2 more points (4 in total) which will give you 4 unknowns (t for first point, t for second point, x and y of the P1, middle control point) and 4 equation to solve (2 from each sample point).
Solve that with your favourite numerical method and you will get the original curve on which the points came from.
If you still think that you can get more curves and that you will have to choose something then you are not working with bezier curves, but with bezier splines (in a sense of multiple curves joined together). Still the same principle applies and if you work out a way to solve a single curve from the above equations (and if you have enough points) then you can divide the problem into n-segments of actual bezier curves and solve each as outlined above.
If it turns out that you don't have enough points then look at the linked article again - you are probably looking for the smoothest curve and there are some suggestions in the article on how to get there as looking for the exact solution (shortest curve/smoothest curve) seems to be rather complex.

Algorithm for inserting points in a piecewise-cubic Bézier path

I'm looking for an algorithm to insert a new control point on a Bézier curve, without deforming.
Does anybody know a library or reference for Bézier algorithms (insertion, optimize, de Casteljau ...)?
This is called the "knot insertion problem". For Bézier curves, the de Casteljau algorithm will give you the right answer. Here is the simple algorithm for a degree 3 Bézier.
Say you want to insert a knot at a fraction t of the parameter space inside the Bézier curve defined by P0, P1, P2, P3. Here's what you do:
P0_1 = (1-t)*P0 + t*P1
P1_2 = (1-t)*P1 + t*P2
P2_3 = (1-t)*P2 + t*P3
P01_12 = (1-t)*P0_1 + t*P1_2
P12_23 = (1-t)*P1_2 + t*P2_3
P0112_1223 = (1-t)*P01_12 + t*P12_23
Then your first Bézier will be defined by: P_0, P0_1, P01_12, P0112_1223; your second Bézier is defined by: P0112_1223, P12_23, P2_3, P3.
The geometrical interpretation is simple: you split each segment of the Bézier polygon at fraction t, then connect these split points in a new polygon and iterate. When you're left with 1 point, this point lies on the curve and the previous/next split points form the previous/next Bézier polygon. The same algorithm also works for higher degree Bézier curves.
Now it can get trickier if you want to insert the control point not at a specific value of t but at a specific location in space. Personally, what I would do here is simply a binary search for a value of t that falls close to the desired split point... But if performance is critical, you can probably find a faster analytic solution.
You could also take the mathematical approach.
A qubic Bézier curve with control points can be written as:
Its derivative w.r.t. is
To limit the curve from to , you get new control points :
Proof
Substituting
We get
The first and last points of the sub-curve are the first and last new control points
And the tangent at those points is
So
Adding this for completeness.
An open-source implementation of many Bézier path operations can be found inside GIMP source code, in gimpbezierstroke.c. For reference on inserting a new anchor, search for gimp_bezier_stroke_anchor_insert.

Resources