OPENGL (DDA、Hermite、Bezie…

1、DDA直线:(两点确定一条曲线,即用鼠标点两点;下同)
  #include <windows.h>
  #include <gl/glut.h>
  #include <gl/gl.h>
  #include <stdio.h>
#include <math.h>
  GLfloat x_coord[2], y_coord[2];
  int nPoints = 0;
  inline GLfloat x_convert (int x)
  {
  return -8.0+x/499.0*16;
  }
  inline GLfloat y_convert (int y)
  {
  return 8.0 - y/499.0*16;
  }
  void init(){
    glClearColor(1,1,1,0);
  }
  void myReshape(int w,int h)
  {
  glViewport(0,0,(GLsizei)w,(GLsizei)h);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  //gluPerspective(45.0,(GLfloat)w/(GLfloat)h,1.0,50.0);
  if(w<=h)
  glOrtho(-8.0,8.0,-8.0*(GLfloat)h/(GLfloat)w,8.0*(GLfloat)h/(GLfloat)w,-8.0,8.0);
  else
  glOrtho(-8.0*(GLfloat)h/(GLfloat)w,8.0*(GLfloat)h/(GLfloat)w,-8.0,8.0,-8.0,8.0);
 
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  }
  int round ( float a){
    return int (a+0.5);
  }
  void DDA(int x0,int xEnd,int y0, int yEnd)   //DDA画线算法
  {
      int dx= xEnd - x0 ;
      int dy= yEnd - y0 ;
      int steps ;
      float xIncrement , yIncrement , x=x0, y=y0;
      if(fabs(dx) > fabs(dy) )
    steps = fabs (dx);
      else steps = fabs(dy);
 
      xIncrement = (float) dx/steps;
      yIncrement = (float) dy/steps;
 
      glBegin(GL_POINTS);
      glPointSize(100);
      glVertex2i( round (x), round (y));
      for(int i=0; i
        x+=xIncrement;
    y+=yIncrement;
    glVertex2i( round (x), round (y));
      }
      glEnd();
  }
  void display(){
      glClear(GL_COLOR_BUFFER_BIT);
 
          glColor3f(0,1,0);                 //画两点之间的直线
    glBegin(GL_LINE_STRIP);
    for (int i = 0; i < nPoints; i++)
  glVertex3f (x_coord[i], y_coord[i], 0.0);
    glEnd();
 
        glColor3f (1.0, 0, 0);             //调用DDA画线算法
    glPointSize(5);
      if (nPoints == 2)
  DDA(x_coord[0],x_coord[1], y_coord[0] , y_coord[1]);
 
  glFlush();
 
  }
  void handle_mouseclick (int button, int state, int x, int y){
  if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
  if (nPoints == 2) nPoints = 0;
 
  printf("%d (%d, %d) ==> (%f, %f)\n", nPoints, x, y, x_convert(x), y_convert(y));
 
  x_coord[nPoints] = x_convert(x);
  y_coord[nPoints] = y_convert(y);
  nPoints++;
  glutPostRedisplay();
  }
  }
  int main(int argc, char** argv)
  {
      glutInit(&argc, argv);
      glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB |GLUT_DEPTH);
      glutInitWindowSize (500, 500);
      glutInitWindowPosition (100, 100);
      glutCreateWindow ("hello");
      init ();
      glutDisplayFunc( display );
      glutReshapeFunc(myReshape);
      glutMouseFunc(handle_mouseclick);
      glutMainLoop();
      return 0;
  }
 
===========================================================
2、Bezier曲线(三次:四点确定一条曲线)
  #include <windows.h>
  #include <gl/glut.h>
  #include <gl/gl.h>
  #include <stdio.h>
