Hi everybody I need your help. My question is: what does "t" represent in De Casteljau's algorithm?
We have the following formula to calculate the point Q:
Q=(1−t)P1+tP2, t∈[0,1]
But what does t mean here and why it is between 0 and 1?
The t is an interpolation value.
For many computations, it is beneficial to parameterize the curve based on unit length. This basically means that the t describes a position on the curve, with t=0 being the start of the curve, and t=1 being the end of the curve.
Consider the simplest case of interpolating between two points: Changing the value of t between 0 and 1 can be imagined as "walking along the line between the two points". For such a simple interpolation, you can say that the "curve" (i.e. the line between the points) is described by the equation
P(t) = (1-t)*P0 + t*P1
For example, for t=0.25, you compute 0.75 * P0 + 0.25 * P1, which yields a point in the middle of the left half of the line between P0 and P1.
For the case of De Casteljau's algorithm, the situation is a bit more involved: Depending on the degree of the curve, you don't interpolate between fixed points P0 and P1, but between multiple points whose positions in turn depend on the variable t. This is usually computed recursively. But still, the variable t is a value between 0 and 1 that describes the position on the curve.
Q = (1 − t) P1 + t P2, t ∈ [0, 1] is a parametrization of the line segment from P1 to P2, and t is its parameter. As t goes from 0 to 1, Q traverses the line segment from P1 to P2.
Note that that is valid for any P1 and P2 such that you can compute a linear combination of them. It's not necessary that P1 and P2 be points in R^n -- they could be matrices, for instance, or functions.
Related
Let's say I have a Bezier curve with two fixed endpoints, one at x(0), y(1) and one at x(1), y(0) (bottom left corner and upper right corner)
Now let's say I have two control points, which can be at any locations between x(0), x(1), y(0), and y(1). For this question, I'll just say that control point #1 is at x(0.1) y(0.6) and control point #2 is at x(0.9) and at y(0.4). (This assumes a "from upper left" coordinate system)
Here's a small illustration of our curve:
Now let's say I'm given a y position of 0.7. What would the math look like to figure out what the corresponding x position is to the point at y(0.7)? How would I do this?
Sorry if this question doesn't belong here, but I figured this is a common problem faced in coding and that it's likely that many of you have the answer I'm looking for.
You have cubic equation for functions X(t) and Y(t) where t is curve parameter (range 0..1 for points on curve). In Bernstein polynomial basis (usual form for curve definition):
X(t) = P0.X*(1-t)^3+3*P1.X*(1-t)^2*t+3*P2.X*(1-t)*t^2+P3.X*t^3
Y(t) = P0.Y*(1-t)^3+3*P1.Y*(1-t)^2*t+3*P2.Y*(1-t)*t^2+P3.Y*t^3
Having Y value, we can find corresponding t parameters - note there might be from 0 to 3 possible roots in range 0..1. Representation of Y-component in power basis:
Y(t) = P0.Y*(1-t)^3+3*P1.Y*(1-t)^2*t+3*P2.Y*(1-t)*t^2+P3.Y*t^3 =
t^3*(P3Y-3P2Y+3P1Y-P0Y) + t^2*(3P2Y-6P1Y+3P0Y) + t^2*(3P1Y-3P0Y) + (P0Y) =
t^3*a + t^2*b + t^2*c + d' = y_position
and finally cubic equation is:
t^3*a + t^2*b + t^2*c + d = 0
where
a = P3.Y-3*P2.Y+3*P1.Y-P0.Y
b = 3*P2.Y-6*P1.Y+3*P0.Y
c = 3*P1.Y-3*P0.Y
d = P0.Y - y_position
Solve cubic equation to calculate t (perhaps some values for wavy curves)
Then for given t calculate corresponding X value:
X(t) = P0.X*(1-t)^3+3*P1.X*(1-t)^2*t+3*P2.X*(1-t)*t^2+P3.X*t^3
This is more of a general Maths question (might be silly even). But in high school we learn to identify the roots of an equation via it's plot right.
For example, for the equation
y = x^2 - 1
The blue line would show us the roots. This is when the blue line crosses x, so +- 1.
Now, if we said that the equation had a real and an imaginary part, so that it is
y = x^2 - 1 + (x^2 - 0.5)i
as given in the Mathematica screenshot, then we have a real part which crosses zero, and an imaginary part which also crosses zero but at a different x. So my question is: is it possible to identify the roots of such an equation by simply looking at the real and imaginary parts of the plot?
Note: part of my confusion is that if I use FindRoot, in Mathematica, I get either 0.877659 - 0.142424i or -0.877659 + 0.142424i. So might be some fundamental property in Maths I don't know about which prevents one from identifying roots of a complex function through separating real and imaginary parts...
we have a real part which crosses zero, and an imaginary part which also crosses zero but at a different x.
Those are graphs of the real and imaginary parts plotted for real values of x. If they both crossed the horizontal axis at the same point(s), that would mean the equation has real root(s), since both real and imaginary parts would be zero for some real value of x. However, this equation has no real roots, so the crossing points are different.
So my question is: is it possible to identify the roots of such an equation by simply looking at the real and imaginary parts of the plot?
f(x) = x^2 - 1 + i (x^2 - 0.5) is a complex function of a complex variable, which maps a complex variable x = a + i b to the complex value f(x) = Re(f(x)) + i Im(f(x)).
Each of Re(f(x)) and Im(f(x)) is a real function of a complex variable. Such functions can be plotted in 3D by representing x = a + i b as a point in the (a, b) plane, and the value of the function along the third dimension, say c. For example, f(x) has the following graphs for the real and imaginary parts.
The cross-sections of the two surfaces by the horizontal plane c = 0 are pairs of curves where each function is zero, respectively. It follows that the intersections of those curves are the points where Re(f(x)) = Im(f(x)) = 0, which means they are the roots of the equation f(x) = 0.
Since f(x) = 0 is a quadratic equation, it must have two roots, and those two points are in fact ±(0.877659 - 0.142424 i), as can be verified by direct calculation.
The only equation to calculate this that I can find involves t in the range [0, 1], but I have no idea how long it will take to travel the entire path, so I can't calculate (1 - t).
I know the speed at which I'm traveling, but it seems to be a heavy idea to calculate the total time beforehand (nor do I actually know how to do that calculation). What is an equation to figure out the position without knowing the total time?
Edit To clarify on the cubic bezier curve: I have four control points (P0 to P1), and to get a value on the curve with t, I need to use the four points as such:
B(t) = (1-t)^3P0 + 3t(1-t)^2P1 + 3t^2(1-t)P2 + t^3P3
I am not using a parametric equation to define the curve. The control points are what define the curve. What I need is an equation that does not require the use of knowing the range of t.
I think there is a misunderstanding here. The 't' in the cubic Bezier curve's definition does not refer to 'time'. It is parameter that the x, y or even z functions based on. Unlike the traditional way of representing y as a function of x, such as y=f(x), an alternative way of representing a curve is by the parametric form that represents x, y and z as functions of an additional parameter t, C(t)=(x(t), y(t), z(t)). Typically the t value will range from 0 to 1, but this is not a must. The common representation for a circle as x=cos(t) and y=sin(t) is an example of parametric representation. So, if you have the parametric representation of a curve, you can evaluate the position on the curve for any given t value. It has nothing to do with the time it takes to travel the entire path.
You have the given curve and you have your speed. To calculate what you're asking for you need to divide the total distance by the speed you traveled given that time. That will give you the parametric (t) you need. So if the total curve has a distance of 72.2 units and your speed is 1 unit then your t is 1/72.2.
Your only missing bit is calculating the length of a given curve. This is typically done by subdividing it into line segments small enough that you don't care, and then adding up the total distance of those line segments. You could likely combine those two steps as well if you were so inclined. If you have your given speed, just iteration like 1000th of the curve add the line segment between the start and point 1000th of the way through the curve, and subtract that from how far you need to travel (given that you have speed and time, you have distance you need to travel), and keep that up until you've gone as far as you need to go.
The range for t is between 0 and 1.
x = (1-t)*(1-t)*(1-t)*p0x + 3*(1-t)*(1-t)*t*p1x + 3*(1-t)*t*t*p2x + t*t*t*p3x;
y = (1-t)*(1-t)*(1-t)*p0y + 3*(1-t)*(1-t)*t*p1y + 3*(1-t)*t*t*p2y + t*t*t*p3y;
I'm trying to design a program that draws graphs given a set of points (x, y), and it also should recognize the curve (straight line, hyperbole, parabola), with only the help of the points.
Is there an algorithm to do that?
You'll need five points if the curve could be a straight line or a conic (hyperbola, parabola, ellipse, circle).
If the five points are collinear, you have a straight line. (Or a degenerate conic? But if you're expecting straight lines, this should indicate a straight line.)
If four are collinear, you have a degenerate conic, given by the line through the four collinear points and any line through the fifth point that is not parallel to the first line.
If three are collinear, you have a degenerate conic, given by the line through the three collinear points and the line through the two other points. (Unless these two lines are parallel, in which case this isn't a conic.)
If no three points are collinear, you have a unique, non-degenerate conic.
To find the equation for this conic (Ax^2 + Bxy + Cy^2 + Dx + Ey + F = 0), take a look at this page, specifically the formula in the DETAILS section. Put in your five x and y values, calculate the determinant of the matrix in terms of x and y, and this will give you the formula of your conic. Then see here to figure out what kind of conic you have based on the values of A, B and C.
If you have more than 5 points, pick five points (preferably so no three are collinear), find the conic, and then check that the remaining points lie on the conic.
You can do it by watching the function extreme but is maybe not optimal solution for this problem (i mean a problem in parabola function like that y = sqrt(x*x-1)).
For straight line you can calc y = ax + b by the 2 random point's and check what other points equal this condition, if yes. This is straight line if no you may check a 2 other exceptions or nothing from it. Maybe somone else get solution for next 2 cases?
I have a nice cubic spline code but it is for interpolation only. I need to extrapolate just a little into the future. Does anyone know of a good source of code, not a library, for doing this?
This is the code I wrote in basic (now ASM) for interpolation.
You don't need new code for that.
To extrapolate the spline you can extrapolate the parameters of the first and last spline.
Depending on your existing code/library that might not be possible without modifying the code. In that case just prepend/append two other points to the beginning/end of your list of points. You can get those two points by linearily interpolating between the first/last two points.
Be careful: Depending on the original meaning of the points that extrapolation might be completely inappropriate, especially when it comes to statistical data. In that case you should consider using regression analysis.
For simplicity, I'm going to represent a cubic Bezier curve
as 4 points (A, B, C, D),
where A and D are the endpoints of the curve,
and B and C are the "control handle points".
(The actual curve usually does not touch the control handle points).
See "Don Lancaster's Guru's Lair Cubic Spline Library"
for ways to convert this representation of a cubic Bezier curve
into other popular representations.
interpolation
Given one cubic Bezier curve (P0, P1, P2, P3),
we use De Casteljau's algorithm
to chop a Bezier curve into
a left half and a right half.
This is super-easy even on a microcontroller that doesn't have a "multiply" instruction,
because it only requires calculating a few averages until we get a midpoint:
P0
F0 := average(P0, P1)
P1 S0 := average(F0, F1)
F1 := average(P1, P2) Midpoint := average(S0, S1)
P2 S1 := average(F1, F2)
F2 := average(P2, P3)
P3
The entire Bezier curve is (P0, P1, P2, P3).
The left half of that entire Bezier curve is the Bezier curve (P0, F0, S0, M).
The right half of that entire Bezier curve is the Bezier curve (M, S1, F2, P3).
Many microcontrollers continue to divide each curve up
into smaller and smaller little curves
until each piece is small enough to approximate with
a straight line.
But we want to go the other way -- extrapolate out to a bigger curve.
extrapolation
Given either the left half or the right half,
we can run this in reverse to recover the original curve.
Let's imagine that we forgot the original points P1, P2, P3.
Given the left half of a Bezier curve (P0, F0, S0, M),
we can extrapolate to the right with:
S1 := M + (M - S0)
F1 := S0 + (S0 - F0)
P1 := F0 + (F0 - P0)
then use those values to calculate
F2 := S1 + (S1 - F1)
P2 := F1 + (F1 - P1)
and finally
P3 := F2 + (F2 - P2)
to extrapolate and recover the extrapolated Bazier curve (P0, P1, P2, P3).
details
The extrapolated curve (P0, P1, P2, P3)
passes through every point in the original curve
(P0, F0, S0, M) --
in particular, starting at P0 and passing through the midpoint M --
and keeps on going until it reaches P3.
We can always extrapolate from any 4 points (P0, F0, S0, M),
whether or not those 4 points were originally calculated
as the left half (or right half) of some larger Bezier spline.
I'm sure you already know this, but just for clarity:
Midpoint = average(F0, F1)
means "find the Midpoint exactly halfway between points F0 and F1",
or in other words,
Midpoint.x = (F0.x + F1.x)/2
Midpoint.y = (F0.y + F1.y)/2
Midpoint.z = (F0.z + F1.z)/2
The expression
S1 := M + (M - S0)
means "Given a line segment, with one end at S0, and the midpoint at M,
start at S0 and run in a straight line past M until you reach the other end at S1",
or in other words
(unless you have a decent vector library) 3 lines of code
S1.x := M.x + (M.x - S0.x)
S1.y := M.y + (M.y - S0.y)
S1.z := M.z + (M.z - S0.z)
.
(If you're doing 2D, skip all the "z" stuff -- it's always zero).
You'll really have to expand that question a little. Also, "cubic spline" is a very wide term.
If you're interested in splines, I can heartly reccomend Carl de Boors "A Practical Guide to Splines". It is however a little mathematically oriented, but it has code examples included (they can be downloaded from the author's home page). Googling and wikiing for "cubic spline" can bring up some examples, maybe even in particular languages - another thing to add to the question (if you're looking for code).
If you're interested in extrapolation and curve fitting, googling those could help. Matlab package has a very nice curve fitting toolbox. Wikipedia has some links to useful references
Really, it is too wide a question, to even start guessing an answer.
Also, could you explain what exactly are you trying to do ? What kind of data ? Anything ?
Edit1: Here, try this: you may find something useful in here - link
Generally for spline interpolation you use a variable t to interpolate over the line. As long as 0 <= t <= 1 you're interpolating. However, when t < 0 or t > 1 you're simply extrapolating the spline.
You need to write better requirements for requested code. Splines are usually used for interpolation of some unknown or complex function by using of some fixed data set. If you want to have an estimate of function's value outside of boundaries of this data set then you shouldn't use splines.
If your spline is function defined in the place where you really want to evaluate your value (cubic, but not piecewise-cubic) then you already can evaluate that value.
If you want to have ability to evaluate your spline outside of interpolation range, but leave it as piecewise-cubic function with the same values inside of interpolation range then you should extend spline range by some nodes, and add some logic of evaluation values at the new nodes (for example you want to have your spline be not only a continuous function, but also have some number of first derivatives be also continuous functions)
Really I suggest you to use some algorithm more suitable for extrapolation, like usage of Lagrange polynomial if everything you really need is single value not very far from points of original data set.