OpenGL计算机图形学梁友栋裁剪算法实验代码及运行结果
OpenGL计算机图形学梁友栋裁剪算法实验代码及运行结果

《计算机图形学实验》报告任课教师:钱文华2016年春季学期实验:梁友栋裁剪实验时间:2016年11月17日实验地点:信息学院2204实验目的:掌握梁友栋裁剪程序代码:#include <stdio.h>#include <glut.h>#include <stdlib.h>#include <math.h>class wcPt2D{public:GLfloat x,y;void setCoords(GLfloat xCoord,GLfloat yCoord){x=xCoord;y=yCoord;}GLfloat getx() const{return x;}GLfloat gety() const{return y;}};inline GLint round(const GLfloat a){return GLint(a+0.5);}void setPixel(int x,int y){glBegin(GL_POINTS);glVertex2i(x,y);glEnd();}void init(){glClearColor(1.0,1.0,1.0,0.0);glMatrixMode (GL_PROJECTION);gluOrtho2D(-200.0,200.0,-200.0,200.0);}void lineBres(GLfloat x0,GLfloat y0,GLfloat xEnd,GLfloat yEnd){ int dx = fabs(xEnd - x0),dy = fabs(yEnd - y0);int p = 2*dy - dx;int twoDy = 2*dy,twoDyMinusDx = 2*(dy - dx);int x,y;if(x0>xEnd){x = xEnd;y = yEnd;xEnd = x0;}else{x = x0;y = y0;}setPixel(x,y);while(x<xEnd){x++;if(p<0)p+=twoDy;else{y++;p+=twoDyMinusDx;}setPixel(x,y);}}GLint clipTest(GLfloat p,GLfloat q,GLfloat *u1,GLfloat *u2){ GLfloat r;GLint returnValue = true;if(p<0.0){r = q/p;if(r>*u2)returnValue = false;elseif(r>*u1)*u1 = r;}elseif(p>0.0){r = q/p;if(r<*u1)returnValue = false;else if(r<*u2)*u2 = r;}elseif(q<0.0)returnValue = false;return(returnValue);}void lineClipLiangBarsk(wcPt2D winMin,wcPt2D winMax,wcPt2D p1,wcPt2D p2){GLfloat u1 = 0.0,u2 = 1.0,dx = p2.getx()-p1.getx(),dy;GLfloat x1 = p1.getx(),y1 = p1.gety();GLfloat x2 = p2.getx(),y2 = p2.gety();if(clipTest(-dx,p1.getx()-winMin.getx(),&u1,&u2))if(clipTest(dx,winMax.getx()-p1.getx(),&u1,&u2)){dy = p2.gety()-p1.gety();if(clipTest(-dy,p1.gety()-winMin.gety(),&u1,&u2)){if(clipTest(dy,winMax.gety()-p1.gety(),&u1,&u2)){if(u2<1.0){p2.setCoords(p1.getx()+u2*dx,p1.gety()+u2*dy);}if(u1>0.0){p1.setCoords(p1.getx()+u1*dx,p1.gety()+u1*dy);}glColor3f(0.0,0.0,0.0);lineBres(x1,y1,p1.getx(),p1.gety());lineBres(p2.getx(),p2.gety(),x2,y2);glColor3f(1.0,0.0,0.0);lineBres(p1.getx(),p1.gety(),p2.getx(),p2.gety());}}else{glColor3f(0.0,0.0,0.0);lineBres(x1,y1,x2,y2);}}}void displayliangyoudongcaijian(){glClear(GL_COLOR_BUFFER_BIT);glLineWidth(5.0);glColor3f(0.0,0.0,0.0);glBegin(GL_LINE_LOOP);glVertex2i(100,100);glVertex2i(100,-100);glVertex2i(-100,-100);glVertex2i(-100,100);glEnd();glPointSize(4);wcPt2D test1[4] = {{-100.0,-100.0},{100.0,100.0},{-150.0,-200.0},{200.0,120.0}};wcPt2D test2[4] = {{-100.0,-100.0},{100.0,100.0},{-150.0,-120.0},{0.0,0.0}};wcPt2D test3[4] = {{-100.0,-100.0},{100.0,100.0},{-50.0,50.0},{150.0,150.0}};wcPt2D test4[4] = {{-100.0,-100.0},{100.0,100.0},{-50.0,0.0},{60.0,50.0}};wcPt2D test5[4] = {{-100.0,-100.0},{100.0,100.0},{-170.0,-200.0},{200.0,-120.0}};lineClipLiangBarsk(test1[0],test1[1],test1[2],test1[3]);lineClipLiangBarsk(test2[0],test2[1],test2[2],test2[3]);lineClipLiangBarsk(test3[0],test3[1],test3[2],test3[3]);lineClipLiangBarsk(test4[0],test4[1],test4[2],test4[3]);lineClipLiangBarsk(test5[0],test5[1],test5[2],test5[3]);glFlush();}void main(int argc, char* argv[]){glutInit(&argc,argv);glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);glutInitWindowPosition(50,100);glutInitWindowSize(400,300);glutCreateWindow("梁友栋裁剪算法");init();glutDisplayFunc(displayliangyoudongcaijian);glutMainLoop();}实验结果:。
计算机图形学——梁友栋-Barsky算法

