之前直接用基计算的Bezier曲线,现在用de Casteljau再次对其进行实现,其主要原因是目前本人对递归的理解非常的不深。。然后之后在CAGD中又要用到大量的递归算法,那么还是从最简单的开始
。。。搞了三个多小时。。终于搞定了,先上代码!
#include<GL/GLUT.H>
#include <windows.h>
#include <math.h>
#include <gl/GL.h>
GLfloat ctrlPoints[4][2] =
{
{ -0.8f, 0.1f }, {-0.4f, 0.6f }, { 0.2f, 0.8f }, { 0.7f, 0.2f }
};
void myDisplay(void){
glClear(GL_COLOR_BUFFER_BIT);
glPointSize(3);
glColor3f(1.0, 0.0, 0.0);
for (int i = 0; i < 4; i++){
glBegin(GL_POINTS);
glVertex2fv(&ctrlPoints[i][0]);
glEnd();
}
glColor3f(0.0, 0.0, 1.0);
glBegin(GL_LINE_STRIP);
for (int i = 0; i < 4; i++){
glVertex2fv(&ctrlPoints[i][0]);
}
glEnd();
float xarray[11];
float yarray[11];
int n = 4;//number
GLfloat ps[11][2];
int u = 0;
for(double t = 0.0;t<=1;t+=0.1)
{
for (int i = 1; i < n; ++i)
{
for (int j = 0; j < n - i; ++j)
{
if (i == 1) // i==1时,第一次迭代,由已知控制点计算
{
xarray[j] = ctrlPoints[j][0] * (1 - t) + ctrlPoints[j+1][0] * t;
yarray[j] = ctrlPoints[j][1] * (1 - t) + ctrlPoints[j + 1][1] * t;
continue;
}
// i != 1时,通过上一次迭代的结果计算
xarray[j] = xarray[j] * (1 - t) + xarray[j + 1] * t;
yarray[j] = yarray[j] * (1 - t) + yarray[j + 1] * t;
}
}
ps[u][0] = xarray[0];
ps[u][1] = yarray[0];
u++;
}
glColor3f(1.0, 1.0, 0.0);
glBegin(GL_LINE_STRIP);
for (int i = 0; i < 11; i++)
{
glVertex2fv(ps[i]);
}
glEnd();
glFlush();
}
int main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(100, 100);
glutInitWindowSize(400, 400);
glutCreateWindow("opengl1");
glutDisplayFunc(&myDisplay);
glutMainLoop();
return 0;
}
效果当然是帮帮哒,突然发现这样做有个非常明显的好处,就是不用计算Bezier曲线的基,直接套用递归法则就可以用其最重要的一段是
int n = 4;//number
float xarray[4];
float yarray[4];
GLfloat ps[11][2];
int u = 0;
for(double t = 0.0;t<=1;t+=0.1)
{
for (int i = 1; i < n; ++i)
{
for (int j = 0; j < n - i; ++j)
{
if (i == 1) // i==1时,第一次迭代,由已知控制点计算
{
xarray[j] = ctrlPoints[j][0] * (1 - t) + ctrlPoints[j+1][0] * t;
yarray[j] = ctrlPoints[j][1] * (1 - t) + ctrlPoints[j + 1][1] * t;
continue;
}
// i != 1时,通过上一次迭代的结果计算
xarray[j] = xarray[j] * (1 - t) + xarray[j + 1] * t;
yarray[j] = yarray[j] * (1 - t) + yarray[j + 1] * t;
}
}
ps[u][0] = xarray[0];
ps[u][1] = yarray[0];
u++;
}
充分体现了递归的算法如果是几次Bezier曲线,只需要把相对应的n的数以及xarray[]中的改成几就好了
早知道早学递归了。。。
http://www.cs.mtu.edu/~shene/COURSES/cs3621/NOTES/spline/Bezier/de-casteljau.html
这篇文章介绍的特别详细
Input: array P[0:n] of n+1 points and real number u in [0,1]
Output: point on curve, C(u)
Working: point array Q[0:n]
for i := 0 to n do
Q[i] := P[i]; // save input
for k := 1 to n do
for i := 0 to n - k do
Q[i] := (1 - u)Q[i] + u Q[i + 1];
return Q[0];
这是伪代码。最后贴上效果