1.实验目的:
了解曲线的生成原理,掌握几种常见的曲线生成算法,利用VC+OpenGL实现Bezier曲线生成算法。
2.实验内容:
(1) 结合示范代码了解曲线生成原理与算法实现,尤其是Bezier曲线;
(2) 调试、编译、修改示范程序。
3.实验原理:
Bezier曲线是通过一组多边形折线的顶点来定义的。如果折线的顶点固定不变,则由其定义的Bezier曲线是唯一的。在折线的各顶点中,只有第一点和最后一点在曲线上且作为曲线的起始处和终止处,其他的点用于控制曲线的形状及阶次。曲线的形状趋向于多边形折线的形状,要修改曲线,只要修改折线的各顶点就可以了。因此,多边形折线又称Bezier曲线的控制多边形,其顶点称为控制点。
三次Bezier曲线,有四个控制点,其数学表示如下:
,
4.实验代码:
1 #include2 3 #include 4 5 #include 6 7 #include 8 9 using namespace std; 10 11 struct Point { 12 13 int x, y; 14 15 }; 16 17 Point pt[4], bz[11]; 18 19 vector vpt; 20 21 bool bDraw; 22 23 int nInput; 24 25 void CalcBZPoints() 26 27 { 28 29 float a0,a1,a2,a3,b0,b1,b2,b3; 30 31 a0=pt[0].x; 32 33 a1=-3*pt[0].x+3*pt[1].x; 34 35 a2=3*pt[0].x-6*pt[1].x+3*pt[2].x; 36 37 a3=-pt[0].x+3*pt[1].x-3*pt[2].x+pt[3].x; 38 39 b0=pt[0].y; 40 41 b1=-3*pt[0].y+3*pt[1].y; 42 43 b2=3*pt[0].y-6*pt[1].y+3*pt[2].y; 44 45 b3=-pt[0].y+3*pt[1].y-3*pt[2].y+pt[3].y; 46 47 float t = 0; 48 49 float dt = 0.01; 50 51 for(int i = 0; t<1.1; t+=0.1, i++) 52 53 { 54 55 bz[i].x = a0+a1*t+a2*t*t+a3*t*t*t; 56 57 bz[i].y = b0+b1*t+b2*t*t+b3*t*t*t; 58 59 } 60 61 } 62 63 void ControlPoint(vector vpt) 64 65 { 66 67 glPointSize(2); 68 69 for(int i=0; i 0) {112 113 ControlPoint(vpt);114 115 }116 117 if(bDraw)118 119 {120 121 PolylineGL(pt, 4);122 123 CalcBZPoints();124 125 PolylineGL(bz, 11);126 127 }128 129 glFlush();130 131 }132 133 void Init()134 135 {136 137 glClearColor(0.0, 0.0, 0.0, 0.0);138 139 glShadeModel(GL_SMOOTH);140 141 printf("Please Click left button of mouse to input control point of Bezier Curve!\n");142 143 }144 145 void Reshape(int w, int h)146 147 {148 149 glViewport(0, 0, (GLsizei) w, (GLsizei) h);150 151 glMatrixMode(GL_PROJECTION);152 153 glLoadIdentity();154 155 gluOrtho2D(0.0, (GLdouble) w, 0.0, (GLdouble) h);156 157 }158 159 void mouse(int button, int state, int x, int y)160 161 {162 163 switch (button)164 165 {166 167 case GLUT_LEFT_BUTTON:168 169 if (state == GLUT_DOWN)170 171 {172 173 if (nInput == 0)174 175 {176 177 pt[0].x = x;178 179 pt[0].y = 480 - y;180 181 nInput = 1;182 183 vpt.clear();184 185 vpt.push_back(pt[0]);186 187 bDraw = false;188 189 glutPostRedisplay();//190 191 }192 193 else if (nInput == 1)194 195 {196 197 pt[1].x = x;198 199 pt[1].y = 480 - y;200 201 vpt.push_back(pt[1]);202 203 nInput = 2;204 205 glutPostRedisplay();//206 207 }208 209 else if (nInput == 2)210 211 {212 213 pt[2].x = x;214 215 pt[2].y = 480 - y;216 217 vpt.push_back(pt[2]);218 219 nInput = 3;220 221 glutPostRedisplay();//222 223 }224 225 else if (nInput == 3)226 227 {228 229 pt[3].x = x;230 231 pt[3].y = 480 - y;232 233 bDraw = true;234 235 vpt.push_back(pt[3]);236 237 nInput = 0;238 239 glutPostRedisplay();//240 241 }242 243 }244 245 break;246 247 default:248 249 break;250 251 }252 253 }254 255 int main(int argc, char *argv[])256 257 {258 259 glutInit(&argc, argv);260 261 glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);262 263 glutInitWindowPosition(100, 100);264 265 glutInitWindowSize(640, 480);266 267 glutCreateWindow("Hello World!");268 269 Init();270 271 glutDisplayFunc(myDisplay);272 273 glutReshapeFunc(Reshape);274 275 glutMouseFunc(mouse);276 277 glutMainLoop();278 279 return 0;280 281 }
附上本实验的VC++(VC++2008)
5.实验提高
尝试实现B样条曲线算法。