计算机图形学报告Word文档下载推荐.docx

上传人:b****5 文档编号:20358758 上传时间:2023-01-22 格式:DOCX 页数:28 大小:860.33KB
下载 相关 举报
计算机图形学报告Word文档下载推荐.docx_第1页
第1页 / 共28页
计算机图形学报告Word文档下载推荐.docx_第2页
第2页 / 共28页
计算机图形学报告Word文档下载推荐.docx_第3页
第3页 / 共28页
计算机图形学报告Word文档下载推荐.docx_第4页
第4页 / 共28页
计算机图形学报告Word文档下载推荐.docx_第5页
第5页 / 共28页
点击查看更多>>
下载资源
资源描述

计算机图形学报告Word文档下载推荐.docx

《计算机图形学报告Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《计算机图形学报告Word文档下载推荐.docx(28页珍藏版)》请在冰豆网上搜索。

计算机图形学报告Word文档下载推荐.docx

=y1,其他情形可以类推)

1.1.1、待扫描转换生成直线段:

1.1.2、直线的表达形式:

,其中

1.1.3、划分区间:

1.1.4、计算纵坐标:

1.1.5、对计算的纵坐标取整:

2、中点算法扫描转换直线段:

2.1、中点算法简介:

2.1.1、待扫描转换生成直线段:

2.1.2、直线的表达形式:

且假定直线段的斜率

2.1.3、直线段的隐式方程:

2.1.4、递推计算纵坐标为:

,其中M为

2.1.5、令2.1.4中的

的2倍为判别式,即取判别式为:

并且有递推计算公式如下:

2.1.6、算法的初始条件为

3、Breshenham算法扫描转换直线段:

3.1、Breshenham算法简介:

3.1.1、前序几步与前面两者的思想一样,不同的是在确定下一个点的纵坐标的值的时候,算法不同;

3.1.2、设点Q为斜线段与

直线的交点,

分别为点Q距上下平行线

距离。

可求出

的长度

3.1.3、推得

,且令

3.1.4、则有递推公式

也即:

3.1.5、得到纵坐标的递推求值为:

二、扫描转换圆弧

1、扫描转换生成圆

1.1、算法简介:

1.1.1、利用圆的八对称性;

1.1.2、利用重点算法扫描转换:

1.1.3、取判别数:

,其中

,即圆的隐函数在中点的函数值;

1.1.4、递推求下一个点的纵坐标值:

1.15、给定算法的初始条件如下:

上机实现及源代码:

实验中,在给定两个点之后,根据算法的思想扫描生成一条直线,二两个端点的给定可以通过捕获鼠标信息来获取:

当鼠标左键按下的时候,调用OnLButtonDown()函数来获取直线段的起点,当释放鼠标左键的时候,调用OnLButtonUp()函数来获取直线段的终点。

在扫描转换圆弧中,当鼠标左键按下的时候,调用OnLButtonDown()函数来获取一个点,作为所要画的圆的圆心,当释放左键时,调用OnLButtonUp()函数获取一个点,取两个点之间的的距离作为所要画的圆的半径R,调用switch语句实现不同算法画直线和圆。

voidCAmyGraphView:

:

OnDda()

{

//TODO:

在此添加命令处理程序代码

m_ndrawtype=1;

}

OnMid()

m_ndrawtype=2;

OnBresenham()

m_ndrawtype=3;

voidCAmyGraphView:

OnLButtonDown(UINTnFlags,CPointpoint)

在此添加消息处理程序代码和/或调用默认值

m_start=point;

CView:

OnLButtonDown(nFlags,point);

OnLButtonUp(UINTnFlags,CPointpoint)

m_end=point;

CDC*pDC=GetDC();

CPointP0,P1;

P0=m_start;

P1=m_end;

floatx(P0.x),y(P0.y);

floatdx,dy;

dx=P1.x-P0.x;

dy=P1.y-P0.y;

floatm;

m=dy/dx;

switch(m_ndrawtype)

{

//DDA算法,并且假定x0<

x1

case1:

if(abs(m)<

1)

for(x=P0.x;

x<

=P1.x;

x++)

if(P0.y<

P1.y)

{

pDC->

SetPixel(x,(int)(y+0.5),RGB(255,0,0));

Sleep

(1);

}//0<

=m<

1

else

SetPixel(x,(int)(y-0.5),RGB(255,0,0));

}//-1<

y+=m;

}

if(abs(m)>

=1)

