我已经成功地实现了二次和三次贝塞尔曲线。它们非常简单,因为我们有一个公式。现在我想使用泛化表示 n 阶贝塞尔曲线:
在哪里
和
我正在使用位图库来呈现输出,所以这是我的代码:
// binomialCoef(n, k) = (factorial(n) / (factorial(k) * factorial(n- k)))
unsigned int binomialCoef(unsigned int n, const unsigned int k)
{
unsigned int r = 1;
if(k > n)
return 0;
for(unsigned int d = 1; d <= k; d++)
{
r *= n--;
r /= d;
}
return r;
}
void nBezierCurve(Bitmap* obj, const Point* p, const unsigned int nbPoint, float steps, const unsigned char red, const unsigned char green, const unsigned char blue)
{
int bx1 = p[0].x;
int by1 = p[0].y;
int bx2;
int by2;
steps = 1 / steps;
for(float i = 0; i < 1; i += steps)
{
bx2 = by2 = 0;
for(int j = 0; (unsigned int)j < nbPoint; j++)
{
bx2 += (int)(binomialCoef(nbPoint, j) * pow(1 - i, (float)nbPoint - j) * pow(i, j) * p[j].x);
by2 += (int)(binomialCoef(nbPoint, j) * pow(1 - i, (float)nbPoint - j) * pow(i, j) * p[j].y);
}
bresenhamLine(obj, bx1, by1, bx2, by2, red, green, blue);
bx1 = bx2;
by1 = by2;
}
// curve must end on the last anchor point
bresenhamLine(obj, bx1, by1, p[nbPoint - 1].x, p[nbPoint - 1].y, red, green, blue);
}
这是要渲染的一组点:Point ncurv[] = {
20, 200,
70, 300,
200, 400,
250, 200
};
这是输出:红色曲线是三次贝塞尔曲线。蓝色的应该是四阶贝塞尔,与三次贝塞尔相同,但在这种情况下,它们不一样?!
编辑:
我忘了注意左下点是 (0, 0)
最佳答案
你公式中的总和...
...从 0 到 n,即对于 n 阶贝塞尔曲线,您需要 n+1 点。
你有 4 个点,所以你正在绘制一个三阶贝塞尔曲线。
您的代码中的错误在这里:
for(int j = 0; (unsigned int)j < nbPoint; j++)
它应该是:
for(int j = 0; (unsigned int)j <= nbPoint; j++)
否则你只是从 0 迭代到 n-1。
编辑:
出于兴趣,您得到的形状与缺失的(第 5 个)点在 (0,0) 处相同,因为这是唯一对您的总和没有任何贡献的点...
关于c - n阶贝塞尔曲线?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15599766/