贝塞尔曲面切片
Slicing Bezier Surfaces

原始链接: https://fatih-erikli-potato.github.io/blog/slicing-bezier-surfaces.html

这段文字描述了一种在基于Javascript的曲面编辑软件中切割贝塞尔曲面的方法。核心功能在于`splitBezier`函数,它在指定参数`t`处将贝塞尔曲线分割成两条曲线,保持原始形状。这允许选择性地移除或操作曲面部分。 代码演示了迭代切割由控制点定义的曲面。一个`while`循环根据“wide”参数重复水平分割曲面,从每次分割的“末端”部分创建新的曲面片段(`objNew`)。原始曲面的“wide”参数在每次切割时进行调整,有效地减小其尺寸。 “fall”参数控制垂直切割,表明该方法可以应用于两个维度。这个过程通过将复杂形状分解为可管理、可单独修改的部分,从而实现精细的曲面编辑。

黑客新闻 新 | 过去 | 评论 | 提问 | 展示 | 招聘 | 提交 登录 切片贝塞尔曲面 (fatih-erikli-potato.github.io) 7 分,来自 fatih-erikli-cg 2 小时前 | 隐藏 | 过去 | 收藏 | 讨论 帮助 指南 | 常见问题 | 列表 | API | 安全 | 法律 | 申请YC | 联系 搜索:
相关文章

原文

It is possible to split a bezier surface into two pieces. It helps us to slice a surface into several pieces without losing the original shape. In that way we are able to delete 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 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 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": [] 
}
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 horizontally that it's segments set by "wide" parameter. The "fall" is for the vertical. Same method must be applied the surface if it needs to be sliced horizontally.

Good luck playing with that.

联系我们 contact @ memedata.com