首页 > 代码库 > [计算机图形学 with OpenGL] Chapter8 习题8.6 线段旋转后使用Cohen-Sutherland算法裁剪
[计算机图形学 with OpenGL] Chapter8 习题8.6 线段旋转后使用Cohen-Sutherland算法裁剪
习题8.6 生成一条比观察窗口对角线还长的线段动画,线段重点位于观察窗口中心,每一帧的线段在上一帧基础上顺时针旋转一点,旋转后用Cohen-Sutherland线段裁剪算法进行裁剪。
步骤:
- 1 视口范围:(-100, -100)到(100, 100);
- 2 裁剪窗口区域:winMin(-50, -50) 到 winMax(50, 50),原始端点:p0(-100, 0)到 p1(100, 0)
- 3 使用Bresenham算法画原始线段,使用Cohen-Sutherland算法画裁剪线段;
- 4 theta += delta,其中 theta为累计旋转角度,delta为每次变化的角度;
- 5 计算旋转后的新的原始线段端点:p0‘和p1‘。x‘ = x * cos(theta) - y * sin(theta), y‘ = x * sin(theta) +y * cos(theta);
- 6 每帧重复步骤3-5.
1 #include <GLUT/GLUT.h> 2 #include <math.h> 3 #include <iostream> 4 #include "linebres.h" 5 #include "linecohsuth.h" 6 7 const GLdouble PI = 3.1416; 8 GLdouble theta = 0.0; 9 const GLdouble delta = - PI / 100;10 11 void init (void)12 {13 glClearColor(0.0, 0.0, 0.0, 1.0);14 15 glMatrixMode(GL_PROJECTION);16 gluOrtho2D(-100, 100, -100, 100);17 18 glMatrixMode(GL_MODELVIEW);19 }20 21 void clippingWindow (void)22 {23 glColor3f(1.0, 1.0, 1.0);24 25 glBegin(GL_LINE_LOOP);26 glVertex2i(-50, -50);27 glVertex2i(-50, 50);28 glVertex2i(50, 50);29 glVertex2i(50, -50);30 glEnd();31 }32 33 void displayFcn (void)34 {35 glClear(GL_COLOR_BUFFER_BIT);36 37 clippingWindow();38 39 glColor3f(1.0, 1.0, 1.0);40 41 wcPt2D winMin, winMax;42 winMin.setCoords(-50, -50);43 winMax.setCoords(50, 50);44 45 wcPt2D p0, p1;46 p0.setCoords(-100, 0);47 p1.setCoords(100, 0);48 49 wcPt2D p00, p01;50 p00.setCoords(p0.getx() * cos(theta) - p0.gety() * sin(theta), p0.getx() * sin(theta) + p0.gety() * cos(theta));51 p01.setCoords(p1.getx() * cos(theta) - p1.gety() * sin(theta), p1.getx() * sin(theta) + p1.gety() * cos(theta));52 53 // std::cout << "p00 : " << p00.getx() << "," << p00.gety() << std::endl;54 // std::cout << "p01 : " << p01.getx() << "," << p01.gety() << std::endl;55 56 glColor3f(1.0, 1.0, 0.0);57 lineBres(round(p00.getx()), round(p00.gety()), round(p01.getx()), round(p01.gety()));58 glColor3f(0.0, 1.0, 1.0);59 lineClipCohSuth(winMin, winMax, p00, p01);60 61 glutSwapBuffers();62 }63 64 void idleFcn (void)65 {66 theta += delta;67 displayFcn();68 }69 70 int main(int argc, char * argv[]) {71 72 glutInit(&argc, argv);73 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);74 glutInitWindowPosition(-50, 50);75 glutInitWindowSize(600, 600);76 glutCreateWindow("Exercise 8.6");77 78 init();79 glutDisplayFunc(displayFcn);80 glutIdleFunc(idleFcn);81 82 glutMainLoop();83 84 return 0;85 }
因为theta一直在变化,每次重新计算cos(theta)和sin(theta)会影响效率,因此p0和p1每次更新为旋转后的坐标,修改代码如下:
1 #include <GLUT/GLUT.h> 2 #include <math.h> 3 #include <iostream> 4 #include "linebres.h" 5 #include "linecohsuth.h" 6 7 const GLdouble PI = 3.1416; 8 const GLdouble delta = - PI / 100; 9 GLint initialized = 0;10 GLdouble cosDelta, sinDelta;11 wcPt2D p0, p1, winMin, winMax;12 13 void init (void)14 {15 glClearColor(0.0, 0.0, 0.0, 1.0);16 17 glMatrixMode(GL_PROJECTION);18 gluOrtho2D(-100, 100, -100, 100);19 20 glMatrixMode(GL_MODELVIEW);21 }22 23 void clippingWindow (void)24 {25 glColor3f(1.0, 1.0, 1.0);26 27 glBegin(GL_LINE_LOOP);28 glVertex2i(-50, -50);29 glVertex2i(-50, 50);30 glVertex2i(50, 50);31 glVertex2i(50, -50);32 glEnd();33 }34 35 void displayFcn (void)36 {37 glClear(GL_COLOR_BUFFER_BIT);38 39 clippingWindow();40 41 glColor3f(1.0, 1.0, 1.0);42 43 if(!initialized)44 {45 initialized = 1;46 cosDelta = cos(delta);47 sinDelta = sin(delta);48 winMin.setCoords(-50, -50);49 winMax.setCoords(50, 50);50 p0.setCoords(-100, 0);51 p1.setCoords(100, 0);52 }53 54 p0.setCoords(p0.getx() * cosDelta - p0.gety() * sinDelta, p0.getx() * sinDelta + p0.gety() * cosDelta);55 p1.setCoords(p1.getx() * cosDelta - p1.gety() * sinDelta, p1.getx() * sinDelta + p1.gety() * cosDelta);56 57 glColor3f(1.0, 1.0, 0.0);58 lineBres(round(p0.getx()), round(p0.gety()), round(p1.getx()), round(p1.gety()));59 glColor3f(0.0, 1.0, 1.0);60 lineClipCohSuth(winMin, winMax, p0, p1);61 62 glutSwapBuffers();63 }64 65 int main(int argc, char * argv[]) {66 67 glutInit(&argc, argv);68 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);69 glutInitWindowPosition(-50, 50);70 glutInitWindowSize(600, 600);71 glutCreateWindow("Exercise 8.6");72 73 init();74 glutDisplayFunc(displayFcn);75 glutIdleFunc(displayFcn);76 77 glutMainLoop();78 79 return 0;80 }
本来想使用glRotatef(delta, 0.0, 0.0, 1.0)这个转换矩阵进行旋转,但使用C-S裁剪算法时传入的端点坐标依然不是旋转后的,先裁剪后旋转导致裁剪区域不对。不知道是否可以用glRotatef来解答这道题目。
完整代码地址:https://github.com/p0e0o0p0l0e0/Computer_Graphics/
commit: 6ee4159541b305fadd2bf88b1dbd950558e12e8e
[计算机图形学 with OpenGL] Chapter8 习题8.6 线段旋转后使用Cohen-Sutherland算法裁剪
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。