0

I am attempting to calculate the tangent of a cubic Bezier curve defined by the points p0, p1, p2, p3, and t.

I know this should be a simple calculation and the tangent should simply be the derivative of the cubic bezier curve equation. I am attempting to do this in the same way as I calculate my curve points: which is by separately passing the x values of each p0-p3 to the cubic Bezier equation and then doing the same with the y point and then using the results for the x, y coords of the next point on the curve (next being the point at t)

The Issue is that while the above equation works and I get an accurate bezier curve plotted, when I try to do the same for the tangent vectors at point t, they all are massively off (specifically way too high (-y value) and to the left).

My graph

Another issue that is bothering me is that I know the tangent vector to the curve at t = 0.0 should be from p0 to p1 however when applying this to the derivative it ends up being (simplified): -3 * p0 + 3 * p1 Which would never be p1 unless p1 and p0 were the same?

I feel as I'm missing an extra step here.

I've also looked at Find the tangent of a point on a cubic bezier curve which didn't work for me.

I should also mention I'm doing this all in Java graphics2d canvas and therefore the origin is in the top left and the positive y axis is "down" and the negative y axis is "up" and x axis is normal – I'm not sure if there is an issue with that.

Code for bezier curve calculation (only x or y)

private static double getPoint(double a0, double a1, double a2, double a3, double detail) {
    return Math.pow(1 - detail, 3) * a0 
     + 3 * Math.pow(1 - detail, 2) * detail * a1
     + 3 * (1 - detail) * Math.pow(detail, 2) * a2
     + Math.pow(detail, 3) * a3;
}

Code for tangent calculation is below.

double tan = -3 * p0 * (Math.pow(1-t,2)) +
              p1 * (3*(Math.pow(1-t,2)) - 6*(1-t)*t) +
              p2*(6 * (1-t) * t) - (3 * Math.pow(t,2)) +
              3 * p3 * Math.pow(t, 2);`

Here I would pass in the x-values for p0 - p3 and then the y-values for p0-p3 and get the coordinates of the (end?) Of the tangent from both of those.

IS there anything blatantly obvious I'm missing?

double-beep
  • 5,031
  • 17
  • 33
  • 41
  • What are you doing with the tangents? It seems that your code is correct, but you might have a wrong understanding of what the tangent is. The tangent that you calculated for the first point `-3 p0 + 3 p1` is correct. It can be rewritten to be `3 (p1 - p0)`, which is obviously the vector from `p0` to `p1`, scaled by `3`. – Nico Schertler Mar 13 '19 at 03:18
  • 1
    How do you render the tangents? they should be rendered as a line starting from `position(t)` and ending at `position(t)+size*tangent(t)` where size is a constant scaling the tangent to visible/usable lengths... my bet is you forgot the `position(t)+` in the last endpoint. If nothing works you can also use `postion(t+dt)-position(t)` as a tangent too ... – Spektre Mar 13 '19 at 09:30
  • Yes, I figured out my issue, As Spektre said I was plotting the tangent vector from the origin rather than starting at position(t). Thank you for the help! – Arthur Gildehaus Mar 13 '19 at 14:23
  • 1
    If you found the solution, post it as an answer so that this site doesn't see this question as "unanswered". – Peter O. Mar 13 '19 at 19:42
  • I transform my comment into answer ... – Spektre Mar 14 '19 at 09:18

1 Answers1

0

How do you render the tangents? they should be rendered as a line starting from position(t) and ending at position(t)+size*tangent(t) where size is a constant scaling the tangent to visible/usable lengths...

my bet is you forgot the position(t)+ in the last endpoint (common rookie mistake even I did it few times before). If nothing works you can also use postion(t+dt)-position(t) as a tangent too.

Spektre
  • 49,595
  • 11
  • 110
  • 380