我想用C ++渲染贝塞尔曲线,所以我自己开始实现它。目前,它不一定非常有效。我的代码以某种方式产生接近结果,但这些曲线不准确。 (dvec2
是两个double值的向量。)
list<dvec2> bezier(list<dvec2> const &points, int resolution)
{
list<dvec2> samples;
double step = 1.0 / resolution;
for (double time = 0.0; time <= 1.0; time += step) {
list<dvec2> sliders = points;
while (sliders.size() > 1)
sliders = slide(sliders, time);
samples.push_back(sliders.front());
}
return samples;
}
list<dvec2> slide(list<dvec2> const &points, double time)
{
list<dvec2> result;
auto current = points.begin();
dvec2 last = *current;
for (++current; current != points.end(); ++current)
result.push_back(last * time + *current * (1.0 - time));
return result;
}
目前,我通过插入第一个和第二个来创建n-1个点,第二个用第三个插值,依此类推,基于时间t。然后,我通过相同的算法再次减少这个新的点集,直到我留下一个我可以绘制的点。我认为这种方法应该有效。
在渲染图像上,您可以在多条渲染曲线上看到算法结果。
例如,在图像的左下角,我认为两条相对的曲线应该是对称的。我的方向偏向于偏见。此外,那些完全封闭的曲线应至少在t = 0.5的中心画一个点。是什么造成的?
答案 0 :(得分:4)
你的方法应该有效。您进行了一些疏忽:在slide()
内,您不会在循环中更新last
。
尝试:
for (++current; current != points.end(); ++current) {
result.push_back(last * time + *current * (1.0 - time));
last = *current; // <--
}
请注意,通过获取这些产品的总和,可以给出对贝塞尔曲线的不同解释:
(资料来源:wikipedia)
某些术语与这些参数曲线相关联。我们有
其中多项式
被称为度 n 的Bernstein基多项式。
在这里,您需要(预先计算的)二项式系数,并且通过使用std::pow
函数,您最终得到一个循环而不是两个嵌套的循环(考虑 n 受限于在实践中不断,使预计算成为可能)。