13

我已经设法实现了二次和三次贝塞尔曲线。它们非常简单,因为我们有一个公式。现在我想使用泛化来表示 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)

4

2 回答 2

5

你的公式中的总和......

在此处输入图像描述

...从 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)处相同,因为这是唯一对您的总和没有任何贡献的点......

第 5 个点在原点的 4 阶贝塞尔曲线

于 2013-03-24T15:49:39.713 回答
4

您正在尝试仅在四个点上构建四阶贝塞尔曲线。难怪它不起作用。

于 2013-03-24T14:54:55.527 回答