4

I need a help in writing the algorithm remove nodes Bezier curve. Using cubic Bezier curves, there are two curves (P0, P1, P2, P3 and Q0, Q1, Q2, Q3), which have a common point (P3=Q0). Need to get a single curve (P0, R1, R2, Q3), repeating the shape of two. How to find the coordinates of control points R1, R2?

Thank you!

Quasimondo
  • 2,485
  • 1
  • 22
  • 30
Nekit_SPb
  • 43
  • 4
  • Sounds as if you would need to do some interpolation of P1 vs. Q1 and P2 vs. Q2 - or is that problem actually more complicated? – Till Dec 31 '11 at 11:03
  • P1, P2, Q1 and Q2 - the control points of Bezier curves. I do not understand about what you say interpolations. For example, in CorelDRAW when removing a node P0P1 and Q3Q2 guides increase or decrease. The curve roughly follows the original two. I need to do something like that – Nekit_SPb Dec 31 '11 at 11:16
  • What if the combined curve has a bent? Just because P3=Q0 doesn't mean that the connection is smooth. I think a smooth continuation requires P2, P3=Q0 and Q1 to be on a line (and perhaps even |P3-P2|=|Q1-Q0|, the distance between P3 and P2 being the same as the distance between Q1 and Q0). – Uli Schlachter Dec 31 '11 at 15:58
  • Yes, you're right. For a smooth connection, you need to P2, P3 = Q0 and Q1 were on the same line. If not, then there is a bend. In this case, the control points P2 and Q1 turn, the connection becomes smooth and made ​​the conversion. – Nekit_SPb Jan 08 '12 at 11:25

1 Answers1

1

In the general case, it's not possible to do what you're asking. You're asking to go from 7 degrees of freedom down to 4 but keep the same result. The representative power of the lower DOF system can't match that of the higher. The only time it would be possible is if the more complex curve still happened to lie in the simpler space. For example, if your two Bezier curves came from sub-dividing a single parent curve with points R0, R1, R2, R3. Using the de Casteljau algorithm, we can generate two new curves, P and Q, that lie on the same original curve and share a point that is t distance along the original curve (where t is in [0,1]).

P0 = R0
P1 = R0*(1-t) + R1*t
X  = R1*(1-t) + R2*t
P2 = P1*(1-t) + X*t
Q3 = R3
Q2 = R2*(1-t) + R3*t
Q1 = X*(1-t) + Q2*t
Q0 = P3 = P2*(1-t) + Q1*t

If that relationship doesn't hold for your original points, then you'll have to craft an approximation. But you might get away with pretending that the relationship holds and just invert the equations:

R1 = (P1 - P0*(1-t))/t
R2 = (Q2 - Q3*t)/(1-t)

Where

t = (Q0 - P2)/(Q1 - P2)

This last equation is the problem because, unless P2, Q0, Q1 are co-linear it won't work exactly. t is a scalar, but Q1-P2 is normally an n-dimensional point. So you can solve it separately for each dimension and find the average, or be a bit more sophisticated and minimize the squared error.

JCooper
  • 6,395
  • 1
  • 25
  • 31
  • I used this in my Bezier tool in Unity. It works flawlessly for segments splitted with Casteljau algorithm. Thank you soooo much! public static Vector3[] JoinSegments(IEnumerable twoSegments) { var s = twoSegments.Take(2); var P = s.First(); var Q = s.Last(); float t = (P[3] - P[2]).magnitude / (Q[1] - P[2]).magnitude; var newSegment = new Vector3[] { P[0], (P[1]-P[0]*(1-t))/t, (Q[2]-Q[3]*t)/(1-t), Q[3], }; return newSegment; } – zORg Alex Jul 01 '22 at 11:56
  • Ah... Can't paste code here – zORg Alex Jul 01 '22 at 11:57