#include <math.h>
  GLfloat x_coord[4], y_coord[4];
  int nPoints = 0;
 
  inline GLfloat x_convert (int x)
  {
  return -5.0+x/249.0*10;
  }
 
  inline GLfloat y_convert (int y)
  {
  return 5.0 - y/249.0*10;
  }
 
  void init(){
    glClearColor(1,1,1,0);
 
  }
  void myReshape(int w,int h)
  {
  glViewport(0,0,(GLsizei)w,(GLsizei)h);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  //gluPerspective(45.0,(GLfloat)w/(GLfloat)h,1.0,50.0);
  if(w<=h)
  glOrtho(-5.0,5.0,-5.0*(GLfloat)h/(GLfloat)w,5.0*(GLfloat)h/(GLfloat)w,-5.0,5.0);
  else
  glOrtho(-5.0*(GLfloat)h/(GLfloat)w,5.0*(GLfloat)h/(GLfloat)w,-5.0,5.0,-5.0,5.0);
 
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  }
 
  //P(t)= B0,3(t)P0 + B1,3(t)P1+ B2,3(t)P2﹢B3,3(t)P3
    //   B0,3(t)﹦(1-t)3
    // B1,3(t)﹦3t(1-t)2
      //B2,3(t)﹦3t2(1-t)
      //B3,3(t)﹦t3
 
  void Bezier(int n)   //Bezier曲线
  {
      float t, dt, t2, t3, f1, f2, f3, f4;
 
      dt = 1.0/n;       // t runs from 0 to 1.
 
      glBegin(GL_LINE_STRIP);
  for (t = 0.0; t <= 1.0; t += dt) {
          t2 = (1-t) *(1- t);
          t3 = t2 * (1-t);       // t3 =(1-t)*(1-t)*(1-t)
 
          f1 = t3;
          f2 = 3*t*t2;
          f3 = 3*t*t*(1-t);
          f4 = t*t*t;
 
          glVertex2f( f1*x_coord[0] + f2*x_coord[1] + f3*x_coord[2] + f4*x_coord[3],
                          f1*y_coord[0] + f2*y_coord[1] + f3*y_coord[2] + f4*y_coord[3]);
      }
      glEnd();
  }
  void display(){
      glClear(GL_COLOR_BUFFER_BIT);
 
          glColor3f (1, 0, 0);
    glBegin(GL_LINE_STRIP);
    for (int i = 0; i < nPoints; i++)
  glVertex3f (x_coord[i], y_coord[i], 0.0);
    glEnd();
 
          glColor3f (0, 1, 0);
      if (nPoints == 4)
  Bezier(20);
 
  glFlush();
 
  }
 
  void handle_mouseclick (int button, int state, int x, int y)
  {
  if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
  if (nPoints == 4) nPoints = 0;
 
  printf("%d (%d, %d) ==> (%f, %f)\n", nPoints, x, y, x_convert(x), y_convert(y));
 
  x_coord[nPoints] = x_convert(x);
  y_coord[nPoints] = y_convert(y);
  nPoints++;
  glutPostRedisplay();
  }
  }
  int   main(int argc, char** argv)
  {
    glutInit(&argc, argv);
    glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB |GLUT_DEPTH);
    glutInitWindowSize (250, 250);
    glutInitWindowPosition (100, 100);
    glutCreateWindow ("hello");
    init ();
 
    glutDisplayFunc( display );
      glutReshapeFunc(myReshape);
    glutMouseFunc(handle_mouseclick);
 
    glutMainLoop();
    return 0;
  }
  =========================================
3、Hermit曲线(三次,三点确定一条曲线)

  #include <windows.h>
  #include <gl/glut.h>
  #include <gl/gl.h>
  #include <stdio.h>
#include <math.h>
  GLfloat x_coord[3], y_coord[3];
  int nPoints = 0;
  inline GLfloat x_convert (int x)
  {
  return -8.0+x/499.0*16;
  }
  inline GLfloat y_convert (int y)
  {
  return 8.0 - y/499.0*16;
  }
  void init(){
    glClearColor(1,1,1,0);
  }
  void myReshape(int w,int h)
  {
  glViewport(0,0,(GLsizei)w,(GLsizei)h);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  //gluPerspective(45.0,(GLfloat)w/(GLfloat)h,1.0,50.0);
  if(w<=h)
  glOrtho(-8.0,8.0,-8.0*(GLfloat)h/(GLfloat)w,8.0*(GLfloat)h/(GLfloat)w,-8.0,8.0);
  else
  glOrtho(-8.0*(GLfloat)h/(GLfloat)w,8.0*(GLfloat)h/(GLfloat)w,-8.0,8.0,-8.0,8.0);
 
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  }
 
  void Hermit(int n)   //
  {
    float t, dt, t2, t3, f1, f2, f3, f4;
 
      dt = 1.0/n;       // t runs from 0 to 1.
      GLfloat PT0_x = x_coord[1] - x_coord[0];
      GLfloat PT0_y = y_coord[1] - y_coord[0];
      GLfloat PT1_x = x_coord[2] - x_coord[1];
  GLfloat PT1_y = y_coord[2] - y_coord[1];
      glBegin(GL_LINE_STRIP);
  for (t = 0.0; t <= 1.0; t += dt) {
          t2 = t * t;
          t3 = t2 * t;       // t3 = t * t * t
          f1 = 2.0*t3 - 3.0*t2 + 1.0;
          f2 = -2.0*t3 + 3.0*t2;
          f3 = t3 - 2.0*t2 + t;
          f4 = t3 - t2;
          glVertex2f( f1*x_coord[0] + f2*x_coord[2] + f3*PT0_x + f4*PT1_x,
                          f1*y_coord[0] + f2*y_coord[2] + f3*PT0_y + f4*PT1_y );
      }
      glEnd();
  }
  void display(){
      glClear(GL_COLOR_BUFFER_BIT);
 
          glColor3f(0,1,0);                 //画两点之间的直线
    glBegin(GL_LINE_STRIP);
    for (int i = 0; i < nPoints; i++)
  glVertex3f (x_coord[i], y_coord[i], 0.0);
    glEnd();
 
        glColor3f (1.0, 0, 0);             //调用DDA画线算法
      if (nPoints == 3)
  Hermit(20);
 
  glFlush();
 
  }
  void handle_mouseclick (int button, int state, int x, int y){
  if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
  if (nPoints == 3) nPoints = 0;
 
  printf("%d (%d, %d) ==> (%f, %f)\n", nPoints, x, y, x_convert(x), y_convert(y));
 
  x_coord[nPoints] = x_convert(x);
  y_coord[nPoints] = y_convert(y);
  nPoints++;
  glutPostRedisplay();
  }
  }
  int main(int argc, char** argv)
  {
      glutInit(&argc, argv);
      glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB |GLUT_DEPTH);
      glutInitWindowSize (500, 500);
      glutInitWindowPosition (100, 100);
      glutCreateWindow ("hello");
      init ();
      glutDisplayFunc( display );
      glutReshapeFunc(myReshape);
      glutMouseFunc(handle_mouseclick);
      glutMainLoop();
      return 0;
  }
  ======================================
