我一直试图找到一种使用自定义函数绘制曲线/立方贝塞尔曲线的方法。但是,互联网上发现的所有例子都有所不同,通常产生不同的结果,为什么呢? 。我尝试的那些都没有产生与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)版本。
编辑:
最终目标,Windows(左侧)VS自定义功能。希望这在某种程度上有所帮助。
答案 0 :(得分:0)
因此,立方贝塞尔曲线是一条数学曲线。立方贝塞尔曲线是更一般曲线的特定情况。
立方贝塞尔曲线由4个控制点定义 - 起点和终点,以及2个控制点。通常,bezier有n个控制点。
该行被绘制为时间参数t
从0变为1.
要找出n
度t
的一般bezier的位置:
对于贝塞尔曲线中的每对相邻控制点,找到它们的加权平均值,由t
控制。因此at + b(1-t)
之前的控制点a
为b
。
使用这些n-1
点形成学位n-1
bezier。
在t
时解决新贝塞尔。
当你达到1
bezier度数时,停下来。这是你的观点。
尝试根据贝塞尔曲线的真实定义编写算法,并查看它与窗口曲线的不同之处。这可能不会比采取一些近似并且有两组错误来协调一样令人沮丧。