计算机图形学——梁友栋-Barsky算法梁算法是计算机图形学上最经典的⼏个算法,也是⽬前唯⼀⼀个以中国⼈命名的出现在国内外计算机图形学课本的算法,我之前在介绍裁剪算法的时候介绍过这个算法这⼏天复习图形学,发现当时那篇博客写的很空洞,⼀些关键性的推理式⼦讲的不是很清楚,于是在这⾥仔细介绍⼀下。
最近发现中国⼤学MOOC上中国农业⼤学的赵明教授讲的很不错,课程短⼩精悍,感兴趣的同学可以去看⼀下⼀、直线的参数⽅程梁算法表⽰直线是通过直线的参数⽅程来确定的,也就是说给出两个点,利⽤参数表⽰直线。
这⾥对U的理解就是(x,y)点在所给两点之间线段上的位置。
⼆、出边和⼊边把被裁剪的红⾊直线段看 成是⼀条有⽅向的线段,把窗⼝ 的四条边分成两类:⼊边和出边⼊边:直线由窗⼝外向窗⼝内移动时和窗⼝边界相交的边(左边界和下边界)。
出边:直线由窗⼝内向窗⼝外移动时和窗⼝边界相交的边(右边界和上边界)。
裁剪结果的线段起点是直线和两条⼊边的交点以及始端点三 个点⾥最前⾯的⼀个点,即参数u最⼤的那个点;裁剪线段的终点是和两条出边的交点以及端点最后⾯的⼀个 点,取参数u最⼩的那个点。
值得注意的是,当u从-∞到+∞遍历直线时,⾸先对裁剪窗⼝的两条边界直线(下边和左边)从外⾯向⾥⾯移动,再对裁剪窗⼝两条边界直线(上边和右边)从⾥⾯向外⾯移动。
如果⽤u1,u2分别表⽰ 线段(u1≤u2)可见部分的开始和结束上⾯就是梁友栋先⽣的发现,但⼜有了新的问题:如何判断出边和⼊边?四个U值是如何求出来的?判断线段某⼀部分是否在窗⼝内,可以简化为判断直线上⼀个点是否在窗⼝内的问题。
我们知道梁友栋算法的基本出发点是直线的参数⽅程,那么对于那些不会被裁剪掉的点⼀定会满⾜下⾯的不等式:三、运算所⽤的量将上⾯的不等式移项得:在这⾥可以确定那些直线与裁剪窗⼝的交点中P K<0的点输⼊⼊边,P K>0的点属于出边1)分析P k=0的情况如果还满⾜q k<0则线段完全在边界外,应舍弃该线段如果q k≥0则进⼀步判断(2)当p k≠0时:当p k<0时线段从裁剪边界延长线的外部 延伸到内部,是⼊边交点当p k> 0时线段从裁剪边界延长线的内部 延伸到外部,是出边交点线段和窗⼝边界⼀共有四个交点,根据p k的符号,就知道 哪两个是⼊交点,哪两个是出交点当p k< 0时:对应⼊边交点当p k> 0时:对应出边交点⼀共四个u值,再加上u=0、u=1两个端点值,总共六个值把pk<0的两个u值和0⽐较去找最⼤的,把pk>0的两个u值 和1⽐较去找最⼩的,这样就得到两个端点的参数值四、⼩结直线参数化直线段看成是有⽅向的把窗⼝的四条边分为⼊边和出边。
opengl算法学习---直线裁剪算法

