OpenGL: B 라인 그리 기

14854 단어 OpenGL
http://blog.csdn.net/yangtrees/article/details/9026411
B 개의 곡선 그리 기:
OpenGL: 绘制B样条曲线_第1张图片
#include 

#include 
#pragma comment(lib,"glut32.lib")

//

#if 0
// the points of the curve - these are the same as the bezier curve
// points demonstrated in the bezier curve example.

float Points[4][3] = {
	{ 10,10,0 },
	{  5,10,2 },
	{ -5,0,0 },
	{-10,5,-2}
};

#define NUM_POINTS 4

//	The following sets of 4 indices are the curves that need to
//	be drawn to create a clamped cubic b-spline. In total there
//	are 5 curve segments to draw.
//
//	0 0 0 1
//    0 0 1 2
//      0 1 2 3
//        1 2 3 3
//          2 3 3 3
//
//	Remember this when trying to understand knot vectors!!
//

#else

float Points[9][3] = {
	{ 10,5,0 },
	{  5,10,0 },
	{ -5,15,0 },
	{ -10,-5,0 },
	{ 4,-4,0 },
	{ 10,5,0 },
	{  5,10,0 },
	{ -5,15,0 },
	{ -10,-5,0 }
};

#define NUM_POINTS 9

//若绘制过首尾控制点的曲线  
//	0 0 0 1
//	0 0 1 2
//	0 1 2 3
//	1 2 3 4
//	2 3 4 5
//	3 4 5 6
//	4 5 6 6
//	5 6 6 6
//
//	Remember this when trying to understand knot vectors!!
//
//若绘制首尾相接的平滑曲线 ,即为当前绘制
//	0 1 2 3
//	1 2 3 4
//	2 3 4 5
//	3 4 5 6
#endif

// the level of detail for the curve
unsigned int LOD=20;

#define NUM_SEGMENTS (NUM_POINTS-3)
//

float* GetPoint(int i) 
{
	// return 1st point
	if (i<0) 
	{
		return	Points[0];
	}

	if (i

closed - B 스타일:
OpenGL: 绘制B样条曲线_第2张图片
Reference:
B 조 상세 설명:
http://blog.csdn.net/tuqu/article/details/5366701
closed - B 라인 그리 기:
http://blog.csdn.net/tuqu/article/details/5386215
OpenGL 은 DDA, Hermite, Bezier, B 를 그립 니 다.
http://blog.163.com/zhou_ghui/blog/static/177580120132159441827/
< 1 > DDA 직선: (두 점 에서 한 곡선 을 정 하고 마우스 로 두 점 을 클릭);
#include 
#include 
#include 

#include 
#pragma comment(lib,"glut32.lib")

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画线算法
{
	float dx= xEnd - x0 ;
	float 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 < steps; 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)
", 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 곡선 (3 회: 4 시 에 한 곡선 확정)
 #include 
 #include 
 #include 
 #include 
 #include 
 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)
", 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 
 #include 
 #include 
 #include 
 #include 
  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)
", 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 #include #include
#include #pragma comment(lib,"glut32.lib")
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)", 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 (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; }

좋은 웹페이지 즐겨찾기