计算机图形学
实验报告
实验报告
I、实验说明:
计算机图形学(Computer Graphics)是近三十年来发展迅速,应用广泛的新
兴学科,主要研究怎样用数字计算机生成、处理和显示图形。
通过这一学期的认真学习,我们对各种各样的图形处理方法有了一个基本的
认识。通过实验,我们综合利用了计算机图形学里面各种图形的基本算法,以及
图形裁剪、填充等算法,并对图形转换有了更深一步的认识。
本次实验的实验环境:
装有 VC6.0 的计算机一台。
II、实验目的:
通过本次实验,把在《计算机图形学》课程中学到的各种知识运用到实际当
中来,达到学以致用的目的。
1、 了解计算机图形学的原理、方法和应用。
2、 掌握计算机的基本图形(直线和圆)的生成算法、图形裁剪、图形填充、
参数曲线的生成和图形变换等基础知识。
III、实验任务:
1、 编写一个直线算法程序;
2、 编写一个圆算法程序;
3、 编写一个曲线算法程序;
4、 编写两个直线裁剪程序;
5、 编写一个填充算法程序;
6、 编写图形的几何变换程序;
IV、实验内容:
新建工程
(b)选择建立单文档:
点击:finish.
(c)选择
然后双击
一次建立菜单栏:
并且输入 ID 和 CAPTION(例:画线)
下面的 Prompt 是显示在界面左下角的,可以为空。
点击左上角的 View
选择第一个,进入 MFC ClassWizard
将 Class name 改为 CZhouView
选择一个 ID 点击 COMMAND 添加到 CZhouView 里面
依次添加,直到所有 ID 均添加完毕
*还要添加鼠标响应:
全部添加完毕后点击
结束。
工程建立完毕。
添加代码:
主要在 ZhouView.cpp 和 ZhouView.h 内添加代码;
定义 CPoint
采用 OnLButtonUp 响应:
定义 m_nChoice 来区分各个函数,
例:case 1:
DDALine(pDC,m_nPoint1.x,m_nPoint1.y,m_nPoint2.x,m_nPoint2.y,color);
break;
调用 DDA 画直线算法。
在 ZhouView.h 中,定义了:
void SeedFill(int xe,int ye, COLORREF newcolor,COLORREF oldcolor);
void pingyi();
void xuanzhuan();
void bili();
void XCQ();
void YCQ();
void DC();
等全局函数,public;
私有变量:
CPoint m_nPoint2;
CPoint m_nPoint1;
以及共有变量:
CPoint m_nPoint;
COLORREF color;
int flag;
int m_nChoice;
HCURSOR m_npen;
在 LBuTTonDown 中定义
flag=1;
m_nPoint=point;
CDC*pDC=GetDC();
CClientDC dc(this);
m_nPoint1.x=point.x;
m_nPoint2.x=m_nPoint1.x;
m_nPoint1.y=point.y;
m_nPoint2.y=m_nPoint1.y;
CView::OnLButtonDown(nFlags, point);
在构造函数中对变量进行必要的初始化:
CZhouView::CZhouView()
{
// TODO: add construction code here
flag=0;
color=RGB(255,0,0);
m_nPoint1=0;
m_nPoint2=0;
m_nChoice=0;
}
详细算法过程:
直线算法:
i、编写直线算法程序:
选用算法:DDALINE
算法分析:文献[1]中 DDA 算法只考虑斜率在(-1,1)内的情况。
假设带扫描转换的直线段是 P0(x0,y0)P1(x1,y1),再另△x=x1-x0, △y=y1-y0;斜率
m=△y/△x,x++,而 y=(int)(y+0.5);
即 x 一直加一,而 y 可能是不加或者是加一。
ii、算法程序:
//直线算法之 DDA 算法
void DDALine(CDC *pDC, int x1, int y1, int x2, int y2, COLORREF color)
{
int dx,dy,a,b;float X;float Y;
dx=x2-x1;
dy=y2-y1;
int x=x1,y=y1;//起点的 x、y 坐标
if(abs(dx)>abs(dy))
a=abs(dx);
else
}
//OnLButtonUp(UINT nFlags, CPoint point)
case 1:
DDALine(pDC,m_nPoint1.x,m_nPoint1.y,m_nPoint2.x,m_nPoint2.y,color);
break;
iii、编译、运行:
a=abs(dy);
X=dx/(float)a;
Y=dy/(float)a;
pDC->SetPixel(x,int(y+0.5),color);
for(b=0;b<=a;b++)
{
x+=X;
y+=Y;
pDC->SetPixel(x,int (y+0.5),color);
}
圆算法:
i、编写圆算法程序:
选用算法:中点画圆算法
算法分析:
撇开直接从当前从 Xi/k 计算 Yi 的过程,而是从当前已获得的像素(xi,yi)递
推出后继的像素(xi+1,y(i+1))。
先算出第一象限内的八分之一圆弧,再根据圆的对称型算出其它象限的像素。
ii、算法程序:
//显示圆弧上的八个对称点:
void CirclePoints(CDC *pDC,int x0,int y0,int x,int y,COLORREF color)
{
pDC->SetPixel(x+x0,y+y0,color);
pDC->SetPixel(-x+x0,y+y0,color);
pDC->SetPixel(x+x0,-y+y0,color);
pDC->SetPixel(-x+x0,-y+y0,color);
pDC->SetPixel(-x+x0,-y+y0,color);
pDC->SetPixel(y+x0,x+y0,color);
pDC->SetPixel(-y+x0,x+y0,color);
pDC->SetPixel(y+x0,-x+y0,color);
pDC->SetPixel(-y+x0,-x+y0,color);
}
///////////////////////////////////////////////////////////////////////////////
//中点画圆算法:
void MidPointCircle(CDC *pDC, int x1, int y1, int x2, int y2, COLORREF color)
{
int r,x,y;
float d;
r=sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
x=0;
y=r;
d=5/4-r;
CirclePoints(pDC,x1, y1,x, y,color);
while(y>x){
if(d<=0)
d+=2*x+3;
else{
d+=2*(x-y)+5;
y--;
}
x++;
CirclePoints(pDC,x1, y1,x, y,color);
}//while 结束
}//MidPointCircle()函数结束
//OnLButtonUp(UINT nFlags, CPoint point)
case 2:
MidPointCircle(pDC,m_nPoint1.x,m_nPoint1.y,m_nPoint2.x,m_nPoint2.y,color);
break;
iii、编译、运行:
////////////////////////////////////////////////////////////////////////////////////////
曲线算法:
i、编写曲线算法程序:
选用算法:Bezier 曲线算法
算法分析:
三次 Bezier 曲线的定义式为:
3
0
i
P
i
BEZ
i
3,
)(
t
P(t)=
,t∈[0,1]