计算机图形学实验03

更新时间:2023-08-10 01:04:01 阅读量: 工程科技 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

《计算机图形学》实验报告

圆(椭圆)的生成算法

一、实验教学目标与基本要求

1.实现圆的生成算法;

2.实现椭圆的生成算法;

二、实验课程内容 (2学时)

1.写出完整的圆的Bresenham生成算法;

2.写出完整的椭圆的中点生成算法;

三、算法思想

1.圆的Bresenham生成算法:

如果我们构造函数 F(x,y)=x+y-R,则对于圆上的点有F(x,y)=0,对于圆外的点有F(x,y)>0,对于圆内的点F(x,y)<0 。与中点画线法一样,构造判别式:d=F(M)=F(xp+1,yp-0.5)=(xp+1)+(yp-0.5)-R。若d<0,则应取P1为下一象素,而且再下一象素的判别式为:

222d=F(xp+2,yp-0.5)=(xp+2)+(yp-0.5)-R=d+2xp+3

若d≥0,则应取P2为下一象素,而且下一象素的判别式为:d=F(xp+2,yp-1.5)=(xp+2)+(yp-

1.5)-R=d+2(xp-yp)+5我们这里讨论的第一个象素是(0,R),判别式d的初始值为:d0=F(1,R-0.5)=1.25-R。为了进一步提高算法的效率,将上面的算法中的浮点数改写成整数,将乘法运算改成加法运算,即仅用整数实现中点画圆法。

2.椭圆的中点生成算法:

椭圆中点生成算法是将椭圆在第一象限中分为两个部分:

1)对于斜率绝对值小于1的区域内在x方向取单位量;

2)对于斜率绝对值大于1的区域内在y方向取单位量;

斜率可以通过椭圆的标准方程中获得为K = - (ry*ry)*x/(rx*rx)*y;这里中点椭圆222222222

生成算法同样和Bresenham算法有很多相似之处,同样有一个决定下一个位置的关键值P来做权衡处理。

四、程序结构

void CCG03View::Bresenham_Line(CDC* pDC,int x0,int y0,int x1,int y1)

{int i;

int x2, y2;

int x, y, dx, dy;

float e, k;

k = (float)(y1 - y0) / (float)(x1 - x0);

if (x0 == x1){

int miny = y0 > y1 ? y1 : y0;

int maxy = y0 <= y1 ? y1 : y0;

while (miny < maxy){

pDC->SetPixel(x0,miny,RGB(0,0,0));

miny++; }

}

else{

if (x0 > x1){

x2 = -1;dx = x0 - x1;}

else{

x2 = 1;dx = x1 - x0;}

if (y0 > y1){

y2 = -1;dy = y0 - y1;}

else{

y2 = 1;dy = y1 - y0;}

if (k<1 && k>-1){

e = -(float)dx;x = x0;y = y0;

for (i = 0; i <= dx; i++){

pDC->SetPixel(x,y,RGB(0,0,0));

x += x2;e += dy + dy;

if (e >= 0){

y += y2;e -= dx + dx;

}}}

else{

e = -(float)dy;

x = x0;y = y0;

for (i = 0; i <= dy; i++){

pDC->SetPixel(x,y,RGB(0,0,0));

y += y2;e += dx + dx;

if (e >= 0)

{

x += y2;e -= dy + dy;

}}}}}

void CCG03View::Bresenham_Circle(CDC* pDC,int r){

int x,y,delta,delta1,delta2,direction;

x=0;y=r;

delta=2*(1-r);

while(y>=0){

pDC->SetPixel(x,y,RGB(0,0,128));

pDC->SetPixel(-x,y,RGB(0,0,128));

pDC->SetPixel(-x,-y,RGB(0,0,128));

pDC->SetPixel(x,-y,RGB(0,0,128));

if(delta<0){

delta1=2*(delta+y)-1;

if(delta1<=0)direction=1;

else direction=2;

}

else if(delta>0){

delta2=2*(delta-x)-1;

if(delta2<=0)direction=2;

else direction=3;

}

else

direction=2;

switch(direction){

case 1: x++;

delta+=2*x+1;

break;

case 2: x++;

y--;

delta+=2*(x-y+1);

break;

case 3: y--;

delta+=(-2*y+1);

break;

}

}

}

