实验6 Bezier曲线生成
1.实验目的:
了解曲线的生成原理,掌握几种常见的曲线生成算法,利用VC+OpenGL实现Bezier曲线生成算法。
2.实验内容:
(1) 结合示范代码了解曲线生成原理与算法实现,尤其是Bezier曲线;
(2) 调试、编译、修改示范程序。
3.实验原理:
Bezier曲线是通过一组多边形折线的顶点来定义的。如果折线的顶点固定不变,则由其定义的Bezier曲线是唯一的。在折线的各顶点中,只有第一点和最后一点在曲线上且作为曲线的起始处和终止处,其他的点用于控制曲线的形状及阶次。曲线的形状趋向于多边形折线的形状,要修改曲线,只要修改折线的各顶点就可以了。因此,多边形折线又称Bezier曲线的控制多边形,其顶点称为控制点。
三次Bezier曲线,有四个控制点,其数学表示如下:
4.实验代码:
1 #include <GL/glut.h> 2 3 #include <stdio.h> 4 5 #include <stdlib.h> 6 7 #include <vector> 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<Point> 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<Point> vpt) 64 65 { 66 67 glPointSize(2); 68 69 for(int i=0; i<vpt.size(); i++) 70 71 { 72 73 glBegin (GL_POINTS); 74 75 glColor3f (1.0f, 0.0f, 0.0f); glVertex2i (vpt[i].x,vpt[i].y); 76 77 glEnd (); 78 79 } 80 81 } 82 83 void PolylineGL(Point *pt, int num) 84 85 { 86 87 glBegin (GL_LINE_STRIP); 88 89 for(int i=0;i<num;i++) 90 91 { 92 93 glColor3f (1.0f, 1.0f, 1.0f); 94 95 glVertex2i (pt[i].x,pt[i].y); 96 97 } 98 99 glEnd (); 100 101 } 102 103 void myDisplay() 104 105 { 106 107 glClear(GL_COLOR_BUFFER_BIT); 108 109 glColor3f (1.0f, 1.0f, 1.0f); 110 111 if (vpt.size() > 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样条曲线算法。
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一次Java后端服务间歇性响应慢的问题排查记录
· dotnet 源代码生成器分析器入门
· ASP.NET Core 模型验证消息的本地化新姿势
· 对象命名为何需要避免'-er'和'-or'后缀
· SQL Server如何跟踪自动统计信息更新?
· 官方的 MCP C# SDK:csharp-sdk
· 一款 .NET 开源、功能强大的远程连接管理工具,支持 RDP、VNC、SSH 等多种主流协议!
· “你见过凌晨四点的洛杉矶吗?”--《我们为什么要睡觉》
· 提示词工程师自白:我如何用一个技巧解放自己的生产力
· C#/.NET/.NET Core技术前沿周刊 | 第 31 期(2025年3.17-3.23)