I am well aware that there are several ways to find the tangents to a Bezier curve. However, I choose to just substitute the result of differentiating the Bezier curve equation.

So, given four control points, ptOne, ptTwo, ptThree and ptFour:

// Differentiate x with respect to t
float dxdt = -3*(1 - t)*(1 - t)*ptOne.x
+ 3*(1 - 4*t + 3*t*t)*ptTwo.x
+ 3*(2*t - 3*t*t)*ptThree.x
+ 3*t*t*ptFour.x;

// Differentiate y with respect to t
float dydt = -3*(1 - t)*(1 - t)*ptOne.y
+ 3*(1 - 4*t + 3*t*t)*ptTwo.y
+ 3*(2*t - 3*t*t)*ptThree.y
+ 3*t*t*ptFour.y;

// Find the tangent, dy/dx
float dydx = dydt * (1/dxdt);

// Find the rotation angle in degrees
float angle = atan(dydx) * 180/M_PI;

The strange thing is that this does not seem to be working for all kinds of curve. For example, if I draw a curve like this, with the first control point being the second leftmost point and then in a clockwise direction:

enter image description here

and attempt to draw the tangents:

enter image description here

You can see that some tangents (in particular, the first two and very last one) are not oriented in the right direction. Why might this be happening? I triple checked my differentiation and can't find anything wrong...

  • 2
    $\begingroup$ The problem is the dydx computation, which cannot distinguish between equal and opposite tangents, e.g. $(1,0)$ and $(-1,0)$. You should just use $(dy/dt, dx/dt)$ as the tangent vector and normalize it. $\endgroup$ – user106 Nov 3 '18 at 16:32
  • $\begingroup$ OK, I'll give it a shot tomorrow. Thanks for the suggestion! $\endgroup$ – umop apisdn Nov 3 '18 at 16:47
  • $\begingroup$ @Rahul Noting that, sometimes one needs to use the 2nd (or 3rd) derivatives if the 1st derivative vanishes. $\endgroup$ – Simon F Nov 5 '18 at 9:55
  • $\begingroup$ @SimonF: If the 1st derivative is zero and the 2nd derivative is not, then the curve has a cusp and the tangent is not defined. Only in the extremely rare case that both the 1st and the 2nd derivatives are zero does one have to use the 3rd derivative to obtain the tangent. (And beyond that in general, the first nonzero higher-order derivative, as long as it is of odd order.) $\endgroup$ – user106 Nov 5 '18 at 12:14
  • $\begingroup$ @Rahul It's been a long time since I was on the OpenVG spec group so this is not exactly fresh in my memory, but what of the cubic Bezier curve with control points A, A, B, C? $\endgroup$ – Simon F Nov 6 '18 at 8:53

Using what Rahul kindly suggested in the comments, I realised that my tangent can be rotated in the opposite direction for two cases:

  1. if dy/dt and dx/dt are both negative, yet dy/dx ends up being positive
  2. if dy/dt is negative and dx/dt is positive, so the overall dy/dx is negative

This is because my angle calculation, which is done by float angle = atan(dydx) * 180/M_PI; will only calculate acute angles from the horizontal, and hence miss out the opposite cases.

Thanks a bunch!

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.