二次Bezier曲线
三次Bezier曲线
n次Bezier曲线
的函数
double B(int n,int i,float t){
int sum=1;
if(i==n||i==0) return pow(t,i)*pow(1-t,n-i);
int j;
for(j=n-i+1;j<=n;j++)
sum*=j;
for(j=1;j<=i;j++)
sum/=j;
return sum*pow(t,i)*pow(1-t,n-i);
}
主要步骤:
1.通过init()函数生成NUM_POINTS个控制顶点(NUM_POINTS在cpp文件开始的define处可以更改),并存入vec[]数组中
2.将控制顶点依次连线,之后标注各个控制顶点。
3.将vec[0]赋给p_current,由定义,将t由0逐渐增加至1,对于每一个t值,求出一个点保存至p,连接p,p_current画线,之后再将p赋给p_current。
代码如下:(也可以通过这个链接支付积分下载:https://download.csdn.net/download/qq_42276781/11081655)
#include
#include
#include
#include
#define NUM_POINTS 6//n次Bezier则修改NUM_POINTS为n+1
struct Point2{
double x;
double y;
Point2() { ; }
Point2(int px, int py) { x = px; y = py; }
void SetPoint2(int px, int py) { x = px; y = py; }
};
/*全局变量*/
Point2 vec[NUM_POINTS];//定义点数组
bool mouseLeftDown = false;//初始化鼠标状态
double B(int n,int i,float t){
int sum=1;
if(i==n||i==0) return pow(t,i)*pow(1-t,n-i);
int j;
for(j=n-i+1;j<=n;j++)
sum*=j;
for(j=1;j<=i;j++)
sum/=j;
return sum*pow(t,i)*pow(1-t,n-i);
}
Point2 setBezier(float t){
Point2 p;
p.x=0;
p.y=0;
/*三次Bezier各项系数
double a0=pow((1-t),3);
double a1=pow((1-t),2)*3*t;
double a2=3*t*t*(1-t);
double a3=t*t*t;
*/
//对于四个定点,给定t,得到p的坐标
//p.x=a0*p0.x+a1*p1.x+a2*p2.x+a3*p3.x;
//p.y=a0*p0.y+a1*p1.y+a2*p2.y+a3*p3.y;
for(int k=0;k<=NUM_POINTS;k++){
p.x+=vec[k].x*B(NUM_POINTS-1,k,t);
p.y+=vec[k].y*B(NUM_POINTS-1,k,t);
}
return p;
}
void setPoint(){//画点
glPointSize(10.0f);
glColor3f(0.0, 0.0, 1.0);//颜色蓝(三个参数分别为R G B
glBegin(GL_POINTS);
for(int b = 0;b < NUM_POINTS; b++)
glVertex2f(vec[b].x, vec[b].y);
glEnd();
}
void setLine(Point2 f,Point2 g){//画线
glLineWidth(1.5f);
glBegin(GL_LINE_STRIP);
glVertex2f(f.x,f.y);
glVertex2f(g.x,g.y);
glEnd();
}
void display(){
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
glColor3f(1.0,0.0,0.0);
for(int a=0;a
setPoint();
Point2 p_current=vec[0];
for(float c=0;c<=1;c+=0.05){
Point2 p=setBezier(c);
setLine(p_current,p);
//glFlush();
p_current=p;
}
glFlush();
glutSwapBuffers();
}
void init(){//初始化
glClearColor(1.0, 1.0, 1.0, 0.0);
glShadeModel(GL_FLAT);
for(int d=0;d
}
void reshape(int w, int h){
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, (GLsizei)w, (GLsizei)h, 0.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void mouse(int button, int state, int x, int y){
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
mouseLeftDown = true;
if (button == GLUT_LEFT_BUTTON && state == GLUT_UP)
mouseLeftDown = false;
}
double distance(int x1, int y1, int x2, int y2){
return sqrt((x1-x2) * (x1 -x2) + (y1-y2) * (y1-y2));
}
void motion(int x, int y){
if (mouseLeftDown){
for (int c = 0; c < NUM_POINTS; c++){
if (distance(vec[c].x, vec[c].y, x, y) < 20)
vec[c].SetPoint2(x, y);
}
}
glutPostRedisplay();
}
int main(int argc, char **argv){
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE);
glutInitWindowSize(600,600);
glutInitWindowPosition(100,100);
glutCreateWindow("Bezier");
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMouseFunc(mouse);
glutMotionFunc(motion);
glutMainLoop();
return 0;
}