if(P0.y<

for(y=P0.y;

y<

=P1.y;

y++)

x=x+1/m;

pDC->

SetPixel((int)(x+0.5),y,RGB(255,0,0));

Sleep

(1);

else

for(y=P0.y;

y>

y--)

x=x-1/m;

TextOutW(P1.x,P1.y,_T("

DDA算法"

));

ReleaseDC(pDC);

break;

//中点算法生成直线,假定x0<

x1,0<

m<

case2:

intE,NE,d;

d=dx-2*dy;

//初始化判别式d

E=-2*dy;

//取像素E时判别式的增量

NE=2*(dx-dy);

//取像素NE时判别式的增量

SetPixel(x,y,RGB(0,255,0));

while(x<

P1.x)

if(d>

0)

d+=E;

d+=NE;

y++;

}

x++;

中点算法"

//Bresenham算法,假定x0<

case3:

intp,twoDy,twoDyDx,xEND;

p=2*dy-dx;

twoDy=2*dy;

twoDyDx=2*(dy-dx);

SetPixel(x,y,RGB(0,0,255));

P1.x)

if(p<

p+=twoDy;

p+=twoDyDx;

y++;

Bresham算法"

//扫描转换圆

case4:

SetPixel(m_start.x,m_start.y,RGB(255,0,0));

TextOutW(m_start.x,m_start.y,_T("

圆心"

intX(0),Y;

floatD;

intradius;

radius=sqrt(double((P0.x-P1.x)*(P0.x-P1.x)+(P0.y-P1.y)*(P0.y-P1.y)));

//根据鼠标捕获的两个点计算所要绘制的圆的半径,在头文件中定义math.h函数。

Y=radius;

D=5/4-radius;

SetPixel(X+P0.x,Y+P0.y,RGB(255,0,0));

SetPixel(-X+P0.x,Y+P0.y,RGB(255,0,0));

SetPixel(Y+P0.x,X+P0.y,RGB(0,255,0));

SetPixel(Y+P0.x,-X+P0.y,RGB(0,255,0));

SetPixel(-X+P0.x,-Y+P0.y,RGB(0,0,255));

SetPixel(X+P0.x,-Y+P0.y,RGB(0,0,255));

SetPixel(-Y+P0.x,X+P0.y,RGB(0,255,0));

SetPixel(-Y+P0.x,-X+P0.y,RGB(0,255,0));

//绘制八点并将绘制的点平移

while(Y>

X)//八分之一圆弧

if(D<

=0)

D+=2*X+3;

D+=2*(X-Y)+5;

Y--;

X++;

Sleep(15);

(实验一扫描转化直线段)

(实验一中点算法扫描转换圆弧)

第二篇二维填充图元的生成

在第一篇中讨论了一维图元的生成,进而讨论二维图形在计算机中的生成算法,在实际生活中,大多数图形采用定点序列表示多边形,二顶点表示却不能直接用于在光栅系统中显示,所以就需要有从顶点表示转换到点阵表示的算法,这就叫扫描转换多边形。

较为常用的经典扫描转换多边形的算法有住店判断法、扫描线算法、边缘填充法以及递归算法(种子算法),此次试验主要选择递归算法来实现扫描转换多边形。

1、递归算法扫描转换多边形算法的思想简介:

将指定的颜色从种子点扩展到整个区域的过程,区域填充算法要求区域是连通的。

2、上机实现的操作思想:

在扫描填充一个多边形之前,首先需要给定该多边形的顶点表示,本程序的基本想法是,定义一个CPoint类的数组存储多边形顶点,s_point记录种子点,调用OnLButtonDblClk(UINTnFlags,CPointpoint)函数绘制出要填充的多边形。

确定数组中纵坐标最大和最小的点,然后从种子点出发向上向下填充多边形。

算法代码及示例如下:

#defineN12

public:

CPointpset[N],s_point,p0;

voidC区域填充View:

OnDraw(CDC*pDC)

C区域填充Doc*pDoc=GetDocument();

ASSERT_VALID(pDoc);

if(!

pDoc)

return;

TextOut(20,20,_T("

双击鼠标左键,出现需填充的多边形,点击相关功能菜单实现区域填充"

在此处为本机数据添加绘制代码

OnLButtonDblClk(UINTnFlags,CPointpoint)

CPennewpen(PS_SOLID,1,RGB(255,0,0));

CPen*old=pDC->

SelectObject(&

newpen);

pset[0]=CPoint(100,100);

pset[1]=CPoint(200,80);

pset[2]=CPoint(320,100);

pset[3]=CPoint(250,250);

pset[4]=CPoint(100,250);

pset[5]=CPoint(150,200);

pset[6]=CPoint(90,180);

pset[7]=CPoint(150,150);

pset[8]=CPoint(100,100);

Polyline(pset,9);

SelectObject(old);

OnLButtonDblClk(nFlags,point);

OnSeedfill()

intfill=RGB(0,255,0);

intboundary=RGB(255,0,0);

s_point.x=200;

s_point.y=150;

//定义种子点

intx,y,pmin,pmax;

//求多边形的最大最小值

for(intm=1;

9;

m++)

for(intn=0;

n<

9-m;

n++)

if(pset[n].y<

pset[n+1].y)

{

p0=pset[n];

pset[n]=pset[n+1];

pset[n+1]=p0;

}

}//循环得到纵坐标最大和最小的点

pmax=pset[0].y,pmin=pset[8].y;

for(;

pmax+1;

y++)

intcurrent=pDC->

GetPixel(x,y);

while((current!

=boundary)&

&

(current!

=fill))

{

pDC->

SetPixel(x,y,fill);

x++;

current=pDC->

//判断循环是否继续

}

x=s_point.x;

x--;

x--;

x=s_point.x;

x=s_point.x;

y=s_point.y-1;

pmin+1;

y--)

(实验二区域填充—种子扫描线算法)

第三篇二维直线段与多边形裁剪

在第一篇中已经提到,二维图形在现实之前都需要进行两个重要的处理步骤,其一是扫描转换,其二是裁剪。

当二维图形只能在某一可见窗口显示的时候,就需要对其进行裁剪。

现今最要的二位图形的裁剪算法有直线段的裁剪有Cohen-Sutherland算法、Nicholl-Lee-Nicholl算法、中点分割算法以及梁友栋-Barsky算法;

多边形裁剪的算法有Sutherland-Hodgman算法,Weiler-Atherton算法。

本实验将利用Cohen-Sutherland算法上机实现直线段裁剪。

一、直线段裁剪

1、Cohen-Sutherland算法的简介就不做叙述,可以参加文献一第六章。

2、上机实现操作的基本思想:

2.1、首先定义一个数组存储线段的起点和终点坐标,并定义裁剪窗口。

2.2、添加鼠标消息响应函数OnLButtonDblClk()显示要裁剪的线段

2.3、编写“线段裁剪”菜单项,添加事件处理函数来实现直线段裁剪。

3、算法程序源代码及示例如下:

#defineLEFT1

#defineRIGHT2

#defineBOTTOM4

#defineTOP8

#defineXL100

#defineXR300

#defineYT100

#defineYB250

#defineN11

public:

CPointpset[N];

voidCCohenSutherland算法View:

CCohenSutherland算法Doc*pDoc=GetDocument();

Rectangle(CRect(XL,YT,XR,YB));

//剪切窗口

pset[0]=CPoint(200,140);

pset[1]=CPoint(200,200);

pset[2]=CPoint(10,225);

pset[3]=CPoint(350,225);

pset[4]=CPoint(280,170);

pset[5]=CPoint(150,10);

pset[6]=CPoint(200,50);

pset[7]=CPoint(120,150);

pset[8]=CPoint(310,100);

pset[9]=CPoint(350,280);

双击鼠标左键,出现要剪切的线段"

OnLinecut()

CPennewpen(PS_SOLID,1,RGB(0,0,255));

floatx,y;

inti;

intcode1,code2;

RedrawWindow();

//求两端点所在区号code

for(i=0;

i<

N;

i++,i++)

intc=0;

if(pset[i].x<

XL)c=c|LEFT;

//按位或"

|"

即做和运算

elseif(pset[i].x>

XR)c=c|RIGHT;

if(pset[i].y>

YB)c=c|BOTTOM;

elseif(pset[i].y<

YT)c=c|TOP;

code1=c;

c=0;

if(pset[i+1].x<

elseif(pset[i+1].x>

XR)c=c|RIGHT;

if(pset[i+1].y>

elseif(pset[i+1].y<

code2=c;

//线段与区域的相交情况

if(code1!

=0&

code2!

(code1&

code2)==0)//按位与"

"

非"

0"

时一定位于裁剪窗口外的某一侧,p2p3线段

{

if((LEFT&

code1)!

=0)//线段与左边界相交

x=XL;

y=(float)pset[i].y+(pset[i+1].y-pset[i].y)*(XL-pset[i].x)/(pset[i+1].x-pset[i].x);

elseif((RIGHT&

=0)//线段与右边界相交

x=XR;

y=(float)pset[i].y+(pset[i+1].y-pset[i].y)*(XR-pset[i].x)/(pset[i+1].x-pset[i].x);

elseif((BOTTOM&

=0)//线段与下边界相交

y=YB;

x=(float)pset[i].x+(pset[i+1].x-pset[i].x)*(YB-pset[i].y)/(pset[i+1].y-pset[i

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 幼儿教育 > 少儿英语

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1