图形学实验报告
班级:07
学号:07
姓名:李
1.编程实现直线生成算法改进的Bresenham算法画直线
(1)源代码:
include
include
include
voidputpi_el(int_,inty)/画点函数{
glColor3f(0.0f,0.0f,0.0f);
glPointSize(3);
glBegin(GL_POINTS);
glVerte_3f(_,y,0.0f);
glEnd();
voidInitial(void)
glClearColor(1.0f,1.0f,1.0f,1.0f);
glMatri_Mode(GL_PROJECTION);gluOrtho2D(0.0,200.0,0.0,150.0);
voidBresenhamLine1(int_0,inty0,int_1,inty1)/斜率0<=k<=1{
int_,y,d_,dy,e;
d_=_1-_0;
dy=y1-y0;
e=-d_;_=_0;y=y0;
while(_<=_1)
putpi_el(_,y);
_++;
e=e+2dy;
if(e>0)
y++;
e=e-2d_;
voidBresenhamLine2(int_0,inty0,int_1,inty1)/斜率1<=k{
int_,y,d_,dy,e;
d_=_1-_0;
dy=y1-y0;
e=-dy;_=_0;y=y0;
while(y<=y1)
putpi_el(_,y);
y++;
e=e+2d_;
if(e>0)
_++;
e=e-2dy;
int_,y,_1,y2;
voidDisplay()/显示直线的函数
floatk;
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0f,0.0f,0.0f);
k=(y2-y)/(_1-_);
if(0<=kk<=1)
BresenhamLine1(_,y,_1,y2);
elseif(k>1)
BresenhamLine2(_,y,_1,y2);
glFlush();
voidmain(intargc,charargv[])
cout<<"依次输入起始点横纵坐标,终点横纵坐标"<
glutInit(argc,argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);glutInitWindowSize(400,300);/设置显示频的尺寸glutInitWindowPosition(100,120);
glutCreateWindow("breswnham算法画直线");glutDisplayFunc(Display);
Initial();
glutMainLoop();
(2)运行演示:
k>=0k<=1
画出的直线如下图所示
画斜率k>1的直线
画出的直线如图所示:
2.编程实现画圆算法
中点Bresenham算法画圆
(1)源代码:
include
include
voidputpi_el(int_,inty)/画点函数
glColor3f(0.0f,0.0f,0.0f);
glPointSize(3);
glBegin(GL_POINTS);
glVerte_3f(_,y,0.0f);
glEnd();
voidInitial(void)
glClearColor(1.0f,1.0f,1.0f,1.0f);
glMatri_Mode(GL_PROJECTION);
gluOrtho2D(0.0,200.0,0.0,150.0);/投影坐标区域
voidMidBresenhamCircle(intr,ints)/终点bresenham算法画一个圆,为了能画一个完整的圆,这里加了平移量s。
/既规定了原点坐标是(s,s)
int_,y,d;
_=0;y=r;d=1-r;
while(_<=y)
putpi_el(_+s,y+s);/下面三句分别做的是该点在2,3,4象限的对称点
putpi_el(-_+s,y+s);
putpi_el(_+s,-y+s);
putpi_el(-_+s,-y+s);
putpi_el(y+s,_+s);/先做出点已经画出的点关于y=_的对称点,再画此点在2,3,4象限的对称点
putpi_el(-y+s,-_+s);
putpi_el(-y+s,_+s);
putpi_el(y+s,-_+s);
if(d<0)
d=d+2_+3;
else
d=d+2(_-y)+5;
y--;
_++;
voidDisplay(void)
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0f,0.0f,0.0f);
MidBresenhamCircle(50,70);/原点从(0,0)平移到(70,70),在新的坐标系下圆心坐标为(50,50),
glFlush();
intmain(intargc,charargv[])
glutInit(argc,argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowSize(550,400);/屏幕的尺寸设定
glutInitWindowPosition(100,120);/屏幕位置的设定
glutCreateWindow("中点Bresenham算法画圆)");
glutDisplayFunc(Display);
Initial();
glutMainLoop();
return0;
(2)运行演示:
为了保证可以画出一个完整的圆,程序已将原点从(0,0)平移到(70,70),在新的坐标系
下圆心坐标为(50,50)
3.(a)编程实现绘制一段三次Bezier曲线
(1)源代码:
include
include
include
classPt3D/定义二维点坐标数据结构
public:GLfloat_,y,z;
/计算多项式的系数
voidGetCnk(GLintn,GLintc)
GLinti,k;
for(k=0;k<=n;k++)
c[k]=1;
for(i=n;i>=k+1;i--)
c[k]=c[k]i;
for(i=n-k;i>=2;i--)
c[k]=c[k]/i;
/计算贝兹尔曲线上点的坐标
voidGetPointPr(GLintc,GLfloatt,Pt3DPt,intControlN,Pt3DControlP)
GLintk,n=ControlN-1;
GLfloatBernstein;
Pt->_=0.0;Pt->y=0.0;Pt->z=0.0;
for(k=0;k Bernstein=c[k]pow(t,k)pow(1-t,n-k); Pt->_+=ControlP[k]._Bernstein; Pt->y+=ControlP[k].yBernstein; Pt->z+=ControlP[k].zBernstein; /根据控制点,求取线上的m个点 voidBezierCurve(GLintm,GLintControlN,Pt3DControlP) GLintC,i; Pt3DCurvePt; C=newGLint[ControlN]; GetCnk(ControlN-1,C); glBegin(GL_POINTS); for(i=0;i<=m;i++) GetPointPr(C,(GLfloat)i/(GLfloat)m,CurvePt,ControlN,ControlP); glVerte_2f(CurvePt._,CurvePt.y); glEnd(); delete[]C; voidinitial(void) glClearColor(1.0,1.0,1.0,0.0); voidDisplay(void) glClear(GL_COLOR_BUFFER_BIT); GLintControlN=4,m=500;/指定有四个控制点,生成的Bezier曲线由500个点组成Pt3DControlP[4]={{-80.0,-40.0,0.0},{-10.0,90.0,0.0},{10.0,-90.0,0.0},{80.0,40.0,0.0}};/控制点的坐标 glPointSize(2);/设置当前绘制点的大小 glColor3f(0.0,0.0,0.0); BezierCurve(m,ControlN,ControlP);/绘制Bezier曲线glBegin(GL_LINE_STRIP);/绘制控制多边形for(GLinti=0;i<4;i++) glVerte_3f(ControlP[i]._,ControlP[i].y,ControlP[i].z);glEnd(); glFlush(); voidReshape(GLintnewWidth,GLintnewHeight) glViewport(0,0,newWidth,newHeight); glMatri_Mode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(-100.0,100.0,-100.0,100.0); voidmain(void) glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);glutInitWindowPosition(100,100); glutInitWindowSize(400,400); glutCreateWindow("Bezier曲线"); initial(); glutDisplayFunc(Display); glutReshapeFunc(Reshape); glutMainLoop(); (2)运行演示: 3.(b)实现两段三次Bezier曲线的拼接 (1)源代码: include include include include include include include classPt3D/定义二维点坐标数据结构 public: GLfloat_,y,z; /就算多项式系数 voidGetCnk(GLintn,GLintc) GLinti,k; for(k=0;k<=n;k++)/计算多项式系数 c[k]=1; for(k=0;k<=n;k++)/计算多项式系数 c[k]=1; for(i=n;i>=k+1;i--) c[k]=c[k]i; for(i=n-k;i>=2;i--) c[k]=c[k]/i; /计算Bezier曲线上点的坐标 voidGetPointPr(GLintc,GLfloatt,Pt3DPt,intControlN,Pt3DControlP){ GLintk,n=ControlN-1; GLfloatBernstein; Pt->_=0.0; Pt->y=0.0; Pt->z=0.0; for(k=0;k Bernstein=c[k]pow(t,k)pow(1-t,n-k); Pt->_+=ControlP[k]._Bernstein; Pt->y+=ControlP[k].yBernstein; Pt->z+=ControlP[k].zBernstein; /根据控制点,求曲线上的m个点 voidBezierCurve(GLintm,GLintControlN,Pt3DControlP) GLintC,i; Pt3DCurvePt; C=newGLint[ControlN]; GetCnk(ControlN-1,C); glBegin(GL_POINTS); for(i=0;i<=m;i++) GetPointPr(C,(GLfloat)i/(GLfloat)m,CurvePt,ControlN,ControlP);glVerte_2f(CurvePt._,CurvePt.y); glEnd(); delete[]C; voidinitial(void) glClearColor(1.0,1.0,1.0,0.0); voidDisplay(void) glClear(GL_COLOR_BUFFER_BIT); GLintControlN=4,m=500;/制定有4个控制点,生成的Bezier曲线由500个点组成Pt3DControlP[4]={{-100.0,-50.0,0.0},{-20.0,70.0,0.0},{20.0,-80.0,0.0},{50.0,50.0,0.0}};/控制点坐标 Pt3DControlP1[4]={{-100.0,50.0,0.0},{10.0,50.0,0.0},{-10.0,-50.0,0.0},{50.0,50.0,0.0}};/另一个Bezier曲线的控制点坐标 glPointSize(2);/设置绘制点的大小 glColor3f(0.0,0.0,0.0); BezierCurve(m,ControlN,ControlP);/绘制Bezier曲线1 BezierCurve(m,ControlN,ControlP1);/绘制Bezier曲线2 glBegin(GL_LINE_STRIP);/绘制控制多边形 for(GLinti=0;i<4;i++) glVerte_3f(ControlP[i]._,ControlP[i].y,ControlP[i].z); for(i=0;i<4;i++) glVerte_3f(ControlP1[i]._,ControlP1[i].y,ControlP1[i].z); glEnd(); glFlush(); voidReshape(GLintnewWidth,GLintnewHeight) glViewport(0,0,newWidth,newHeight); glMatri_Mode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(-100.0,100.0,-100.0,100.0); voidmain(void) glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB); glutInitWindowPosition(100,100); glutInitWindowSize(400,400); glutCreateWindow("Bezier曲线"); initial(); glutDisplayFunc(Display); glutReshapeFunc(Reshape); glutMainLoop(); (2)运行演示: 4.编程实现Y-_算法(又称改进的有效边表算法)或者线段的编码裁剪算法(二选一)线段的裁剪,使用的是liang--Barsky算法 (1)源代码: include include voidInitial(void) glClearColor(1.0f,1.0f,1.0f,1.0f); glMatri_Mode(GL_PROJECTION); gluOrtho2D(0.0,200.0,0.0,150.0); voidputpi_el(int_,inty)/画点函数 glPointSize(3); glBegin(GL_POINTS); glVerte_3f(_,y,0.0f); glEnd(); voidDDALine(int_0,inty0,int_1,inty1)/DDA画直线函数(数值微分法) intd_,dy,epsl,k; float_,y,_Incre,yIncre; d_=_1-_0; dy=y1-y0; _=_0; y=y0; if(abs(d_)>abs(dy)) epsl=abs(d_); else epsl=abs(dy); _Incre=(float)d_/(float)epsl; yIncre=(float)dy/(float)epsl; for(k=0;k<=epsl;k++) putpi_el(int(_+0.5),(int)(y+0.5)); _+=_Incre; y+=yIncre; intLBLineClipTest(floatp,floatq,floatuma_,floatumin) /liang式线段测试函数 floatr=0.0; if(p<0.0)/p小于0时比较最大值 r=q/p; if(r>umin)/umin小于umin直线段才有在窗口内的部分 return0; elseif(r>uma_) uma_=r; elseif(p>0.0)/p大于0时比较最小值 r=q/p; if(r return0; elseif(r umin=r; elseif(q<0.0)/处理p=0的情况 return0; return1; voidLBLineClip(float_wl,float_wr,floatywb,floatywt,float_1,floaty1,float_2,floaty2)/线段裁剪函数,对线段裁剪,只保留在窗口内的部分 floatuma_,umin,delta_,deltay; delta_=_2-_1; deltay=y2-y1; uma_=0.0; umin=1.0; if(LBLineClipTest(-delta_,_1-_wl,uma_,umin))/处理左边界交点 if(LBLineClipTest(delta_,_wr-_1,uma_,umin))/处理右边界交点{ if(LBLineClipTest(-deltay,y1-ywb,uma_,umin))/处理下边界交点{ if(LBLineClipTest(deltay,ywt-y1,uma_,umin))/处理上边界交点{ _1=int(_1+uma_delta_+0.5); y1=int(y1+uma_delta_+0.5); _2=int(_2+umindelta_+0.5); y2=int(y2+umindelta_+0.5); DDALine(_1,y1,_2,y2); voidDisplay(void) glClear(GL_COLOR_BUFFER_BIT); glColor3f(0.0f,0.0f,0.0f); LBLineClip(40.0f,160.0f,40.0f,160.0f,40.0f,10.0f,100.0f,100.0f); glFlush(); voidmain(intargc,charargv[]) glutInit(argc,argv); glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB); glutInitWindowSize(500,380); glutInitWindowPosition(200,320); glutCreateWindow("裁剪后留在窗口内的线段"); glutDisplayFunc(Display); Initial(); glutMainLoop(); (2)运行演示: 裁减函数LBLineClip的 参数值如下 LBLineClip(40.0f,160.0f,40.0f,160.0f,40.0f,10.0f,100.0f,100.0f);直线有一部分不在窗口内被裁减掉
Copyright © 2019- aiwanbo.com 版权所有 赣ICP备2024042808号-3
违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务