计算机图形学实验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生成算法又与上次实验有些共同点,所以进行得较为顺利。同样,椭圆的生成算法也编写的较为顺利。但是后半部分就没那么简单了,这次实验与以往的最大不同就是需要重新建立两个坐标系。在这里遇到了比较大的困难,最后还是在查阅网上资料以及向同学请教的基础上完成了坐标系的建立。希望自己能够在新的学期多学技术和编程知识,也希望老师能够多多指导,为我将来的发展打下良好的基础。
评语:
正在阅读:
计算机图形学实验0308-10
江苏省继续开展运输船舶吨位丈量04-07
企业工资管理系统毕业设计论文 - 图文04-12
行政单位廉政风险点排查工作报告10-14
2016-2017学年物理高二教科版选修3-4自我小测:第1章5 学生实验:用单摆测定重力加速度 含解析 精品11-05
浅谈柏拉图的“洞穴比喻”11-25
个人租房合同【最新7篇】03-22
第6章练习及答案12-01