void CCG03View::MidpointEllipse(CDC* pDC,int a,int b){

int x,y;

float d1,d2;

x=0;y=b;

d1=b*b+a*a*(-b+0.25);

pDC->SetPixel(x,y,RGB(30,144,255));

pDC->SetPixel(-x,y,RGB(30,144,255));

pDC->SetPixel(-x,-y,RGB(30,144,255));

pDC->SetPixel(x,-y,RGB(30,144,255));

while(b*b*(x+1)<a*a*(y-0.5))

{

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,y,RGB(30,144,255));

pDC->SetPixel(-x,y,RGB(30,144,255));

pDC->SetPixel(-x,-y,RGB(30,144,255));

pDC->SetPixel(x,-y,RGB(30,144,255));

}

d2=sqrt((double)b*(x+0.5))+sqrt((double)a*(y-1))-sqrt((double)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,y,RGB(30,144,255));

pDC->SetPixel(-x,y,RGB(30,144,255));

pDC->SetPixel(-x,-y,RGB(30,144,255));

pDC->SetPixel(x,-y,RGB(30,144,255));

}

}

void CCG03View::OnDraw(CDC* pDC)

{

CCG03Doc* pDoc = GetDocument();

ASSERT_VALID(pDoc);

if (!pDoc)

return;

pDC -> SetMapMode(MM_HIMETRIC);

pDC -> SetViewportOrg(250,450);

Bresenham_Line(pDC,0,0,0,10000);

Bresenham_Line(pDC,-751,9350,0,10000);

Bresenham_Line(pDC,0,10000,751,9350);

Bresenham_Line(pDC,0,0,10000,0);

Bresenham_Line(pDC,9350,500,10000,0);

Bresenham_Line(pDC,9350,-500,10000,0);

Bresenham_Circle(pDC,4000);

pDC -> TextOutW(10000,-100, TEXT("x"));

pDC -> TextOutW(751,10000, TEXT("y"));

pDC -> TextOutW(-180,-100, TEXT("O"));

pDC -> SetMapMode(MM_LOMETRIC);

pDC -> SetViewportOrg(650,450);

Bresenham_Line(pDC,0,0,0,1000);

Bresenham_Line(pDC,-71,930,0,1000);

Bresenham_Line(pDC,0,1000,71,930);

Bresenham_Line(pDC,0,0,1000,0);

Bresenham_Line(pDC,935,50,1000,0);

Bresenham_Line(pDC,935,-50,1000,0); ;

MidpointEllipse(pDC,300,200);

pDC -> TextOutW(1000,-20, TEXT("x"));

pDC -> TextOutW(71,1000, TEXT("y"));

pDC -> TextOutW(-20,-20, TEXT("O"));

// TODO: 在¨²此ä?处ä|为a本À?机¨²数ºy据Y添¬¨ª加¨®绘?制?代䨲码?

}

五、程序调试及结果的分析

六、实验心得及建议

这是我第三次上计算机图形学实验课,对于实验的操作流程以及对VS2010的用法已经基本熟悉,而且圆的bresenham生成算法又与上次实验有些共同点,所以进行得较为顺利。同样,椭圆的生成算法也编写的较为顺利。但是后半部分就没那么简单了,这次实验与以往的最大不同就是需要重新建立两个坐标系。在这里遇到了比较大的困难,最后还是在查阅网上资料以及向同学请教的基础上完成了坐标系的建立。希望自己能够在新的学期多学技术和编程知识,也希望老师能够多多指导,为我将来的发展打下良好的基础。

评语:

本文来源:https://www.bwwdw.com/article/5llj.html

Top