2
$\begingroup$

So I'm working on a program that graphs a bezier curve by manipulating the control points. This curve represents the velocity of something over time; I also want the option manipulate it all in terms of acceleration in respect to that velocity. My initial thought was to take the derivative of the bezier curve function and plot that with the same control points.

In my program it works, however I think the math doesn't really do what I want. This nice article has helped me on the math so far, but the problem I'm facing is that the derivative curve is simply "off."

The graphs below are velocity on the Y axis and time on the X axis.

Here's what the graph looks like with my bezier function:

Now, the derivative of that looks like this...

I'm not sure if my math is off, or if that's simply what the derivative of the bezier function actually does. But, what I really want to do is take my bezier curve and draw the rate of change over the same domain. However, the derivative seems to take it out of the domain (when you see my graphs below you'll see how the derivative changes the scope).

What can I do to extrapolate the data I'm looking for from this curve (turning velocity over time with a bezier function into acceleration over time)?

Here's the code where I'm drawing the point of the graph (it is calculating the curve from 0 to 1 and drawing a point there). I subract an extra 1 with n (the number of control points) as I calculate in an extra 1 at some point in the code above to be more efficient elsewhere:

Bezier function:

position $+=$ linearCombination$(n - 1, z) \cdot$ Mathf.Pow$((1.0f - t), n - 1 - z) \cdot$ Mathf.Pow$(t, z) \cdot$ controls[$z$].position;

Derivative:

position $+=$ linearCombination$( n - 2, z ) \cdot$ Mathf.Pow$(1.0f - t, n - 2 - z) \cdot$ Mathf.Pow $(t, z) \cdot (n - 1) \cdot$ (controls[$z + 1$].position - controls[$z$].position );

$\endgroup$
3
  • $\begingroup$ cs.mtu.edu/~shene/COURSES/cs3621/NOTES/spline/Bezier/… Link to the article I talked about in the question. $\endgroup$
    – Wuzseen
    Mar 4, 2013 at 2:31
  • $\begingroup$ If you want velocity to be a function of time, you shouldn't be using a Bézier curve in the first place! Just use a cubic Hermite spline directly. After all, a Bézier curve with four control points is just a curve where both $x$ and $y$ are cubic functions of a hidden parameter $u$. But you want $y$ to be a function of $x$ here. $\endgroup$
    – user856
    Mar 4, 2013 at 8:08
  • $\begingroup$ Great suggestion Rahul, I just might do that! $\endgroup$
    – Wuzseen
    Mar 4, 2013 at 8:50

1 Answer 1

2
$\begingroup$

It depends what you're graphing.

The buttons on the left of your image say "xCurve, yCurve, zCurve", and this suggests that you have a 3D curve, and you are graphing one of the coordinates ($x$) versus a time parameter, $t$.

If so, the graph of the derivative is certainly wrong. It should have the value $0$ when the abscissa (the horizontal axis value, the $t$-value) is around 17 or 53.

On the other hand, your graphs don't look like "$x$ versus $t$" graphs, they look like "$(x,y)$ versus $t$" graphs. If this is the case, then your results might well be correct (though undesirable). See below for details.

Let's start from the beginning with a nice simple notation:

Suppose $P(t)$ is a cubic Bezier, with control points $A$, $B$, $C$, $D$. Then its equation is:

$$P(t) = (1-t)^3A + 3t(1-t)^2B + 3t^2(1-t)C + t^3D \quad (0 \le t \le 1) $$

Then the derivative curve is a quadratic (degree 2) curve, and its control points are $3(B-A)$, $3(C-B)$, $3(D-C)$, so it's equation is:

$$Q(t) = 3(1-t)^2(B-A) + 6t(1-t)(C-B) + 3t^2(D-C) \quad (0 \le t \le 1) $$

All of this applies regardless of whether $A$, $B$, $C$, $D$ are $x$ values or $(x,y)$ values.

If you want to draw "$x$ versus $t$" graphs, then drawing $P$ and $Q$ together on the same graph should be straightforward.

If you want to draw "$(x,y)$ versus $t$" graphs, then putting both $P$ and $Q$ on the same graph is more problematic. Suppose the control points $A$, $B$, $C$, $D$ were a great distance from the origin, but fairly close to each other. Then $B-A$, $C-B$, $D-C$ would be small, so the $Q$ curve would be close to the origin -- far away from the $P$ curve. In your case, it looks like (roughly) $A = (0,0)$ and $B=(32,12)$, so the first control point of the derivative curve $Q$ is $3(B-A) = (96,36)$, which is off the charts. Your derivative graph is clipped, so the end-points of the curve are not visible, which makes it harder to say whether or not it's correct. At least it looks like a parabola, though, which is correct (Bezier curves of degree 2 are parabolas).

These notes might help. Section 2.5 discusses derivatives, and there's a picture showing how the derivative curve relates to the original one (for the xy-vs-t case). Section 2.12 talks about the x-vs-t type of curve (which is variously referred to as a real-valued, explicit, or non-parametric Bezier curve).

$\endgroup$
9
  • $\begingroup$ The buttons on the left are for displaying additional curves. One for x versus t, one for y versus t, one for z versus t and so on. They're all two dimensional curves though. As you mentioned though, the derivative of X degree curves are coming out like X-1 curves. $\endgroup$
    – Wuzseen
    Mar 4, 2013 at 8:48
  • $\begingroup$ I had to walk away for a moment and come back to read your answer more closely, it sounds like that the curve is being drawn exactly as it should be (off the screen). imgur.com/RjUcETb That's the rest of the curve (it's all on 1 plane despite the 3d view... this is an interface inside the unity game engine by the way). 96,36 is looking pretty darn accurate. In the comments to the original post, Rahul suggested taking a different approach? Might that be the best way to achieve the result I'm looking for then? $\endgroup$
    – Wuzseen
    Mar 4, 2013 at 9:07
  • $\begingroup$ If you want to draw both curves on the same graph, I'd suggest you use "x-versus-t" curves. You can still use Bezier curves, if you want, but the "control points" A, B, C, D will just be numbers; in mathematical jargon, you'll be using real-valued Bezier curves, rather than the usual vector-valued ones. Then, to describe a 3D curve, you will have 3 graphs -- x-vs-t, y-vs-t, and z-vs-t. What you are current drawing are "xy-versus-t" curves, I think. You are drawing them correctly, but the result is not useful, it seems to me, because the two curves are so disconnected in space. $\endgroup$
    – bubba
    Mar 4, 2013 at 9:19
  • $\begingroup$ i.imgur.com/Q5uBLyn.png Hopefully that image might clear up some confusion, I turned on the 3 X/Y/Z curves all at once. I do have 3 different graphs (I'm just drawing them all at once). The program can switch between drawing the derivative and the normal bezier of these curves. That is, I think I am drawing the 3 different graphs as you are suggesting. What may not be clear is what I want out of the data. I want to be able to modify the rate of change of the curve so that I might be able to create steeper slopes. Maybe I need to interpolate these control points differently. $\endgroup$
    – Wuzseen
    Mar 4, 2013 at 9:29
  • $\begingroup$ Ran out of space but wanted to add on... I'm simply using this data for the slope of the curves. The x axis is completely arbitrary. While it goes to 65 here, that's just to match units in unity (the game engine). All I do is divide the x position of the blue bar by 65 so that it goes from 0 to 1 (so the X axis is t). I'm sending this data to another program that computes acceleration from velocity data. So just sending the acceleration data isn't really the option. $\endgroup$
    – Wuzseen
    Mar 4, 2013 at 9:37

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .