Subdivide:
PUBLIC
PROC [patch: Patch, s, t:
REAL ¬ 0.5]
RETURNS [fp: FourPatches] ~ {
BezierDivide:
PROC [b: Bezier, t:
REAL]
RETURNS [b1, b2: Bezier] ~ {
Lerp:
PROC [p, q: Triple]
RETURNS [Triple] ~
INLINE {
tt: REAL ¬ 1.0-t;
RETURN[[tt*p.x+t*q.x, tt*p.y+t*q.y, tt*p.z+t*q.z]];
};
b01: Triple ¬ Lerp[b.b0, b.b1];
b12: Triple ¬ Lerp[b.b1, b.b2];
b23: Triple ¬ Lerp[b.b2, b.b3];
b0112: Triple ¬ Lerp[b01, b12];
b1223: Triple ¬ Lerp[b12, b23];
b01121223: Triple ¬ Lerp[b0112, b1223];
RETURN[[b.b0, b01, b0112, b01121223], [b01121223, b1223, b23, b.b3]];
};
PatchFromBezier:
PROC [b0, b1, b2, b3: Bezier]
RETURNS [p: Patch] ~ {
RETURN[FromBezier[
NEW[ControlPointsRep ¬ [
[b0.b0, b0.b1, b0.b2, b0.b3],
[b1.b0, b1.b1, b1.b2, b1.b3],
[b2.b0, b2.b1, b2.b2, b2.b3],
[b3.b0, b3.b1, b3.b2, b3.b3]]]]];
};
cp: ControlPoints ¬ patch.controlPoints;
s0, s1, s2, s3, s4, s5, s6, s7, t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13: Bezier;
[s0, s1] ¬ BezierDivide[[cp[0][0], cp[0][1], cp[0][2], cp[0][3]], s];
[s2, s3] ¬ BezierDivide[[cp[1][0], cp[1][1], cp[1][2], cp[1][3]], s];
[s4, s5] ¬ BezierDivide[[cp[2][0], cp[2][1], cp[2][2], cp[2][3]], s];
[s6, s7] ¬ BezierDivide[[cp[3][0], cp[3][1], cp[3][2], cp[3][3]], s];
[t0, t1] ¬ BezierDivide[[s0.b0, s2.b0, s4.b0, s6.b0], t];
[t2, t3] ¬ BezierDivide[[s0.b1, s2.b1, s4.b1, s6.b1], t];
[t4, t5] ¬ BezierDivide[[s0.b2, s2.b2, s4.b2, s6.b2], t];
[t6, t7] ¬ BezierDivide[[s0.b3, s2.b3, s4.b3, s6.b3], t];
[t8, t9] ¬ BezierDivide[[s1.b1, s3.b1, s5.b1, s7.b1], t];
[t10, t11] ¬ BezierDivide[[s1.b2, s3.b2, s5.b2, s7.b2], t];
[t11, t12] ¬ BezierDivide[[s1.b3, s3.b3, s5.b3, s7.b3], t];
fp[0] ¬ PatchFromBezier[t0, t2, t4, t6];
fp[1] ¬ PatchFromBezier[t1, t3, t5, t7];
fp[2] ¬ PatchFromBezier[t6, t8, t10, t12];
fp[3] ¬ PatchFromBezier[t7, t9, t11, t13];
};