home
Slicing bezier surfaces

It is possible to split a bezier surface into two pieces. It helps to slice a surface into several pieces by keeping the whole shape in its original form. In that way we are able to shape one piece of several slices of a whole surface.

function splitBezier(t, p0, p1, p2, p3) {
  const p4 = lerp(t, p0, p1);
  const p5 = lerp(t, p1, p2);
  const p6 = lerp(t, p2, p3);
  const p7 = lerp(t, p4, p5);
  const p8 = lerp(t, p5, p6);
  const p9 = lerp(t, p7, p8);
  return [
    [{...p0}, p4, p7, p9],
    [{...p9}, p8, p6, {...p3}]
  ];
}

This is a javascript code. I create the surface editing software in javascript. The function lerp is identical to Python one that I mentioned in my blog post before. It takes the t value between 0 and 1, and returns two bezier curves, one is the half that splitted at t, the other one is other half. Two of them when combined shapes the given bezier curve.

This slices a curve into two pieces. So I slice the main piece until it is one piece of slices I want while I create another surface with the each other half.

let sliceCurrent = 4;
const obj = {
  "wide": 10,
  "fall": 4,
  "points": [] // I leave it empty
}
while (sliceCurrent > 1) {
  const t = obj["wide"] / sliceCurrent * (sliceCurrent - 1) / obj["wide"];
  const [halfa, enda] = splitBezier(t, obj.points[0], obj.points[1], obj.points[2], obj.points[3]);
  const [halfb, endb] = splitBezier(t, obj.points[4], obj.points[5], obj.points[6], obj.points[7]);
  const [halfc, endc] = splitBezier(t, obj.points[8], obj.points[9], obj.points[10], obj.points[11]);
  const [halfd, endd] = splitBezier(t, obj.points[12], obj.points[13], obj.points[14], obj.points[15]);
  obj.points[0] = halfa[0];
  obj.points[1] = halfa[1];
  obj.points[2] = halfa[2];
  obj.points[3] = halfa[3];
  obj.points[4] = halfb[0];
  obj.points[5] = halfb[1];
  obj.points[6] = halfb[2];
  obj.points[7] = halfb[3];
  obj.points[8] = halfc[0];
  obj.points[9] = halfc[1];
  obj.points[10] = halfc[2];
  obj.points[11] = halfc[3];
  obj.points[12] = halfd[0];
  obj.points[13] = halfd[1];
  obj.points[14] = halfd[2];
  obj.points[15] = halfd[3];
  const objNew = {
    "id": getNewId(),
    "wide": parseInt((1 - t) * obj["wide"]),
    "fall": obj["fall"],
    "type": "plane",
    "points": [
      enda[0], enda[1], enda[2], enda[3],
      endb[0], endb[1], endb[2], endb[3],
      endc[0], endc[1], endc[2], endc[3],
      endd[0], endd[1], endd[2], endd[3]
    ],
  };
  draft.push(objNew);
  obj["wide"] *= t;
  sliceCurrentWide -= 1;
}
obj["wide"] = int(obj["wide"])

This slices the surface vertically that it's segments set by "wide" parameter. The "fall" is for curves that longing in vertical. Each slice should be sliced in horizontal if the surface needs to be sliced horizontally. I added the example code for only slicing in vertical.

/screenshots/split.png

Good luck playing with that.