First things first: This is not for any kind of homework.
I'm currently trying to implement CSS3-like cubic bezier stuff into a C# program that does pretty color transitions, but fail due to my lacking knowledge of cubic bezier curves.
In fact, I have never heard of them until today.
Assuming that they basically consist of four points with X and Y values that are between 0 and 1, and that the first and last points are (0, 0) and (1, 1), respectively, how would I calculate the Y value for a given X if points 2 and 3 have these X and Y values?
Point 2: (0.42, 0)
Point 3: (1, 1)
Point 2: (0, 0)
Point 3: (0.58, 1)
Point 2: (0.42, 0)
Point 3: (0.58, 1)
There has to be some kind of formula that allows me to insert X somewhere, calculate a bit and then get Y. Please explain this for dummies, as I really don't know shit about this.
Oops, didn't see that when I rushed into this subforum. :P
This is the image that helped me understand bezier curves.
[img]http://upload.wikimedia.org/wikipedia/commons/f/ff/Bezier_3_big.gif[/img]
I recently implemented cubic bezier splines into a project I'm working on, and I found this helpful (particularly see "Curve Evaluation")
[url]http://www.algorithmist.net/bezier3.html[/url]
[img]http://upload.wikimedia.org/wikipedia/en/math/6/1/6/616fa6865c565d8385bb64bf4aa32a79.png[/img]
Only the first line is relevant to our interests. Courtesy of Wikipedia.
n is the number of points in the curve - 1, in this case two, the argument, t, is 'drawing progress', from 0 to 1, and P is a coordinate of a point (in 2d space, you have to calculate this once for P = x, and once for P = y, to get x,y coordinates). If you don't know, that giant Sigma means 'sum of elements to the right of me, from 0 to n, i being the iterator' and that weird stuff in parentheses is the [url=http://en.wikipedia.org/wiki/Binomial_coefficient]binomial coefficient[/url].
In your first case, this would mean using this for calculating the X coordinate of a curve point:
[img]http://i.imgur.com/BcnL9.gif[/img]
The binomial coefficients expand to 1, 2 and 1 respectively.
@Jinto It may look easy to you, but I'm not your average math genius. :P
I'm sure I'd understand it once we do this in school, but I'm not doing this for school.
@BMCHa I don't really get this part: [url]http://cl.ly/C0P5[/url]
I'm working in .NET here, and I don't know of a way to multiply/add/subtract/divide points there. (e.g. "c3 = P3-P0+b-c")
@q3k This question may sound dumb, but do I have to multiply the binomial coefficients with (1-t) in your formula?
I played a bit with it, which resulted in this: [url]http://cl.ly/C0mU[/url]
Is one of those getXforT functions correct?
How would your X(t) formula look like if the given two points were (0.2, 0.6) and (0.8, 0.4)?
[QUOTE=Jinto;33379170]This is the image that helped me understand bezier curves.
[img]http://upload.wikimedia.org/wikipedia/commons/f/ff/Bezier_3_big.gif[/img][/QUOTE]
This is great, images do such a better job conveying knowledge like this.
[editline]22nd November 2011[/editline]
So I had some downtime at work and threw this together. Can someone who understands the actual formula explain it's performance characteristics vs this implementation? I would expect this naive implementation to be much slower.
[CODE]
class line
{
public:
line(POINT _a, POINT _b) : a(_a), b(_b) { }
POINT getPointatT(float t) {
POINT r;
r.x = a.x * (1.0f - t) + b.x * t;
r.y = a.y * (1.0f - t) + b.y * t;
return r;
}
private: POINT a, b;
};
std::vector<POINT> GenerateCurve(POINT a, POINT b, POINT c, POINT d, float step)
{
line first1(a, b), first2(b, c), first3(c, d);
std::vector<POINT> r;
r.reserve(1.0f / step + 1);
for (float t = 0.0f; t < 1.00001; t += step)
{
line second1(first1.getPointatT(t), first2.getPointatT(t));
line second2(first2.getPointatT(t), first3.getPointatT(t));
line third(second1.getPointatT(t), second2.getPointatT(t));
r.push_back(third.getPointatT(t));
}
return r;
}[/CODE]
[QUOTE=SamusAranX;33384533]How would your X(t) formula look like if the given two points were (0.2, 0.6) and (0.8, 0.4)?[/QUOTE]
In pseudocode:
[cpp]
Vector2 g_P0(0.0, 0.0);
Vector2 g_P1(0.2, 0.6);
Vector2 g_P2(0.8, 0.4);
float BezierQuadFloat(float P0, float P1, float P2, float t)
{
float A = (1 - t) * (1 - t) * P0;
float B = 2 * (1 - t) * t * P1;
float C = t * t * P2;
return A + B + C;
}
Vector2 BezierQuadVector2(Vector2 P0, Vector2 P1, Vector2 P2, float t)
{
Vector2 Result(BezierQuadFloat(P0.X, P1.X, P2.X, t), BezierQuadFloat(P0.Y, P1.Y, P2.Y, t));
}
void DrawBezier(float dt)
{
for (float t = 0.0; t < 1.0; t += dt)
{
Vector2 Point = BezierQuadVector(g_P0, g_P1, g_P2, t);
PutScreenspacePixelFloat(Vector2.X, Vector2.Y);
}
}
[/cpp]
[QUOTE=Jinto;33379170]This is the image that helped me understand bezier curves.
[img]http://upload.wikimedia.org/wikipedia/commons/f/ff/Bezier_3_big.gif[/img][/QUOTE]
It's funny how much more intuitive every mathematical problem gets when you're shown how it breaks down into basic geometry, as opposed to just staring at a page of meaningless symbols for hours on end.
Even more abstract problems benefit from a spatial/graphical representation.
[QUOTE=ROBO_DONUT;33386087]It's funny how much more intuitive every mathematical problem gets when you're shown how it breaks down into basic geometry, as opposed to just staring at a page of meaningless symbols for hours on end.
Even more abstract problems benefit from a spatial/graphical representation.[/QUOTE]
It certainly makes sense. The human brain isn't normally wired to do math. Some people's brains are, a la neuroplasticity, but most people's brains work with things, not ideas. Solving equations isn't going to help you escape a hungry tiger.
In any case, this is off topic now.
I just stared at q3k's pseudocode and that GIF for like 5 minutes and then, it all came together in my head. >.<
Thanks for all your help, guys. :)
In case you're interested in that project I needed this for, it's [url]http://samusaranfreak.deviantart.com/art/Aero-Adjuster-261383189[/url]. I'm trying to implement CSS3-like cubic bezier color transitions instead of that linear lerp transition I'm using now. ;)
Edit: This is my C# code, derived from q3k's pseudocode: [url]http://cl.ly/C1Nl[/url]
It works like a charm. :3
Sorry, you need to Log In to post a reply to this thread.