西安石油大学计算机图形学实验报告.docx
《西安石油大学计算机图形学实验报告.docx》由会员分享,可在线阅读,更多相关《西安石油大学计算机图形学实验报告.docx(21页珍藏版)》请在冰豆网上搜索。
![西安石油大学计算机图形学实验报告.docx](https://file1.bdocx.com/fileroot1/2023-2/23/c6228cb0-3d17-4c73-bb72-414cfe2783ce/c6228cb0-3d17-4c73-bb72-414cfe2783ce1.gif)
西安石油大学计算机图形学实验报告
实验报告
—计算机图形学实验大作业
课程名称计算机图形学
实验名称二维绘图系统与计算机动画
姓名
学号
专业班级
成绩
指导教师爨莹
实验报告
课程名称计算机图形学实验名称二维绘图系统
姓名学号专业班级
实验日期2015年12月8日成绩指导教师爨莹
一、实验目的
本实验为设计和开发一个小型的二维绘图系统。
通过图形软件的设计开发和上机实验,巩固所学图形学基本知识,掌握交互式图形系统的设计方法,熟悉并掌握有关图形图象编程语言、工具和类库的使用。
二、实验环境
Win8操作系统+VC6.0开发平台
三、实验内容与步骤
1、算法原理
(1)DDA算法画直线原理
DDA算法是根据直线的微分方程来计算Δx或Δy生成直线的扫描转换算法。
在一个坐标轴上以单位间隔对线段取样,以决定另一个坐标轴方向上最靠近理想线段的整数值。
设(x0,y0)为直线段的始点,(x1,y1)为直线段的终点,且端点坐标均为整数,则直线的微分方程为
设|k|≤1,则有
yi+1=kxi+1+b=k(xi+Δx)+b=yi+kΔx
上式表明,若Δx=1,则当x每递增1时,y递增k。
扫描转换开始时,取直线始点(x0,y0)作为初始坐标。
(2)中点Bresenham算法画直线原理
Bresenham画线算法与中点画线法有相似之处,也是通过在每列像素中确定与理想直线最近的像素来进行直线的扫描转换的。
为了讨论的方便,不妨也假定直线的斜率在0~1之间。
如图所示,过各行、各列像素中心构造一组虚拟网格线,按直线从起点到终点的顺序计算直线与各垂直网格线的交点,然后确定该列像素中与该交点最近的像素。
Bresenham算法误差项d的几何意义
(3)中点Bresenham算法画圆算法原理
为了讨论的方便,我们考虑中心在原点,半径为R的圆的第二个八分圆弧,圆的其它部分可通过一系列的简单的反射变换得。
也就是讨论如何从(0,R)到
(R/,R/)顺时针确定最佳逼近于该圆弧的像素序列。
中心在原点,半径为R的圆的方程为x2+y2=R2
若令F(x,y)=x2+y2-R2,则上述方程为F(x,y)=0
如图所示,假定x坐标为xP的像素中最佳逼近理想圆弧的为P(xP,yP),那么,下一个像素只能是正右方的P1(xP+1,yP)或右下方的P2(xP+1,yP-1)两者之一。
引入P1和P2的中点M(xP+1,yP-0.5),当M在圆内时,应取P1(xP+1,yP)为下一个像素,否则,应取P2(xP+1,yP-1)为下一个像素。
为此,构造判别式
d=F(M)=F(xP+1,yP-0.5)=(xP+1)2+(yP-0.5)2-R2
中点画圆法
若d<0,则应取P1(xP+1,yP)为下一个像素,而且再下一个像素的判别式为
d′=F(xP+2,yP-0.5)=(xP+2)2+(yP-0.5)2-R2=d+2xP+3
而d≥0,则应取P2(xP+1,yP-1)为下一个像素,而且再下一个像素的判别式为
d′=F(xP+2,yP-1.5)=(xP+2)2+(yP-1.5)2-R2=d+2(xP-yP)+5
由于第一个像素是(0,R),因而d的初始值为
d0=F(1,R-0.5)=1.25-R
(4)中点bresenham算法画椭圆原理
中点画圆法可以推广到一般二次曲线的生成,下面以中心在原点的标准椭圆的扫描转换为例说明。
设椭圆的方程为
F(x,y)=b2x2+a2y2-a2b2=0
其中,a为沿x轴方向的长半轴长度,b为y轴方向的短半轴长度,a、b均为整数。
不失一般性,我们只讨论第一象限椭圆弧的生成。
需要注意的是,在处理这段椭圆时,必须以弧上斜率为-1的点(即法向量两个分量相等的点)作为分界把它分为上部分和下部分,如图所示。
第一象限的椭圆弧
该椭圆上一点(x,y)处的法向量为
其中,i和j分别为沿x轴和y轴方向的单位向量。
从图3.6可看出,在上部分,法向量的y分量更大,而在下部分,法向量的x分量更大,因而,在上部分若当前最佳逼近理想椭圆弧的像素(xP,yP)满足下列不等式
b2(xP+1)<a2(yP-0.5)
而确定的下一个像素不满足上述不等式,则表明椭圆弧从上部分转入下部分。
在上部分,假设横坐标为xP的像素中与椭圆弧更接近点是(xP,yP),那么下一对候选像素的中点是(xP+1,yP-0.5)。
因此判别式为
d1=F(xP+1,yP-0.5)=b2(xP+1)2+a2(yP-0.5)2-a2b2
若d1<0,中点在椭圆内,则应取正右方像素,且判别式应更新为
d′1=F(xP+2,yP-0.5)=b2(xP+2)2+a2(yP-0.5)2-a2b2=d1+b2(2xP+3)
当d1≥0,中点在椭圆之外,这时应取右下方像素,并且更新判别式为
d′1=F(xP+2,yP-1.5)=b2(xP+2)2+a2(yP-1.5)2-a2b2=d1+b2(2xP+3)+a2(-2yP+2)
由于弧起点为(0,b),因此,第一中点是(1,b-0.5),对应的判别式是
d10=F(1,b-0.5)=b2+a2(b-0.5)2-a2b2=b2+a2(-b+0.25)
在下部分,应改为从正下方和右下方两个像素中选择下一像素。
如果在上部分所选择的最后一像素是(xP,yP),则下部分的中点判别式d2的初始值为
d20=F(xP+0.5,yP-1)=b2(xP+0.5)2+a2(yP-1)2-a2b2
d2在正下方向与右下方向的增量计算与上部分类似,这里不再赘述。
下部分弧的终止条件是y=0。
(5)三次Bezier曲线算法的原理
Bézier曲线是法国雷诺汽车公司的工程师PierreBézier于1962年提出的,它将函数逼近同几何表示结合起来,目的在于使设计师在计算机上能得心应手地绘图。
Bézier曲线在各种CAD系统中有广泛的应用。
假设给出n+1个控制点的位置矢量Pi(i=0,1,2,…,n),则n次Bézier多项式函数为
由控制点Pi(i=0,1,2,…,n)中相邻两点的连线构成的折线集称为Bézier特征多边形。
Bézier曲线的形状逼近于特征多边形的形状,起点和终点与多边形的起点、终点重合,且多边形的第一条边和最后一条边表示了曲线在起点和终点处的切矢量方向。
Bi,n(t)是Bernstein基函数,也是Bézier曲线的调和函数。
Bézier曲线的性质由它的调和函数所决定。
如图7所示的是一条三次Bézier曲线。
图8三次Bézier曲线
三次Bézier曲线算法实现公式:
(6)三次B样条曲线算法原理
已知n+1个控制点Pi(i=0,1,…,n),则k次(k+1阶)B样条曲线的表达式是
其中,Ni,k(u)是调和函数,也称之为基函数,由Schoenberg提出,其递归定义为
(tk≤u≤tn+1)
(7)基本图形变换原理
基本图形变换即是对一个基本图形进行各种平移,旋转,剪切,对称,比例等各项基本操作,其本质便是将一个基本图形的坐标写成其次坐标的形式,齐次坐标表示法就是用N+1维向量来表示一个N维向量。
在齐次坐标系统中,点(X,Y)用(X,Y,H)来表达,其中H为非零的一个任意数。
点(X,Y)的标准齐次坐标表达为(X/H,Y/H,1),由于H是一个任意非零常量,为了简便起见,我们通常取H=1。
齐次坐标系统中的点(X,Y,1)包含有笛卡尔坐标上的点(X,Y)。
对其进行各种变换即是在本身齐次坐标的矩阵上进行矩阵乘运算,使其产生不同的变换效果
例如:
平移变换的矩阵乘法如下
100
[x’y’1]=[xy1]010=[x+Txy+Ty1]
TxTy1
比例变换的矩阵乘法如下
Sx00
[x’y’1]=[xy1]0Sy0=[xSxySy1]
001
2、代码编程:
(1)直线
1>DDA直线
intx0=10,y0=150,x1=150,y1=100;
intx,y;
floatdx,dy,k;
dx=(float)(x1-x0);
dy=(float)(y1-y0);
k=dy/dx;
y=y0;
if(abs(k)<1)
{
for(x=x0;x<=x1;x++)
{
pDC->SetPixel(x,int(y+0.5),RGB(255,0,0));
y=y+k;
}
}
if(abs(k)>=1)
{
for(y=y0;y{
pDC->SetPixel(int(x+0.5),y,RGB(0,0,288));
x=x+1/k;
}
}
ReleaseDC(pDC)
2>中点Bresenham算法直线
CDC*pDC=GetDC();
intx1=10,y1=20,x2=550,y2=400,c=RGB(255,0,0);
inti,s1,s2,interchange;
floatx,y,deltax,deltay,f,temp;
x=x1;
y=y1;
deltax=abs(x2-x1);
deltay=abs(y2-y1);
if(x2-x1>=0)s1=1;elses1=-1;
if(y2-y1>=0)s2=1;elses2=-1;
if(deltay>deltax)
{
temp=deltax;
deltax=deltay;
deltay=temp;
interchange=1;
}
elseinterchange=0;
f=2*deltay-deltax;
pDC->SetPixel(x,y,c);
for(i=1;i<=deltax;i++)
{
if(f>=0)
{
if(interchange==1)x+=s1;
elsey+=s2;
pDC->SetPixel(x,y,c);
f=f-2*deltax;
}
else
{
if(interchange==1)y+=s2;
elsex+=s1;
f=f+2*deltay;
}
}
(2)画圆
1>中点Bresenham算法画圆
CDC*pDC=GetDC();
intxc=200,yc=110,radius=100,c=0;
intx=0,y=radius,p=3-2*radius;
while(x{
pDC->SetPixel(xc+x,yc+y,c);
pDC->SetPixel(xc-x,yc+y,c);
pDC->SetPixel(xc+x,yc-y,c);
pDC->SetPixel(xc-x,yc-y,c);
pDC->SetPixel(xc+y,yc+x,c);
pDC->SetPixel(xc-y,yc+x,c);
pDC->SetPixel(xc+y,yc-x,c);
pDC->SetPixel(xc-y,yc-x,c);
if(p<0)
p=p+4*x+6;
else
{
p=p+4*(x-y)+10;
y-=1;
}
x+=1;
}
if(x==y)
pDC->SetPixel(xc+x,yc+y,c);
pDC->SetPixel(xc-x,yc+y,c);
pDC->SetPixel(xc+x,yc-y,c);
pDC->SetPixel(xc-x,yc-y,c);
pDC->SetPixel(xc+y,yc+x,c);
pDC->SetPixel(xc-y,yc+x,c);
pDC->SetPixel(xc+y,yc-x,c);
pDC->SetPixel(xc-y,yc-x,c);
2>系统画圆
pDC->SetViewportOrg(230,110);
pDC->Ellipse(-90,90,90,-90);
break;
(3)画椭圆
1>中点Bresenham算法画椭圆
CDC*pDC=GetDC();
inta=200,b=100,xc=700,yc=110,c=0;
intx,y;
doubled1,d2;
x=0;y=b;
d1=b*b+a*a*(-b+0.25);
pDC->SetPixel(x+300,y+200,c);
pDC->SetPixel(-x+300,y+200,c);
pDC->SetPixel(x+300,-y+200,c);
pDC->SetPixel(-x+300,-y+200,c);
while(b*b*(x+1){
if(d1<0)
{
d1+=b*b*(2*x+3);
x++;
}
else
{
d1+=b*b*(2*x+3)+a*a*(-2*y+2);
x++;y--;
}
pDC->SetPixel(x+xc,y+yc,c);
pDC->SetPixel(-x+xc,y+yc,c);
pDC->SetPixel(x+xc,-y+yc,c);
pDC->SetPixel(-x+xc,-y+yc,c);
}
d2=sqrt(b*(x+0.5))+a*(y-1)-a*b;
while(y>0)
{
if(d2<0)
{
d2+=b*b*(2*x+2)+a*a*(-2*y+3);
x++;
y--;
}
else
{
d2+=a*a*(-2*y+3);
y--;
}
pDC->SetPixel(x+xc,y+yc,c);
pDC->SetPixel(-x+xc,y+yc,c);
pDC->SetPixel(x+xc,-y+yc,c);
pDC->SetPixel(-x+xc,-y+yc,c);
}
2>系统画椭圆
pDC->SetViewportOrg(600,190);
pDC->Ellipse(0,0,200,150);
break;
(4)图形基本变换
1>母图
floata[4][3]={{-100,-100,1},{-20,100,1},
{170,0,1},{100,-120,1}};
inti;
pDC->MoveTo(int(a[3][0]),int(a[3][1]));
for(i=0;i<4;i++)
{
pDC->LineTo(int(a[i][0]),int(a[i][1]));
}
2>基本变换
以平移为例:
floata[4][3]={{-100,-100,1},{-20,100,1},
{170,0,1},{100,-120,1}};
floatb[][3]={{1,0,0},{0,1,0},{-100,-100,1}};
floatc[4][3];
inti;
pDC->MoveTo(int(a[3][0]),int(a[3][1]));
for(i=0;i<4;i++)
{
pDC->LineTo(int(a[i][0]),int(a[i][1]));
}
JuZhenCheng(a,b,c,3,4);//列,行
CPenpen(PS_SOLID,1,RGB(255,0,0));
CPen*pOldPen=pDC->SelectObject(&pen);
pDC->MoveTo(int(c[3][0]),int(c[3][1]));
for(i=0;i<4;i++)
{
pDC->LineTo(int(c[i][0]),int(c[i][1]));
}
pDC->SelectObject(pOldPen);
当需要其他变换时,只需要按照原理将floatb[][3]中的矩阵数列进行改即可得到相应的基本图形变换。
四、实验结果
基本界面
基本直线绘制
Bezier曲线绘制
三次B样条曲线绘制
DDA直线绘制
图形变换母图
平移变换
旋转45°
旋转90°
旋转180°
原点对称
关于X轴对称
关于Y轴对称
关于Y=X对称
关于Y=-X对称
错切变换
比例变换
系统画圆
系统画椭圆
中点Bresenham算法画圆
中点Bresenham算法画椭圆
实验报告
课程名称计算机图形学实验名称计算机动画
姓名学号专业班级
实验日期2015年12月1日成绩指导教师爨莹
一、实验目的
本实验基本部分为设计和开发一个计算机动画,通过软件的设计开发和上机实验,巩固所学图形学基本知识,掌握交互式图形系统的设计方法,熟悉并掌握有关图形图象编程语言、工具和类库的使用。
二、实验环境
Win8操作系统+Flash6.0
三、实验内容与步骤
1、素材准备:
(1)图片
(2)音乐
(3)文字特效
2、脚本编写:
动画主题为《战争与和平》,……………
3、动画效果:
四、实验结果