Archived

This topic is now archived and is closed to further replies.

dmatter

Bezier curve for motion prob

Recommended Posts

I can draw and move objects along a bezier curve but the problem I''m having is that at curves the motion slows down and at straight parts it speed up. My curve is notated by b(u), where u is apparently the percentage along the curve. How can I replace u with t being time instead so that the speed is constand all along the curve? Thanx!

Share this post


Link to post
Share on other sites
the short answer is that you can''t =)

your best bet is probably to determine how far you want to move each frame... then go along your bezier curve by small steps until the distance you wanted to move is reached... or something like that, but you won''t be able to find the position in one step, you''ll have to do some kind of iterations...

Share this post


Link to post
Share on other sites
You need to reparameterize the curve to produce a sequence u values that result in constant motion. The basic algorithm is to create a table of u values and the corresponding distance along the curve that the u value will calculate to. The arc length can be a little tricky to compute, but i''m sure google can walk you through some of them. After you have this table filled in, go through the arc length entries, find evenly spaced values, and use the corresponding u values for animation instead of just incrementing u at a constant rate. All this can be done during some initialization routine so performance should be unaffected at runtime. Hopefully, that makes some sense, i didn''t explain it very well.

Share this post


Link to post
Share on other sites
Is this how all games create smooth curved motion or is there a better way of doing it, perhaps another type of curve will do what I need?
I found a link which seems to be related to what I described:
http://gamedev.net/community/forums/topic.asp?topic_id=99623



[edited by - dmatter on April 4, 2004 1:37:13 AM]

Share this post


Link to post
Share on other sites
I guess you could try cubic spline interpolation, but I don''t know offhand if it''s any easier to get constant-rate motion that way :/

Share this post


Link to post
Share on other sites
You can calculate the length of a curve f(x) like this:

L = the integral from a till b of sqrt(1+(f''(x))²)

You know a (the starting position). You can seek b so that L is constant.

(I don''t know bezier curves, but this should work for all kinds of curves)

Share this post


Link to post
Share on other sites
erm, could you explain that a little more, I dont understand where that came from at all. Although it does seem familier I think I may have seen it somewhere before on this site (but can find it now - typical)

As far as I know there isnt an exact answer (like circumference of a circle) but I supose theres a formula, or something, that can approximate.

Share this post


Link to post
Share on other sites
quote:
Original post by Koroljov
You can calculate the length of a curve f(x) like this:

L = the integral from a till b of sqrt(1+(f'(x))²)

You know a (the starting position). You can seek b so that L is constant.

(I don't know bezier curves, but this should work for all kinds of curves)


i see how this works... but it won't work for bezier curves... since bezier curves are parametric equations, they look something like this:

x = f(t)
y = f(t)
z = f(t)

and integrating sqrt(1+(f'(x))²) is pretty hard i think, i can't think of a way to do it off the top of my head even for the simple case of say f'(x) = x...

[edited by - SpaceDude on April 4, 2004 9:31:25 AM]

Share this post


Link to post
Share on other sites
If you have a vector valued function
(f(t), g(t), h(t))
and you want each change in t to represent the same distance along the curve for the same change in t then you need find the arc length parametrization.
s = integral from L0 to L of sqrt((df/dt)^2+(dg/dt)^2+(dh/dt)^2))dt
L0 is a constant.
solve for L.
then your new curve is (f(L), g(L), h(L)) but replace L with what L is though.

[edited by - O_o on April 4, 2004 1:32:01 PM]

Share this post


Link to post
Share on other sites
http://www.saccade.com/writing/graphics/RE-PARAM.PDF

[edited by - O_o on April 4, 2004 1:45:18 PM]

Share this post


Link to post
Share on other sites
My math isnt exactly amazing, what are df, dt, dg and dh?

s = integral from L0 to L of sqrt((df/dt)^2+(dg/dt)^2+(dh/dt)^2))dt

How do you get an integral?
Some unoptimized code snippets might help explain better (or just complicate things more?)

Currently I'm rtying to implement a method by creating a table for all the points and then picking out those points that are evenly spaced. I dont think its too accurate and the method you are describing is probably more accurate - is it fast? -

[edited by - dmatter on April 4, 2004 3:24:37 PM]

Share this post


Link to post
Share on other sites
Look at url above it is math heavy though to understand. It has some code there I didn't read all of it though.

df/dt, dg/dt, dh/dt are derivatives of f with repect to t, g with repect to t and h with repect to t.

[edited by - O_o on April 4, 2004 2:21:52 PM]

Share this post


Link to post
Share on other sites
quote:
Original post by dmatter
Is this how all games create smooth curved motion or is there a better way of doing it, perhaps another type of curve will do what I need?
I found a link which seems to be related to what I described:
http://gamedev.net/community/forums/topic.asp?topic_id=99623



[edited by - dmatter on April 4, 2004 1:37:13 AM]


This method of reparameterization is pretty standard. I don''t know of any parametric curves where increasing u linearly will create a smooth path along the curve.

It''s not all that complicated once you get past the math, which can be a little tedious. Anyways, when i calculate arc length, i''d usually just subdivide the arc and take the sum of the linear distances between the additional points. For example, if i want to find the length of the arc from u = 0 to u = 0.10, I''d calculate it as something close to the distance between the point when u=0 and u = 0.01 plus the distance between u = .01 and u = .02 and so on. This method is not be perfect and it has some flaws (as i''m sure people will be pointing out beneath me), but it will work reasonably well in most cases, as long as you subdivide enough times. After all, you don''t need the motion to be perfectly smooth mathematically, you just don''t want the user to be able to notice the difference.

Share this post


Link to post
Share on other sites