为什么Cubic Bezier的功能与windows api PolyBezier相比还不准确?

时间:2014-09-26 22:53:47

标签: c++ graphics bezier

我一直试图找到一种使用自定义函数绘制曲线/立方贝塞尔曲线的方法。但是,互联网上发现的所有例子都有所不同,通常产生不同的结果,为什么呢? 。我尝试的那些都没有产生与windows api PolyBezier相同的结果,这是我需要的。

这是我目前绘制立方贝塞尔曲线的代码:

double Factorial(int number)
{
    double factorial = 1;

    if (number > 1)
    {
        for (int count = 1; count <= number; count++) factorial = factorial * count;
    }

    return factorial;
}

double choose(double a, double b)
{
    return Factorial(a) / (Factorial(b) * Factorial(a - b));
}

VOID MyPolyBezier(HDC hdc, PPOINT Pts, int Total)
{
    float x, y;

    MoveToEx(hdc, Pts[0].x, Pts[0].y, 0);

    Total -= 1;

    //for (float t = 0; t <= 1; t += (1./128.))
    for (float t = 0; t <= 1; t += 0.0078125)
    {
        x = 0;
        y = 0;
        for (int I = 0; I <= Total; I++)
        {
            x += Pts[I].x * choose(Total, I) * pow(1 - t, Total - I) * pow(t, I);
            y += Pts[I].y * choose(Total, I) * pow(1 - t, Total - I) * pow(t, I);
        }
        LineTo(hdc, x, y);
    }
}

以下是测试它的代码。

POINT TestPts[4];
BYTE TestType[4] = {PT_MOVETO, PT_BEZIERTO, PT_BEZIERTO, PT_BEZIERTO};
//set x, y points for the curved line.
TestPts[0].x = 50;
TestPts[0].y = 200;
TestPts[1].x = 100;
TestPts[1].y = 100;
TestPts[2].x = 150;
TestPts[2].y = 200;
TestPts[3].x = 200;
TestPts[3].y = 200;
//Draw using custom function.
MyPolyBezier(hdc, TestPts, 4);
//Move the curve down some.
TestPts[0].y += 10;
TestPts[1].y += 10;
TestPts[2].y += 10;
TestPts[3].y += 10;
//Draw using windows api.
//PolyDraw(hdc, TestPts, TestType, 4); //PolyDraw gives the same result as PolyBezier.
PolyBezier(hdc, TestPts, 4);

附上我不良结果的图片: 注意:底部bezier线是windows(PolyBezier)版本。

Custom cubic bezier function vs windows PolyBezier

编辑: 最终目标,Windows(左侧)VS自定义功能。希望这在某种程度上有所帮助。 Windows Vs Custom PolyBezier

1 个答案:

答案 0 :(得分:0)

因此,立方贝塞尔曲线是一条数学曲线。立方贝塞尔曲线是更一般曲线的特定情况。

立方贝塞尔曲线由4个控制点定义 - 起点和终点,以及2个控制点。通常,bezier有n个控制点。

该行被绘制为时间参数t从0变为1.

要找出nt的一般bezier的位置:

  • 对于贝塞尔曲线中的每对相邻控制点,找到它们的加权平均值,由t控制。因此at + b(1-t)之前的控制点ab

  • 使用这些n-1点形成学位n-1 bezier。

  • t时解决新贝塞尔。

当你达到1 bezier度数时,停下来。这是你的观点。

尝试根据贝塞尔曲线的真实定义编写算法,并查看它与窗口曲线的不同之处。这可能不会比采取一些近似并且有两组错误来协调一样令人沮丧。