4、B样条曲线(实现鼠标右键在屏幕中选点,左键可拖动点)(三次,四点确定一条曲线)
  #include <windows.h>
  #include <gl/glut.h>
  #include <gl/gl.h>
  #include <stdio.h>
#include <math.h>
  GLfloat x_coord[100], y_coord[100];
 
  int nPoints = 0;
 
  int j=0;
 
  inline GLfloat x_convert (int x)
  {
  return -5.0+x/249.0*10;
  }
 
  inline GLfloat y_convert (int y)
  {
  return 5.0 - y/249.0*10;
  }
 
  void init(){
    glClearColor(1,1,1,0);
 
  }
  void myReshape(int w,int h)
  {
  glViewport(0,0,(GLsizei)w,(GLsizei)h);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  //gluPerspective(45.0,(GLfloat)w/(GLfloat)h,1.0,50.0);
  if(w<=h)
  glOrtho(-5.0,5.0,-5.0*(GLfloat)h/(GLfloat)w,5.0*(GLfloat)h/(GLfloat)w,-5.0,5.0);
  else
  glOrtho(-5.0*(GLfloat)h/(GLfloat)w,5.0*(GLfloat)h/(GLfloat)w,-5.0,5.0,-5.0,5.0);
 
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  }
 
  //   (1/2)*(t-1)*(t-1)
  //   (1/2)*(-2*t*t+2*t+1)
  //   (1/2)*t*t
 
  void B2(int n)   //B样条3次曲线
  {
      float t, dt, t2, t3, f1, f2, f3, f4;
 
      dt = 1.0/n;       // t runs from 0 to 1.
 
      glBegin(GL_LINE_STRIP);
 
  for(int j=0; j< (nPoints - 2 ); j++ )
  for (t = 0.0; t <= 1.0; t += dt) {
 
          f1 = (1.0/6)*((-1)*t*t*t+3*t*t-3*t+1);
          f2 = (1.0/6)*(3*t*t*t-6*t*t+4);
          f3 = (1.0/6)*((-3)*t*t*t+3*t*t +3*t +1);
  f4= (1.0/6)*(t*t*t);
 
          glVertex2f( f1*x_coord[j] + f2*x_coord[j+1] + f3*x_coord[j+2]+ f4*x_coord[j+3],
                          f1*y_coord[j] + f2*y_coord[j+1] + f3*y_coord[j+2] + f4*y_coord[j+3]);
      }
      glEnd();
  }
 
  void display(){
      glClear(GL_COLOR_BUFFER_BIT);
 
    glBegin(GL_LINE_STRIP);
        glColor3f (0, 1, 0);
    for (int i = 0; i < nPoints; i++) {
  glVertex3f (x_coord[i], y_coord[i], 0.0);
    }
    glEnd();
 
  glColor3f (1.0, 0, 0);
  if (nPoints >=4)   {
  B2(20);
    }
  glFlush();
 
  }
 
  void handle_mouseclick (int button, int state, int x, int y)
  {
  if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN) {
 
  if( nPoints >=4 )   j++;
 
  printf("%d (%d, %d) ==> (%f, %f)\n", nPoints, x, y, x_convert(x), y_convert(y));
 
  x_coord[nPoints] = x_convert(x);
  y_coord[nPoints] = y_convert(y);
 
  nPoints++;
 
  glutPostRedisplay();
  }
  }
 
  void mousemotion(int x, int y) {
  float min =99999999;
  int index;
  x = x_convert(x);
          y = y_convert(y);
  int i ;
  for(i=0; i
  if(min > (x-x_coord[i])*(x-x_coord[i]) + (y-y_coord[i])*(y-y_coord[i]) ){
  min=(x-x_coord[i])*(x-x_coord[i]) + (y-y_coord[i])*(y-y_coord[i]) ;
  index=i;
  }
  x_coord[index] = x;
  y_coord[index] = y;
 
  glutPostRedisplay();
  }
 
  int main(int argc, char** argv)
  {
    glutInit(&argc, argv);
    glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB |GLUT_DEPTH);
    glutInitWindowSize (250, 250);
    glutInitWindowPosition (100, 100);
    glutCreateWindow ("hello");
    init ();
 
    glutDisplayFunc( display );
      glutReshapeFunc(myReshape);
    glutMouseFunc(handle_mouseclick);
    glutMotionFunc(mousemotion);
 
    glutMainLoop();
    return 0;
  }
 
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值