Arthur Gildehaus
Arthur Gildehaus

Reputation: 1

How to calculate tangent for cubic bezier curve?

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?

Upvotes: 0

Views: 1937

Answers (1)

Spektre
Spektre

Reputation: 51923

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.

Upvotes: 0

Related Questions