Home > Software engineering >  Splitting rational bezier
Splitting rational bezier

Time:06-15

According to someone a rational bezier can be split by projecting its control points from 2d to 3d (or from 3d to 4d and so on), splitting the resulting non-rational curve with De Casteljau, and then projecting the two curves back to 2d which makes them rational again.

I have this Shadertoy prototype where I tried to put the weights directly in place of the z value, before realizing there would need to be some kind of transformation on the xy coordinates for the De Casteljau calculated midpoint (m) to align with the weighted curve. A projection matrix can have a field of view and an aspect ratio attribute from what I've seen.

What kind of matrix do I need to get the points and weights to align correctly, and what should I do with the weights to begin with to turn them into z coordinates?

vec3[6] split(float[3] r, vec2[3] p, float t)
{
    vec3 a = vec3(p[0],r[0]);
    vec3 b = vec3(p[1],r[1]);
    vec3 c = vec3(p[2],r[2]);
    vec3 ab = mix(a, b, t);
    vec3 bc = mix(b, c, t);
    vec3 m = mix(ab, bc, t);
    
    vec3[3] l = vec3[3](a,ab,m);
    vec3[3] R = vec3[3](m,bc,c);
    return vec3[6](l[0],l[1],l[2],R[0],R[1],R[2]);
}

CodePudding user response:

In degree 2, for example, a Bezier is f(t) = (1-t)2P0 2t(1-t)P1 t2P2

A rational Bezier is (1-t)2P0w0 2t(1-t)P1w1 t2P2w2 / (1-t)2w0 2t(1-t)w1 t2w2

If your perspective transform maps (x,y,z) to (x/z, y/z), then you can move the weights directly into the z coordinate to get the correct denominator, but you also have to multiply the corresponding points to make the new points map to the same (x,y).

When you do both, it simplifies, and your new points are:

P0' = w0(P0,1)

P1' = w1(P1,1)

P2' = w2(P2,1)

The regular 3D Bezier will then map to the same (x,y) curve under perspective transformation:

f(t) = (1-t)2P0' 2t(1-t)P1' t2P2'

  • Related