我正在处理涉及Bezier曲线的个人项目。我已经看到许多实现单独处理二次曲线和三次曲线,但我希望创建一个更通用的算法,我可以通过增加和减少曲线的度数(顺序)来添加和删除控制点。
这不是我主要问题的一部分,但如果有人知道我可以看到的广义算法的例子,我将不胜感激,如果他们可以指出我的方向。
首先,我知道从低阶到高阶曲线的任何转换都是近似值,而不是等价的。我很满意计算和#34;足够接近"。
其次,我也明白从较高阶到较低阶曲线时,信息会丢失。这是不可避免的,因为高阶曲线有更多的弯曲"在曲线中,低阶曲线根本无法逼近。
我对这些限制很好,因为必须能够在曲线内添加和减去控制点以获得所需的功能。
我的第一个问题与大约5年前提出的问题有关: Convert quadratic curve to cubic curve
二次曲线有三(3)个控制点:
Vector3 Start;
Vector3 Control1;
Vector3 End;
转换为立方体我们引入了第四个控制点...
Vector3 Control2;
..."之间" Control1和End。然后我们相应地设置Control1和Control2:
Control2 = new Vector3(
End.x + ((2.0f / 3.0f) * (Control1.x - End.x)),
End.y + ((2.0f / 3.0f) * (Control1.y - End.y)),
End.z + ((2.0f / 3.0f) * (Control1.z - End.z))
);
Control1 = new Vector3(
Start.x + ((2.0f / 3.0f) * (Control1.x - Start.x)),
Start.y + ((2.0f / 3.0f) * (Control1.y - Start.y)),
Start.z + ((2.0f / 3.0f) * (Control1.z - Start.z))
);
我不确定这是否正确。在示例中,只有' x'组件已设置。我只是推断出' y'和' z'从中。如果这不正确,那么我很高兴知道什么是正确的。
此示例仅涵盖从二次曲线到三次曲线的转换。设置坐标时,控制值似乎是(2.0f / 3.0f)。那么,这是否意味着从立方到四次转换将是(2.0f / 4.0f)或(3.0f / 4.0f)或其他完全?对于任意曲线顺序,此转换的适当广义函数是什么?
我的项目也将使用样条线。我正在使用边对边方法来构造我的样条曲线,其中边被定义为从1(一条线)到n的任意有序曲线,其中控制点列表中的第一个和最后一个Vector3是起点和终点。边缘和连接边缘共享前一边缘的终点与下一个边缘的起点。
与贝塞尔曲线不同,我不添加和减去控制点。相反,我划分和组合边缘。将曲线细分为两条低阶曲线并且序数不低于2近似原始曲线的好方法是什么?同样,将两条曲线组合成单个高阶曲线的好方法是什么?
我意识到在一篇文章中要提出这个问题很多,但我认为最好将它放在一个主题中,而不是将其分开。
感谢您的帮助!
答案 0 :(得分:0)
您需要阅读http://pomax.github.io/bezierinfo/#reordering了解如何将曲线提升到更高的顺序,这几乎是微不足道的:
这可能看起来很可怕,但如果你真的看看这三个术语中的每一个是什么,那三个都是愚蠢的小学数学。您通常只需要新的权重,因此将这些权重生成为新的坐标列表绝对是微不足道的,并在大约一分钟内完成。在Javascript中:
function getOneHigher(x, y):
n = x.length;
k = n + 1;
s = n - 1;
let nx = [], ny =[];
nx[0] = x[0]; nx[n] = x[s];
ny[0] = y[0]; ny[n] = y[s];
for (let i=1; i<n; i++) {
nx[i] = (n*x[i] + i*x[i-1]) / k;
ny[i] = (n*y[i] + i*y[i-1]) / k;
}
return {nx, ny};
}
我们已经完成了。调用getOneHigher(x, y)
将为同一曲线产生两个新坐标数组,表示为比我们输入的高一度的Bezier曲线。注意,这意味着我们保持曲线坐标集为相同(字面意思:函数是相同的)同时减少每个坐标处的切线(因为导数不相同),有效地“减慢”沿着该曲线所经过的路径传播的任何东西。
您还可以在该部分中关注Sirver's Castle的链接,其中解释了how to do the lossy conversion down in a way that minimizes loss of information。这应该是多个问题:这是一个Q&amp; A网站,如果您没有提出具体问题,将来的访问者无法找到具体问题的答案,而是将一些技术上无关的问题合并在一个帖子中。