Bezier曲线生成【计算机图形学】

原理:

Bezier曲线是通过一组多边形折线的顶点来定义的。如果折线的顶点固定不变,则由其定义的Bezier曲线是唯一的。在折线的各顶点中,只有第一点和最后一点在曲线上且作为曲线的起始处和终止处,其他的点用于控制曲线的形状及阶次。曲线的形状趋向于多边形折线的形状,要修改曲线,只要修改折线的各顶点就可以了。因此,多边形折线又称Bezier曲线的控制多边形,其顶点称为控制点。

三次多项式,有四个控制点,其数学表示如下:

#include <GL/glut.h>

#include <stdio.h>

#include <stdlib.h>

#include <vector>

using namespace std;

struct Point {

       int x, y;

};

Point pt[4], bz[11];

vector<Point> vpt;

bool bDraw;

int nInput;

void CalcBZPoints()

{

       float a0,a1,a2,a3,b0,b1,b2,b3;

       a0=pt[0].x;

       a1=-3*pt[0].x+3*pt[1].x;

       a2=3*pt[0].x-6*pt[1].x+3*pt[2].x;

       a3=-pt[0].x+3*pt[1].x-3*pt[2].x+pt[3].x;

       b0=pt[0].y;

       b1=-3*pt[0].y+3*pt[1].y;

       b2=3*pt[0].y-6*pt[1].y+3*pt[2].y;

       b3=-pt[0].y+3*pt[1].y-3*pt[2].y+pt[3].y;

       float t = 0;

       float dt = 0.01;

       for(int i = 0; t<1.1; t+=0.1, i++)

       {

              bz[i].x = a0+a1*t+a2*t*t+a3*t*t*t;

              bz[i].y = b0+b1*t+b2*t*t+b3*t*t*t;           

       }

}

void ControlPoint(vector<Point> vpt)//画点函数

{

       glPointSize(5);//点的粗细

       for(int i=0; i<vpt.size(); i++)

       {

              glBegin (GL_POINTS);
			  

              glColor3f (1.0f, 0.0f, 0.0f);   glVertex2i (vpt[i].x,vpt[i].y);
			  
              glEnd ();

       }

}

void PolylineGL(Point *pt, int num)//连线函数

{

       glBegin (GL_LINE_STRIP);

       for(int i=0;i<num;i++)

       {           

              glColor3f (1.0f, 1.0f, 0.0f);//线的颜色
		

              glVertex2i (pt[i].x,pt[i].y);           

       }

       glEnd ();

}

void myDisplay()

{

       glClear(GL_COLOR_BUFFER_BIT);//清屏

       glColor3f (1.0f, 1.0f, 1.0f);//线的颜色为白色
	   glPointSize(5);//点的宽度

       if (vpt.size() > 0) {

              ControlPoint(vpt);

       }

       if(bDraw)

       {

              PolylineGL(pt, 4);//画连接点的三条直线

             CalcBZPoints();

              PolylineGL(bz, 11);//画曲线

       }

       glFlush();

}

void Init()//初始化

{

       glClearColor(0.0, 0.0, 0.0, 0.0);

       glShadeModel(GL_SMOOTH);

       printf("Please Click left button of mouse to input control point of Bezier Curve!\n");

}

void Reshape(int w, int h)

{

       glViewport(0, 0, (GLsizei) w, (GLsizei) h);

       glMatrixMode(GL_PROJECTION);

       glLoadIdentity();

       gluOrtho2D(0.0, (GLdouble) w, 0.0, (GLdouble) h);

}

void mouse(int button, int state, int x, int y)//鼠标控制四个控制点

{

       switch (button)

       {

       case GLUT_LEFT_BUTTON:

              if (state == GLUT_DOWN)

              {

                     if (nInput == 0)

                     {

                            pt[0].x = x;

                            pt[0].y = 480 - y;

                            nInput = 1;

                            vpt.clear();

                            vpt.push_back(pt[0]);

                            bDraw = false;

                            glutPostRedisplay();//

                     }

                     else if (nInput == 1)

                     {

                            pt[1].x = x;

                            pt[1].y = 480 - y;

                            vpt.push_back(pt[1]);

                            nInput = 2;

                            glutPostRedisplay();//

                     }    

                     else if (nInput == 2)

                     {

                            pt[2].x = x;

                            pt[2].y = 480 - y;

                            vpt.push_back(pt[2]);

                            nInput = 3;

                            glutPostRedisplay();//

                     }

                     else if (nInput == 3)

                     {

                            pt[3].x = x;

                            pt[3].y = 480 - y;

                            bDraw = true;

                            vpt.push_back(pt[3]);

                            nInput = 0;

                            glutPostRedisplay();//

                     }

              }

              break;

       default:

              break;

       }

}

int main(int argc, char *argv[])

{

       glutInit(&argc, argv);

       glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);

       glutInitWindowPosition(100, 100);

       glutInitWindowSize(640, 480);

       glutCreateWindow("Hello World!");

       Init();

       glutDisplayFunc(myDisplay);

       glutReshapeFunc(Reshape);

       glutMouseFunc(mouse);

       glutMainLoop();

       return 0;

}

 

  • 3
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值