opengl 算法学习---直线裁剪算法裁剪是从数据集合提取信息的过程,它是计算机图形学许多重要问题的基础。
裁剪典型的⽤途就是从⼀个⼤的场景中提取所需的信息,以显⽰某⼀局部场景或视图。
⽐如浏览地图时,对感兴趣的区域放⼤显⽰,此时窗⼝内显⽰的内容会相应减少。
确定图形的哪些部分在窗⼝内,哪些部分在窗⼝外(不可见区域),只显⽰窗⼝内的那部分图形,这个选择处理过程就是裁剪。
这⾥详细讲述两种算法Cohen-Sutherland 编码裁剪算法Cohen-Sutherland 编码裁剪算法算法思想1)若线段完全在窗⼝之内则显⽰该线段称为“取”,2)若线段明显在窗⼝之外则丢弃该线段称为“弃”3)若线段既不满⾜“取”的条件也不满⾜“弃”的条件则把线段分割为两段,对于完全在窗⼝之外的部分可弃之。
具体实现为快速判断⼀条直线段与矩形窗⼝的位置关系采⽤如图所⽰的空间划分和编码⽅案(四位⼆进制编码上下右左)裁剪⼀条线段时先求出两端点所在的区号,若皆为零保留。
若端点编码按位取与运算的结果不为零,意味着线段位于窗⼝之外,应舍弃。
否则求出线段与窗⼝某边的交点并将该线段⼀分为⼆后,舍弃完全在窗⼝外的线段并对另⼀段重复上述处理。
代码实现Liang-Barsky 算法概念Liang-Barsky 算法的基本思想是,从 A 、B 和 P1中找出最靠近 P2的点,如图所⽰为 P1;从C 、D 和 P2中找出最靠近P1的点,显然为C 点;也即 PC1即为裁剪后部分。
具体实现稍后再补对于区域内存在的线段P1P2,根据两点坐标构造⽅程x=x_{1}+u(x_{2}-x_{1})y=y_{1}+u(y_{2}-y_{1})令\Delta x=x_{2}-x_{1} \Delta y=y_{2}-y_{1}即可推出x=x_{1}+u\Delta xy=y_{1}+u\Delta yLiang-Barsky算法通过计算两端点截取后的u值,绘制截取后的线段,设截取后线段的两端点u为u_{1}、u_{2} u_{1}初始值=0,即线段初始点,u_{2}初始值=1,即线段终点对于x⽽⾔x_{l} \leqslant x \leqslant x_{r}同理y_{b} \leqslant y \leqslant y_{t}\Rightarrow \left\{\begin{matrix} x_{l} \leqslant x_{1}+u\Delta x \leqslant x_{r} \\ y_{b} \leqslant y_{1}+u\Delta y \leqslant y_{t} \end{matrix}\right.即可推得\Rightarrow \left\{\begin{matrix} u\Delta x \leqslant x_{r}-x_{1} \\ -u\Delta x \leqslant x_{1}-x_{l} \\ u\Delta y \leqslant y_{t}-y_{1} \\ -u\Delta y \leqslant y_{1}-y_{b} \end{matrix}\right.构造p_{k} \leqslant q_{k} ,k={1,2,3,4}每个k对应上式每种情况\Rightarrow \left\{\begin{matrix} p_{1}=\Delta x & q_{1}=x_{r}-x_{1} \\ p_{2}=-\Delta x & q_{2}=x_{1}-x_{l} \\ p_{3}=\Delta y & q_{3}=y_{t}-y_{1} \\ p_{4}=-\Delta y & q_{4}=y_{1}-y_{b} \end{matrix}\right.当p_{k}=0时,该线段平⾏于轮廓线如果q_{k}<0当k=1时,x_{r}<x_{1}当k=2时,x_{1}<x_{l}当k=3时,y_{t}<y_{1}当k=4时,y_{1}<y_{b}可推出若q_{k}<0时,该线段位于裁剪区域外如果q_{k}\geqslant 0则该线段位于区域内当p_{k} \neq 0时,此时线段延长线与轮廓线交点在上式中u值=\frac{q_{k}}{p_{k}}若p_{k}<0则该线段部分为由边界外到边界内,u_{1}=max(u_{1},u)若p_{k}>0则该线段部分为由边界内到边界外,u_{2}=min(u_{2},u)通过以上过程,可推出截取后线段两端点的u_{1}与u_{2},若u_{1}>u_{2},则该线段不为于裁剪区域内代码实现void LiangBarsky(Point p1,Point p2,Rectan rec){float u1=0,u2=1,p[4],q[4];p[0]=p1.x-p2.x;p[1]=p2.x-p1.x;p[2]=p1.y-p2.y;p[3]=p2.y-p1.y;q[0]=p1.x-rec.xl;q[1]=rec.xr-p1.x;q[2]=p1.y-rec.yb;q[3]=rec.yt-p1.x;for(int i=0;i<4;i++){if(!p[i] && q[i]<0) return ;else if(p[i]){float u=q[i]/p[i];if(p[i]<0) u1=max(u1,u);else u2=min(u2,u);}}if(u1>u2) return ;drawline(Point(p1.x+u1*(p2.x-p1.x),p1.y+u1*(p2.y-p1.y)),Point(p1.x+u2*(p2.x-p1.x),p1.y+u2*(p2.y-p1.y)),BLUE);}Processing math: 0%。
梁友栋-Barsky直线裁剪算法计算机图形学课程设计

河南理工大学万方科技学院课程设计报告2011 — 2012学年第二学期课程名称计算机图形学设计题目计算机图形学基本算法演示系统设计学生姓名学号专业班级网络11升—1班指导教师徐文鹏2012 年5 月28 日目录第1章设计内容与要求 (1)1.1 总体目标和要求 (1)1.2内容与要求 (1)1.2.1 直线的生成 (1)1.2.2 圆弧的生成 (1)1.2.3 线段裁剪 (2)1.2.4 多边形裁剪 (2)1.2.5 综合 (2)第2章总体设计 (3)2.1 Bresenham算法画直线 (3)2.1.1 Bresenham算法画直线理论基础 (3)2.1.2 Bresenham算法画直线原理 (3)2.2 Bresenham算法画圆 (4)2.2.1 Bresenham算法画圆理论基础 (4)2.2.2 Bresenham算法画圆原理 (5)2.3 梁友栋-Barsky算法进行线段裁剪 (6)2.3.1梁友栋-Barsky算法进行线段裁剪基本原理 (6)2.4 Sutherland-Hodgman算法进行多边形裁剪 (8)2.4.1 Sutherland—Hodgman多边形裁剪算法思想 (8)2.4.2 点在边界内侧的判断方法 (8)2.4.4 Sutherland-Hodgeman多边形裁剪算法特点 (8)第3章详细设计 (9)3.1 Bresenham算法画直线 (9)3.1.1 Bresenham 算法画线算法具体实现过程 (9)3.2 Bresenham算法画圆 (9)3.2.1 Bresenham 算法画圆核心代码 (9)3.3 梁友栋-Barsky算法进行线段裁剪 (10)3.3.1梁友栋-Barsky算法推导过程 (10)3.3.2梁友栋-Barsky算法进行线段裁剪的步骤 (11)3.4 Sutherland-Hodgman算法进行多边形裁剪 (11)3.4.1 Sutherland—Hodgman多边形裁剪算法步骤 (11)3.5将画线、画圆、线段裁剪和多边形裁剪综合 (12)第4章功能实现 (14)4.1用Bresenham算法画线测试结果 (14)4.2用Bresenham算法画圆测试结果 (14)4.3梁友栋-Barsky算法进行线段裁剪测试结果 (15)4.4 Sutherland-Hodgman算法进行多边形裁剪测试结果 (16)4.5将四种算法综合测试结果 (16)第5章总结 (17)参考文献 (18)第1章设计内容与要求1.1 总体目标和要求目标:以图形学算法为目标,深入研究。
计算机图形学直线裁剪代码

using System;using ;using ponentModel;using System.Data;using System.Drawing;using System.Text;using ;namespace LineCut_Cohen{public partial class Form1 : Form{public Form1(){InitializeComponent();}//定义钻石参数int x0 = 100;int y0 = 100;int n = 13;int r = 50;int[] x;int[] y;////计算钻石顶点 by tiantian//public void ZuanShi(){float t = (float)3.14159 * 2 / n;x = new int[n];y = new int[n];for (int i = 0; i < n; i++){x[i] = (int)(r * Math.Cos(i * t) + x0);y[i] = (int)(r * Math.Sin(i * t) + y0);}}////计算点(x,y)的编码//void CompOutCode(int x, int y, Rectangle rect, OutCode outCode){outCode.all = 0;outCode.top = outCode.bottom = 0;if (y < rect.Top) //rect类的top相当于我们惯常用的坐标系的bottomby:tiantian{outCode.bottom = 1;outCode.all += 1;}else if (y > rect.Bottom)//rect类的bottom相当于我们惯常用的坐标系的top by:tiantian{outCode.top = 1;outCode.all += 1;}outCode.right = outCode.left = 0;if (x > rect.Right){outCode.right = 1;outCode.all += 1;}else if (x < rect.Left){outCode.left = 1;outCode.all += 1;}}////线段裁剪,p0(x0,y0),p1(x1,y1)为待裁剪线断,rect为裁剪窗口//bool ChoenSutherlandLineClip(ref int x0, ref int y0, ref int x1, ref int y1, Rectangle rect) //这里必须是引用传递!by:tiantian{Boolean accept, done;OutCode outCode0 = new OutCode();OutCode outCode1 = new OutCode();OutCode outCodeOut = new OutCode();int x = 0;int y = 0;accept = false;done = false;CompOutCode(x0, y0, rect, outCode0);CompOutCode(x1, y1, rect, outCode1);do{int code0 = outCode0.Code();int code1 = outCode1.Code();if ((outCode0.all == 0) && (outCode1.all == 0)) //完全可见{accept = true;done = true;}else if ((code0 & code1) != 0) //显然不可见 by ttdone = true;else //进行求交测试{if (outCode0.all != 0) //判断哪一点位于窗口之外outCodeOut = outCode0;else outCodeOut = outCode1;if (outCodeOut.left == 1)//线段与窗口的左边相交{x = rect.Left;y = y0 + (y1 - y0) * (x - x0) / (x1 - x0);}else if (outCodeOut.right == 1)//线段与窗口的右边相交{x = rect.Right;y = y0 + (y1 - y0) * (x - x0) / (x1 - x0);}else if (outCodeOut.top == 1)//线段与窗口的上边相交{y = rect.Bottom;x = x0 + (x1 - x0) * (y - y0) / (y1 - y0);}else if (outCodeOut.bottom == 1)//线段与窗口的下边相交{y = rect.Top;x = x0 + (x1 - x0) * (y - y0) / (y1 - y0);}//以交点为界,将线段位于窗口边所在的直线的外侧的部分丢弃。
计算机图形学裁剪

《计算机图形学》实验报告学院:理学院专业:信息与计算科学班级:structRectangle{floatxmin,xmax,ymin,ymax;};Rectanglerect;intx0,y0,x1,y1;intCompCode(intx,inty,Rectanglerect){intcode=0x00;if(y<rect.ymin)code=code|4;if(y>rect.ymax)code=code|8;if(x>rect.xmax)code=code|2;if(x<rect.xmin)code=code|1;returncode;}intcohensutherlandlineclip(Rectanglerect,int&x0,int&y0,int&x1,int&y1){ intaccept,done;floatx,y;accept=0;done=0;intcode0,code1,codeout;code0=CompCode(x0,y0,rect);code1=CompCode(x1,y1,rect);do{if(!(code0|code1)){accept=1;done=1;}elseif(code0&code1)done=1;else{if(code0!=0)codeout=code0;elsecodeout=code1;if(codeout&LEFT_EDGE){y=y0+(y1-y0)*(rect.xmin-x0)/(x1-x0);x=(float)rect.xmin;}elseif(codeout&RIGHT_EDGE){y=y0+(y1-y0)*(rect.xmax)/(x1-x0);x=(float)rect.xmax;}elseif(codeout&BOTTOM_EDGE){x=x0+(x1-x0)*(rect.ymin-y0)/(y1-yO);y=(float)rect.ymin;}elseif(codeout&TOP_EDGE){x=x0+(x1-x0)*(rect.ymax-y0)/(y1-y0);y=(float)rect.ymax;if(codeout==code0){x0=x;y0=y;code0=CompCode(x0,y0,rect);}else{x1=x;y1=y;code1=CompCode(x1,y1,rect);}}while(!done);if(accept)LineGL(x0,y0,x1,y1);returnaccept;}voidmyDisplay(){glClear(GL_COLOR_BUFFER_BIT);glColor3f(1.0f,0.0f,0.0f);glRectf(rect.xmin,rect.ymin,rect.xmax,rect.ymax);LineGL(x0,y0,x1,y1);glFlush();voidInit(){glClearColor(0.0,0.0,0.0,0.0);glShadeModel(GL_FLAT);rect.xmin=100;rect.xmax=300;rect.ymin=100;rect.ymax=300;x0=450,y0=0,x1=0,y1=450;printf("Presskey'c'toClip!\nPresskey'r'toRrstore!\n");}voidReshape(intw,inth){glViewport(0,0,(GLsizei)w,(GLsizei)h);glMatrixMode(GL_PROJECTION);glLoadldentityO;gluOrtho2D(0.0,(GLdouble)w,0.0,(GLdouble)h);}voidkeyboard(unsignedcharkey,intx,inty){switch(key){case'c':cohensutherlandlineclip(rect,x0,y0,x1,y1);glutPostRedisplay();break;case'r':Init();glutPostRedisplay();break;case'x':exit(0);break;default:break;}}voidmain(intargc,char**argv){glutInit(&argc,argv);glutInitDisplayMode(GLUT_RGBIGLUT_SINGLE);glutInitWindowPosition(100,100);glutInitWindowSize(640,480);glutCreateWindow("helloworld");Init();glutDisplayFunc(myDisplay);glutReshapeFunc(Reshape);glutMainLoop();}Mhellovorld实验结。
计算机图形学实验报告-OpenGL基本使用

学生实验实习报告册学年学期:2016-2017学年 春□√秋学期课程名称:大学计算机基础学生学院:通信与信息工程学院专业班级:学生学号:学生姓名:联系电话:重庆邮电大学教务处印制实验实习名OpenGL基本使用指导教师秦红星考核成绩课程名称计算机图形学A 课程编号实验实习地点信息科技大厦S306 完成日期学生姓名学生学号学院专业广电与数字媒体类所在班级教师评语教师签名:年月日一、实验实习目的及要求目的:认识了解OpenGL的性质、功能要求:1.利用OpenGL绘制一个简单的场景:比如球体、正方体2.加入灯光3.实现交互操作:平移、缩放、旋转二、实验实习设备(环境)及要求(软硬件条件)采用Microsoft Visual C 2010生成环境并用C++编写程序三、实验实习内容与步骤内容:背景为黑色,在点光源下,能够实现平移、缩放、旋转的球。
步骤:建立立体-->添加光照-->添加变换1.先写“主函数”,在主函数中将窗口生成好。
2.在“自定义函数1”中对窗口进行清除、填色等操作。
3.在“自定义函数1”中设置点光源,设置光照的各种参数。
4.在“自定义函数1”中设置平移、缩放、旋转及各参数。
5.在“自定义函数2”中设置平移和缩放的循环。
6.在主函数中调用这两个自定义函数,并且在主函数里面用“自定义函数1”为参数调用glutDisplayFunc()来注册一个绘图函数。
其次用空闲回调函数glutIdleFunc()来使球体不停地循环有缩放、平移功能的函数。
实现动画。
四、实验实习过程或算法(源程序、代码)#include<GL/glut.h>GLfloat angle = 0.0f;GLfloat multiply = 0.0f;void display(void){glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glClearColor(0.0f, 0.0f, 0.0f, 0.0f); //设置窗口里面的背景颜色glMatrixMode(GL_PROJECTION);glLoadIdentity();gluPerspective(90.0f, 1.0f, 1.0f, 20.0f);glLoadIdentity();gluLookAt(0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);{//设置一个点光源GLfloat light_position[] = { 0.5f,0.0f,0.0f,1.0f };//(xyzw)w为1时代表点光源,0时代表方向光源GLfloat light_ambient[] = { 0.5f,0.5f,0.5f,1.0f };//(0001)GLfloat light_diffuse[] = { 1.0f,1.0f,1.0f,1.0f };//(1111)GLfloat light_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };//(1111)glLightfv(GL_LIGHT0, GL_POSITION, light_position);glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);//光源环境光强值glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);//光源漫反射强值glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);//光源镜面反射强值glEnable(GL_LIGHT0);//打开该光源glEnable(GL_LIGHTING);//打开光照}{glRotatef(angle, 0.0f, 1.0f, 0.0f);glTranslatef(0.0f, 0.0f, 0.6f); //平移glScaled(multiply, multiply, multiply); //缩放glutSolidSphere(0.2, 50, 50);}glutSwapBuffers();}void rotateAndzoom(void) //旋转和缩放{angle += 1.0f;if (angle >= 360.0f)angle = 0.0f;display();//设置旋转multiply += 0.01f;if (multiply >= 2.0f)// multiply -= 0.01f;//if (multiply <= 1.0f)multiply = 1.0f;display();//设置缩放}int main(int argc, char* argv[]){glutInit(&argc, argv);glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);glutInitWindowPosition(400, 50);glutInitWindowSize(800, 800);glutCreateWindow("立体");glutDisplayFunc(&display);glutIdleFunc(&rotateAndzoom);//旋转glutMainLoop();//调用该函数启动程序,所有以创建的窗口将会显示return 0;}五、实验实习结果分析和(或)源程序调试过程实验实习名直线扫面和区域填充实现指导教师考核成绩课程名称课程编号实验实习地点完成日期学生姓名学生学号学院专业通信与信息工程学院广电与数字媒体类所在班级教师评语教师签名:年月日一、实验实习目的及要求项目目的:熟悉光栅图形学中的相关算法项目要求:1.应用OpenGL点绘制函数直线与区域2.采用直线扫面算法绘制一条线段,直线有离散点组成3.利用区域填充算法绘制多边形区域,区域由离散点组成二、实验实习设备(环境)及要求(软硬件条件)采用Microsoft Visual C 2010生成环境并用C++编写程序三、实验实习内容与步骤内容:1.用DDA算法实现点绘制直线。
裁剪III(计算机图形学)

2009-2010-2:CG:SCUEC
14
多边形裁剪-凸多边形的二维裁剪
多边形是由一组线段围成的封闭区域,线段裁剪是多边形 裁剪的基础。下图(b)是多边形的线段被裁剪后的结果,但 已不再是封闭的区域。正确的剪裁结果应是一个有边界的区 域,即裁剪后的结果仍是一个(或多个)多边形 ,这就要求
x t x R x 0 y t y0 yB y t y T y 0
令
QR x QB y QT y
则有 t Q i D i i L , R , B , T
2009-2010-2:CG:SCUEC
3
梁友栋-Barsky算法
凸多边形裁剪区域
3) N (P(t)-A) < 0,则P(t)在L外侧。
性质1表明,P(t)在凸多边形内的充要条件是,对于凸多边形边界上 任意一点A和该处内法向量N,都有N (P(t)-A) 0 。
2009-2010-2:CG:SCUEC
9
Cyrus-Beck算法
现假设多边形有k条边,在每条边界Li上取1个点 Ai ,该点处的内法 向量Ni(i=1,2,…,k),则可见线段的参数区间为下列不等式组的解
由
t Q i D i i L , R , B , T
i , j { L , R }i j
Dj Di (Q i 0 ) t (Q j 0 ) Q Qj i D Dj i (Q i 0 ) t (Q j 0 ) Qj Qi 0 t 1
i , j { B , T }i j
2009-2010-2:CG:SCUEC
4
梁友栋-Barsky算法
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
glMatrixMode (GL_PROJECTION); gluOrtho2D(-200.0,200.0,-200.0,200.0); } void lineBres(GLfloat x0,GLfloat y0,GLfloat xEnd,GLfloat yEnd){ int dx = fabs(xEnd - x0),dy = fabs(yEnd - y0); int p = 2*dy - dx; int twoDy = 2*dy,twoDyMinusDx = 2*(dy - dx); int x,y; if(x0>xEnd){ x = xEnd; y = yEnd; xEnd = x0; } else{ x = x0; y = y0; } setPixel(x,y);
inline GLint round(const GLfloat a){return GLint(a+0.5);} void setPixel(int x,int y){ glBegin(GL_POINTS); glVertex2i(x,y); glEnd(); }
void init(){ glClearColor(1.0,1.0,1.0,0.0);
if(clipTest(-dy,p1.gety()-winMin.gety(),&u1,&u2)){ if(clipTest(dy,winMax.gety()-p1.gety(),&u1,&u2)){ if(u2<1.0){ p2.setCoords(p1.getx()+u2*dx,p1.gety()+u2*dy); } if(u1>0.0){ p1.setCoords(p1.getx()+u1*dx,p1.gety()+u1*dy); } glColor3f(0.0,0.0,0.0); lineBres(x1,y1,p1.getx(),p1.gety()); lineBres(p2.getx(),p2.gety(),x2,y2); glColor3f(1.0,0.0,0.0); lineBres(p1.getx(),p1.gety(),p2.getx(),p2.gety()); } } else{ glColor3f(0.0,0.0,0.0); lineBres(x1,y1,x2,y2); } } } void displayliangyoudongcaijian(){
class wcPt2D{ public: GLfloat x,yoord,GLfloat
yCoord){x=xCoord;y=yCoord;} GLfloat getx() const{return x;} GLfloat gety() const{return y;} };
glClear(GL_COLOR_BUFFER_BIT); glLineWidth(5.0); glColor3f(0.0,0.0,0.0); glBegin(GL_LINE_LOOP); glVertex2i(100,100); glVertex2i(100,-100); glVertex2i(-100,-100); glVertex2i(-100,100); glEnd(); glPointSize(4); wcPt2D test1[4] =
{{-100.0,-100.0},{100.0,100.0},{-170.0,-200.0},{200.0,-120.0}}; lineClipLiangBarsk(test1[0],test1[1],test1[2],test1[3]); lineClipLiangBarsk(test2[0],test2[1],test2[2],test2[3]);
lineClipLiangBarsk(test3[0],test3[1],test3[2],test3[3]); lineClipLiangBarsk(test4[0],test4[1],test4[2],test4[3]); lineClipLiangBarsk(test5[0],test5[1],test5[2],test5[3]); glFlush(); }
while(x<xEnd){ x++; if(p<0) p+=twoDy; else{ y++; p+=twoDyMinusDx; } setPixel(x,y); } } GLint clipTest(GLfloat p,GLfloat q,GLfloat *u1,GLfloat *u2){ GLfloat r; GLint returnValue = true;
init(); glutDisplayFunc(displayliangyoudongcaijian); glutMainLoop(); }
实
验
结
果
:
p1,wcPt2D p2){ GLfloat u1 = 0.0,u2 = 1.0,dx = p2.getx()-p1.getx(),dy; GLfloat x1 = p1.getx(),y1 = p1.gety(); GLfloat x2 = p2.getx(),y2 = p2.gety(); if(clipTest(-dx,p1.getx()-winMin.getx(),&u1,&u2)) if(clipTest(dx,winMax.getx()-p1.getx(),&u1,&u2)){ dy = p2.gety()-p1.gety();
void main(int argc, char* argv[]){ glutInit(&argc,argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); glutInitWindowPosition(50,100); glutInitWindowSize(400,300); glutCreateWindow("梁友栋裁剪算法");
{{-100.0,-100.0},{100.0,100.0},{-50.0,50.0},{150.0,150.0}}; wcPt2D test4[4] =
{{-100.0,-100.0},{100.0,100.0},{-50.0,0.0},{60.0,50.0}}; wcPt2D test5[4] =
《计算机图形学实验》报告
任课教师:钱文华
2016 年春季学期
实验:梁友栋裁剪
实验时间:2016 年 11 月 17 日 实验地点:信息学院 2204 实验目的:掌握梁友栋裁剪
程序代码:#include <stdio.h> #include <glut.h> #include <stdlib.h> #include <math.h>
if(p<0.0){ r = q/p; if(r>*u2) returnValue = false; else if(r>*u1) *u1 = r;
} else if(p>0.0){ r = q/p; if(r<*u1) returnValue = false; else if(r<*u2) *u2 = r; } else if(q<0.0) returnValue = false; return(returnValue); } void lineClipLiangBarsk(wcPt2D winMin,wcPt2D winMax,wcPt2D
{{-100.0,-100.0},{100.0,100.0},{-150.0,-200.0},{200.0,120.0}}; wcPt2D test2[4] =
{{-100.0,-100.0},{100.0,100.0},{-150.0,-120.0},{0.0,0.0}}; wcPt2D test3[4] =