作者热门文章
- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我想在 C++ 中渲染贝塞尔曲线,所以我开始自己实现它。目前,它不必非常高效。我的代码以某种方式产生了接近的结果,但这些曲线并不准确。 (dvec2
是两个 double 值的 vector 。)
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;
}
目前,我根据时间 t 将第一个插值到第二个,第二个插值到第三个,依此类推,从曲线创建 n-1 个点。然后,我通过相同的算法再次减少这组新的点,直到我剩下一个可以绘制的点。我认为这种方法应该有效。
在渲染图像上,您可以看到算法在几条渲染曲线上的结果。
例如,在图像的左下角,我认为两条相对的曲线应该是对称的。我的方向有偏差。此外,那些完全封闭的曲线至少应该在t=0.5的中心画一个点。是什么原因造成的?
最佳答案
您的方法应该有效。您犯了一个小疏忽:在 slide()
中,您没有更新循环中的 last
。
尝试:
for (++current; current != points.end(); ++current) {
result.push_back(last * time + *current * (1.0 - time));
last = *current; // <--
}
请注意,可以通过对这些乘积求和来给出对贝塞尔曲线的不同解释:
(Source: wikipedia)
Some terminology is associated with these parametric curves. We have
where the polynomials
are known as Bernstein basis polynomials of degree n.
在这里,您需要(预先计算的)二项式系数,并且通过使用 std::pow
函数,您最终得到一个循环而不是两个嵌套循环(考虑 n 在实践中受到一个常数的限制,使预计算成为可能)。
关于c++ - 为什么我的贝塞尔曲线实现有偏差?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27444140/
我是一名优秀的程序员,十分优秀!