小型绘图系统.docx
《小型绘图系统.docx》由会员分享,可在线阅读,更多相关《小型绘图系统.docx(24页珍藏版)》请在冰豆网上搜索。
小型绘图系统
实验报告
—计算机图形学实验大作业
课程名称计算机图形学
实验名称二维绘图与计算机动画
姓名
学号
专业班级数媒1002
成绩
指导教师爨莹
实验报告
课程名称计算机图形学实验名称小型绘图系统
姓名学号专业班级数媒1002
实验日期20112年12月6日成绩指导教师爨莹
一、实验目的
1.熟悉计算机图形的生成算法
2.用编程的方法实现计算机的生成算法
3.巩固计算机图形学中学到的一些理论知识
二、实验环境
软件:
windows7系统
三、实验内容与步骤(可提供屏幕抓图)
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)作为初始坐标。
程序代码:
voidDDA-line(x0,y0,x1,y1,color)
intx0,y0,x1,y1,color;
{intx;
floaty,k,deltx,delty;
deltx=x1-x0;
delty=y1-y0;
k=delty/deltx;
y=y0;
for(x=x0;x<=x1;x++)
{putpixel(x,int(y+0.5),clolor);
y=y+k;
}
实现截图
DDA算法绘制直线
(2)中点法
●算法的原理
为了讨论的方便,假定直线的斜率在0~1之间,其它情况参照下述讨论进行处理。
假设直线的起点和终点分别为(x0,y0)和(x1,y1),则直线方程为
F(x,y)=ax+by+c=0
其中,a=y0-y1,b=x1-x0,c=x0y1-x1y0。
对于直线上的点,F(x,y)=0;对于直线上方的点,F(x,y)>0;而对于直线下方的点,F(x,y)<0。
如图3.1所示,若直线在x方向上增加一个单位,则在y方向上的增量只能在0和1之间。
假设横坐标为xP的各像素点中最佳逼近于理想直线的像素为(xP,yP),用实心小圆表示。
那么,下一个与直线最近的像素只能是正右方的P1(xP+1,yP)或右上方的P2(xP+1,yP+1)两者之一,用空心小圆表示。
我们用P1和P2的中点M(xP+1,yP+0.5)与理想直线的位置关系来判定。
中点画线示意图
●程序
voidMidPoint-Line(x0,y0,x1,y1,color)
intx0,y0,x1,y1,color;
{inta,b,delta1,delta2,d,x,y;
a=y0-y1;
b=x1-x0;
d=2*a+b
delta1=2*a;
x=x0;
y=y0;
putpixel(x,y,color);
while(x{if(d<0)
{x++;y++;
d+=delta2;
}
else{x++;
d+=delta1;
}
putpixel(x,y,color);
}
}
}
●实现截图
(3)Bresenham算法
●算法的原理
Bresenham画线算法与中点画线法有相似之处,也是通过在每列像素中确定与理想直线最近的像素来进行直线的扫描转换的。
为了讨论的方便,不妨也假定直线的斜率在0~1之间。
如图所示,过各行、各列像素中心构造一组虚拟网格线,按直线从起点到终点的顺序计算直线与各垂直网格线的交点,然后确定该列像素中与该交点最近的像素。
Bresenham算法误差项d的几何意义
●程序
classdrawingsimplementsSerializable//父类,基本图形单元,用到串行化接口,保存时所用
{
intx1,y1,x2,y2;//定义坐标属性
intR,G,B;//定义色彩属性
floatstroke;//定义线条粗细属性
inttype;//定义字体属性
Strings1;
Strings2;//定义字体风格属性
voiddraw(Graphics2Dg2d){
}
;//定义绘图函数
}
publicvoidBresenhamLine(Graphicsg,intx1,inty1,intx2,inty2)throwsException{
intx,y,dx,dy,e;
dx=x2-x1;
dy=y2-y1;
e=-dx;
x=x1;
y=y1;
while(x<=x2){
g.setColor(Color.red);
pset(g,x,y);
x++;
e=e+2*dy;
if(e>0){
y++;
e=e-2*dx;
}
}
classLineextendsdrawings//直线类
{
voiddraw(Graphics2Dg2d){
g2d.setPaint(newColor(R,G,B));
g2d.setStroke(newBasicStroke(stroke,
BasicStroke.CAP_ROUND,BasicStroke.JOIN_BEVEL));
g2d.BresenhamLine(g2d,x1,y1,x2,y2);
}
}
●实现截图
2)圆
●算法的原理
为了讨论的方便,我们考虑中心在原点,半径为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
●程序
voidBresenham-Circle(r,color)
Intr,color;
{intx,y,delta,delta1,delta2,direction;
x=0;y=r;
delta=2*(1-r);
while(y>=0)
{putpixel(x,y,color);
if(delta<0)
{delta1=2*(delta+y)-1;
if(delta1<=0)diretion=1;
elsedirection=2;
}
elseif(delta>0)
{delta2=2*(delta-x)-1;
if(delta2<=0)direction=2;
elsedirecion=3;
}
elsedirection=2;
switch(direction)
{case1:
x++;
delta+=2*x+1;
break;
case2:
x++;
y--;
delta+=2*(x-y+1)
break;
case3:
y--;
delta+=(-2*y+1);
break;
}
}
}
程序截图
绘制圆
3)椭圆
●算法的原理
中点画圆法可以推广到一般二次曲线的生成,下面以中心在原点的标准椭圆的扫描转换为例说明。
设椭圆的方程为
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。
●程序
程序代码:
voidMidpointEllipse(a,b,color)
inta,b,color;
{intx,y;
floatd1,d2;
x=0;y=b;
d1=b*b+a*a*(-b+0.25);
putpixel(x,y,color);
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--;
}
putpixel(x,y,color);
}/*上半部分*/
d2=sqr(b*(x+0.5))+sqr(a*(y-1))-sqr(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--;
}
putpixel(x,y,color);
}
}
●实现截图
绘制椭圆
4)曲线
(1)三次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曲线算法实现公式:
●实现截图(输入参数、输出图形)
输入:
从输入界面中输入四个控制点,坐标任意:
输出:
三次Bézier曲线
(2)三次B样条曲线的绘制
●算法的原理
已知n+1个控制点Pi(i=0,1,…,n),则k次(k+1阶)B样条曲线的表达式是
其中,Ni,k(u)是调和函数,也称之为基函数,由Schoenberg提出,其递归定义为
(tk≤u≤tn+1)
●实现截图(输入参数、输出图形)
输入:
从输入界面中输入四个控制点:
P0(220,350),P1(280,180),P2(300,170),P3(500,3)。
输出:
三次B样条曲线的绘制
5)二维变换
(1)平移
程序:
publicvoidsetpingyi()
{
Stringinput1;
input1=JOptionPane.showInputDialog(
"请输入x平移的量");
m=Float.parseFloat(input1);
Stringinput2;
input2=JOptionPane.showInputDialog(
"请输入y平移的量");
l=Float.parseFloat(input2);
a=1;
b=0;
c=0;
d=1;
}
实验截图:
(2)缩放
程序:
publicvoidsetsuofang()
{
Stringinput;
input=JOptionPane.showInputDialog(
"请输入x的缩放比例");
a=Float.parseFloat(input);
Stringinput1;
input1=JOptionPane.showInputDialog(
"请输入y的缩放比列");
d=Float.parseFloat(input1);
m=313*(1-a);
b=0;
c=0;
l=240*(1-d);
}
实验截图:
(3)旋转
程序:
publicvoidxuanzhuang()
{
Stringinput;
input=JOptionPane.showInputDialog(
"请输入旋转角度");
floato=Float.parseFloat(input);
a=(float)(Math.cos(o*Math.PI/180));
d=(float)(Math.cos(o*Math.PI/180));
m=313*(1-(float)(Math.cos(o*Math.PI/180)))+
240*(1-(float)(Math.sin(o*Math.PI/180)));
b=(float)(Math.sin(o*Math.PI/180));
c=-(float)(Math.sin(o*Math.PI/180));
l=240*(1-(float)(Math.cos(o*Math.PI/180)))-
313*(1-(float)(Math.sin(o*Math.PI/180)));
}
实验截图:
四、实验结果与分析
1.实验结果:
完成的程序界面效果如下所示:
1.实验分析
通过本次绘图系统的设计,使我能够进一步了解绘图系统基本图形绘制的算法。
五、问题与建议
问题:
由于自己能力有限,在有些时候还需要同学的帮助,或者搜集资料参考文献,不能真正的独立完成设计,通过不断调试系统中还是存在一些不足之处。
建议:
本次课程设计使我加深了对课堂所学到的东西的印象,对以后我的学习有很大意义,今后我将更加努力学习,使自己的专业知识尽量完善。
实验报告
课程名称计算机图形学实验名称动画
姓名亢先卫学号201007120206专业班级数媒1002
实验日期2012年12月6日成绩指导教师爨莹
一、实验目的
1.熟悉并掌握flash5.5常用工具,按钮,能练做出小的flash动画.
二、实验环境
1)硬件windows7
2)软件flash5.5
三、实验内容与步骤(可提供屏幕抓图)
1)创意简介
以秋为背景,写出,画出自己对秋最真实的感触!
2)实现手段
运用flash5.5做出效果图
3)屏幕截图
渐变
四、问题与建议
本次课程设计使我加深了对课堂所学到的东西的印象,对以后我的学习有很大意义,今后我将更加努力学习,使自己的专业知识尽量完善