001. #include <math.h>
002. #include <gl/glut.h>
003. #include <iostream>
004. using namespace std;
005.
006. #define NUM_POINTS 6
007. #define NUM_SEGMENTS (NUM_POINTS-3)
008.
009. struct Point2
010. {
011. double x;
012. double y;
013.
014. Point2() { ; }
015. Point2( int px, int py) { x = px; y = py; }
016. void SetPoint2( int px, int py) { x = px; y = py; }
017. };
018.
019. /*全局变量*/
020. Point2 vec[NUM_POINTS];
021. bool mouseLeftDown = false ;
022.
023. /*绘制B样条曲线*/
024. void Bspline( int n)
025. {
026. float f1, f2, f3, f4;
027. float deltaT = 1.0 / n;
028. float T;
029.
030. glBegin(GL_LINE_STRIP);
031. for ( int num = 0; num < NUM_SEGMENTS; num++)
032. {
033. for ( int i = 0; i <= n; i++) {
034.
035. T = i * deltaT;
036.
037. f1 = (-T*T*T + 3*T*T - 3*T + 1) / 6.0;
038. f2 =(3*T*T*T - 6*T*T + 4) / 6.0;
039. f3 = (-3*T*T*T +3*T*T + 3*T + 1) / 6.0;
040. f4 = (T*T*T) / 6.0;
041.
042. glVertex2f( f1*vec[num].x + f2*vec[num+1].x + f3*vec[num+2].x + f4*vec[num+3].x,
043. f1*vec[num].y + f2*vec[num+1].y + f3*vec[num+2].y + f4*vec[num+3].y);
044. }
045. }
046.
047. glEnd();
048. }
049.
050.
051. void display()
052. {
053. glClear(GL_COLOR_BUFFER_BIT);
054. glLoadIdentity();
055.
056. glLineWidth(1.5f);
057. glColor3f(1.0,0.0,0.0);
058. glBegin(GL_LINE_STRIP);
059. for ( int i = 0;i < NUM_POINTS; i++)
060. {
061. glVertex2f(vec[i].x, vec[i].y);
062. }
063. glEnd();
064.
065. glPointSize(10.0f);
066. glColor3f(0.0, 0.0, 1.0);
067. glBegin(GL_POINTS);
068. for ( int i = 0;i < NUM_POINTS; i++)
069. {
070. glVertex2f(vec[i].x, vec[i].y);
071. }
072. glEnd();
073.
074. Bspline(20);
075.
076. glFlush();
077. glutSwapBuffers();
078. }
079.
080. void init()
081. {
082. glClearColor(1.0, 1.0, 1.0, 0.0);
083. glShadeModel(GL_FLAT);
084.
085. vec[0].SetPoint2(200, 400);
086. vec[1].SetPoint2(100, 300);
087. vec[2].SetPoint2(200, 200);
088. vec[3].SetPoint2(250, 300);
089. vec[4].SetPoint2(400, 200);
090. vec[5].SetPoint2(400, 400);
091. }
092.
093. void reshape( int w, int h)
094. {
095. glViewport(0, 0, (GLsizei)w, (GLsizei)h);
096. glMatrixMode(GL_PROJECTION);
097. glLoadIdentity();
098. gluOrtho2D(0.0, (GLsizei)w, (GLsizei)h, 0.0);
099. glMatrixMode(GL_MODELVIEW);
100. glLoadIdentity();
101. }
102.
103. void mouse( int button, int state, int x, int y)
104. {
105. if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
106. {
107. mouseLeftDown = true ;
108. }
109.
110. if (button == GLUT_LEFT_BUTTON && state == GLUT_UP)
111. {
112. mouseLeftDown = false ;
113. }
114. }
115.
116. double distance( int x1, int y1, int x2, int y2)
117. {
118. return sqrt ((x1-x2) * (x1 -x2) + (y1-y2) * (y1-y2));
119. }
120.
121. void motion( int x, int y)
122. {
123. if (mouseLeftDown)
124. {
125. for ( int i = 0; i < NUM_POINTS; i++)
126. {
127. if (distance(vec[i].x, vec[i].y, x, y) < 20)
128. {
129. vec[i].SetPoint2(x, y);
130. }
131. }
132. }
133.
134. glutPostRedisplay();
135. }
136.
137. int main( int argc, char ** argv)
138. {
139. glutInit(&argc,argv);
140. glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE);
141. glutInitWindowSize(500, 500);
142. glutInitWindowPosition (200, 200);
143. glutCreateWindow( 'B-Spline Curve' );
144. init();
145.
146. glutDisplayFunc(display);
147. glutReshapeFunc(reshape);
148. glutMouseFunc(mouse);
149. glutMotionFunc(motion);
150. glutMainLoop();
151.
152. return 0;
153.
154. }
|