当前位置:文档之家› 计算机图形学实验z-buffer算法

计算机图形学实验z-buffer算法

计算机图形学实验z-buffer算法
计算机图形学实验z-buffer算法

实验六 9-7

一、实验题目

z-buffer 算法的代表性案例是绘制三个相互交叉的红绿蓝条,如图9-85所示,请使用MFC 编程实现。

二、实验思想

Z-Buffer 算法建立两个缓冲器:

深度缓冲器,用以存储图像空间中每一像素相应的深度值,初始化为最大深度值(z s 坐标)。

帧缓冲器,用以存储图像空间中的每个像素的颜色,初始化为屏幕的背景色。 ① 帧缓冲器初始值置为背景色。

② 确定深度缓冲器的宽度、高度和初始深度。一般将初始深度置为最大深度值。 ③ 对于多边形表面中的每一像素(x s ,y s ),计算其深度值z s (x s ,y s )。

④ 将z s (x s ,y s )与存储在z 缓冲器中该位置的深度值zBuffer (x s ,y s )进行比较。 ⑤ 如果z s (x s ,y s )

≤zBuffer (x s ,y s ),则将此像素的颜色写入帧缓冲器,且用z (x s ,y s )重置zbuffer (x s ,y s )。

三、实验代码

CZBuffer::~CZBuffer()

{

delete []P;

}

void CZBuffer::SetPoint(CPi3 p[],int m)

{

P=new CPi3[m];

for(int i=0;i

{

P[i]=p[i];

}

PNum=m;

}

void CZBuffer::CreateBucket()//创建桶表

{

int yMin,yMax;

yMin=yMax=P[0].y;

for(int i=0;i

{

if(P[i].y

{

yMin=P[i].y;//扫描线的最小值

}

if(P[i].y>yMax)

{

yMax=P[i].y;//扫描线的最大值

}

}

for(int y=yMin;y<=yMax;y++)

{

if(yMin==y)//建立桶头结点

{

HeadB=new CBucket;//建立桶的头结点

CurrentB=HeadB;//CurrentB为CBucket当前结点指针

CurrentB->ScanLine=yMin;

CurrentB->pET=NULL;//没有连接边链表

CurrentB->next=NULL;

}

else//建立桶的其它结点

{

CurrentB->next=new CBucket;

CurrentB=CurrentB->next;

CurrentB->ScanLine=y;

CurrentB->pET=NULL;

CurrentB->next=NULL;

}

}

}

void CZBuffer::CreateEdge()//创建边表

{

for(int i=0;i

{

CurrentB=HeadB;

int j=(i+1)%PNum;//边的第二个顶点,P[i]和P[j]构成边

if(P[i].y

{

Edge=new CAET;

Edge->x=P[i].x;//计算ET表的值

Edge->yMax=P[j].y;

Edge->k=(P[j].x-P[i].x)/(P[j].y-P[i].y);//代表1/k

Edge->pb=P[i];//绑定顶点和颜色

Edge->pe=P[j];

Edge->next=NULL;

while(CurrentB->ScanLine!=P[i].y)//在桶内寻找该边的yMin

{

CurrentB=CurrentB->next;//移到yMin所在的桶结点

}

}

if(P[j].y

{

Edge=new CAET;

Edge->x=P[j].x;

Edge->yMax=P[i].y;

Edge->k=(P[i].x-P[j].x)/(P[i].y-P[j].y);

Edge->pb=P[i];

Edge->pe=P[j];

Edge->next=NULL;

while(CurrentB->ScanLine!=P[j].y)

{

CurrentB=CurrentB->next;

}

}

if(int(P[j].y)!=P[i].y)

{

CurrentE=CurrentB->pET;

if(CurrentE==NULL)

{

CurrentE=Edge;

CurrentB->pET=CurrentE;

}

else

{

while(CurrentE->next!=NULL)

{

CurrentE=CurrentE->next;

}

CurrentE->next=Edge;

}

}

}

}

void CZBuffer::Gouraud(CDC *pDC)//填充多边形

{

double CurDeep=0.0;//当前扫描线的深度

double DeepStep=0.0;//当前扫描线随着x增长的深度步长

double A,B,C,D;//平面方程Ax+By+Cz+D=0的系数

CVector V21(P[1],P[2]),V10(P[0],P[1]);

CVector VN=V21*V10;

A=VN.X();B=VN.Y();C=VN.Z();

D=-A*P[1].x-B*P[1].y-C*P[1].z;

DeepStep=-A/C;//计算直线deep增量步长

CAET *T1,*T2;

HeadE=NULL;

for(CurrentB=HeadB;CurrentB!=NULL;CurrentB=CurrentB->next)

{

for(CurrentE=CurrentB->pET;CurrentE!=NULL;CurrentE=CurrentE->next) {

Edge=new CAET;

Edge->x=CurrentE->x;

Edge->yMax=CurrentE->yMax;

Edge->k=CurrentE->k;

Edge->pb=CurrentE->pb;

Edge->pe=CurrentE->pe;

Edge->next=NULL;

AddEt(Edge);

}

EtOrder();

T1=HeadE;

if(T1==NULL)

{

return;

}

while(CurrentB->ScanLine>=T1->yMax)//下闭上开{

T1=T1->next;

HeadE=T1;

if(HeadE==NULL)

return;

}

if(T1->next!=NULL)

{

T2=T1;

T1=T2->next;

}

while(T1!=NULL)

{

if(CurrentB->ScanLine>=T1->yMax)//下闭上开

{

T2->next=T1->next;

T1=T2->next;

}

else

{

T2=T1;

T1=T2->next;

}

}

CRGB Ca,Cb,Cf;//Ca、Cb代边上任意点的颜色,Cf代表面上任意点的颜色

Ca=Interpolation(CurrentB->ScanLine,HeadE->pb.y,HeadE->pe.y,HeadE->pb.c,He adE->pe.c);

Cb=Interpolation(CurrentB->ScanLine,HeadE->next->pb.y,HeadE->next->pe.y,He adE->next->pb.c,HeadE->next->pe.c);

BOOL Flag=FALSE;

double xb,xe;//扫描线的起点和终点坐标

for(T1=HeadE;T1!=NULL;T1=T1->next)

{

if(Flag==FALSE)

{

xb=T1->x;

CurDeep=-(xb*A+CurrentB->ScanLine*B+D)/C;//z=-(Ax+By-D)/C

Flag=TRUE;

}

else

{

xe=T1->x;

for(double x=xb;x

{

Cf=Interpolation(x,xb,xe,Ca,Cb);

if(CurDeep>=ZB[ROUND(x)+Width/2][CurrentB->ScanLine+Height/2])//如果新采样点的深度大于原采样点的深度

{

ZB[ROUND(x)+Width/2][CurrentB->ScanLine+Height/2]=CurDeep;//xy坐标与数组下标保持一致

pDC->SetPixel(ROUND(x),CurrentB->ScanLine,RGB(Cf.red*255,Cf.green*255,Cf.b lue*255));

}

CurDeep+=DeepStep;

}

Flag=FALSE;

}

}

for(T1=HeadE;T1!=NULL;T1=T1->next)//边的连续性

{

T1->x=T1->x+T1->k;

}

}

delete HeadB;

delete HeadE;

delete CurrentE;

delete CurrentB;

delete Edge;

}

void CZBuffer::AddEt(CAET *NewEdge)//合并ET表{

CAET *CE;

CE=HeadE;

if(CE==NULL)

{

HeadE=NewEdge;

CE=HeadE;

}

else

{

while(CE->next!=NULL)

{

CE=CE->next;

}

CE->next=NewEdge;

}

}

void CZBuffer::EtOrder()//边表的冒泡排序算法{

CAET *T1,*T2;

int Count=1;

T1=HeadE;

if(T1==NULL)

{

return;

}

if(T1->next==NULL)//如果该ET表没有再连ET表{

return;//桶结点只有一条边,不需要排序

}

while(T1->next!=NULL)//统计结点的个数

{

Count++;

T1=T1->next;

}

for(int i=1;i

{

T1=HeadE;

if(T1->x>T1->next->x)//按x由小到大排序

{

T2=T1->next;

T1->next=T1->next->next;

T2->next=T1;

HeadE=T2;

}

else

{

if(T1->x==T1->next->x)

{

if(T1->k>T1->next->k)//按斜率由小到大排序

{

T2=T1->next;

T1->next=T1->next->next;

T2->next=T1;

HeadE=T2;

}

}

}

T1=HeadE;

while(T1->next->next!=NULL)

{

T2=T1;

T1=T1->next;

if(T1->x>T1->next->x)//按x由小到大排序{

T2->next=T1->next;

T1->next=T1->next->next;

T2->next->next=T1;

T1=T2->next;

}

else

{

if(T1->x==T1->next->x)

{

if(T1->k>T1->next->k)//按斜率由小到大排序

{

T2->next=T1->next;

T1->next=T1->next->next;

T2->next->next=T1;

T1=T2->next;

}

}

}

}

}

}

CRGB CZBuffer::Interpolation(double t,double t1,double t2,CRGB c1,CRGB c2)//线性插值

{

CRGB c;

c=(t-t2)/(t1-t2)*c1+(t-t1)/(t2-t1)*c2;

return c;

}

void CZBuffer::InitDeepBuffer(int width,int height,double depth)//初始化深度缓冲

{

Width=width,Height=height;

ZB=new double *[Width];

for(int i=0;i

ZB[i]=new double[Height];

for(i=0;i

for(int j=0;j

ZB[i][j]=double(depth);

计算机图形学实验内容汇总

计算机图形学实验 肖加清

实验一图形学实验基础 一、实验目的 (1)掌握VC++绘图的一般步骤; (2)掌握OpenGL软件包的安装方法; (3)掌握OpenGL绘图的一般步骤; (4)掌握OpenGL的主要功能与基本语法。 二、实验内容 1、VC++绘图实验 (1)实验内容:以下是绘制金刚石图案。已给出VC++参考程序,但里面有部分错误,请改正,实现以下图案。 N=3 N=4

N=5 N=10 N=30

N=50 (2)参考程序 //自定义的一个类 //此代码可以放在视图类的实现文件(.cpp) 里class CP2 { public: CP2(); virtual ~CP2(); CP2(double,double); double x; double y; }; CP2::CP2() { this->x=0.0; this->y=0.0; } CP2::~CP2() { } CP2::CP2(double x0,double y0) { this->x=x0; this->y=y0; }

//视图类的一个成员函数,这个成员函数可以放在OnDraw函数里调用。 //在视图类的头文件(.h)里定义此函数 void Diamond(); //在视图类的实现文件(.cpp)里实现此函数 void CTestView::Diamond() { CP2 *P; int N; double R; R=300; N=10; P=new CP2[N]; CClientDC dc(this); CRect Rect; GetClientRect(&Rect); double theta; theta=2*PI/N; for(int i=0;i #include #include #include //定义输出窗口的大小 #define WINDOW_HEIGHT 300

计算机图形学实验报告 (2)

中南大学信息科学与工程学院 实验报告实验名称 实验地点科技楼四楼 实验日期2014年6月 指导教师 学生班级 学生姓名 学生学号 提交日期2014年6月

实验一Window图形编程基础 一、实验类型:验证型实验 二、实验目的 1、熟练使用实验主要开发平台VC6.0; 2、掌握如何在编译平台下编辑、编译、连接和运行一个简单的Windows图形应用程序; 3、掌握Window图形编程的基本方法; 4、学会使用基本绘图函数和Window GDI对象; 三、实验内容 创建基于MFC的Single Document应用程序(Win32应用程序也可,同学们可根据自己的喜好决定),程序可以实现以下要求: 1、用户可以通过菜单选择绘图颜色; 2、用户点击菜单选择绘图形状时,能在视图中绘制指定形状的图形; 四、实验要求与指导 1、建立名为“颜色”的菜单,该菜单下有四个菜单项:红、绿、蓝、黄。用户通过点击不同的菜单项,可以选择不同的颜色进行绘图。 2、建立名为“绘图”的菜单,该菜单下有三个菜单项:直线、曲线、矩形 其中“曲线”项有级联菜单,包括:圆、椭圆。 3、用户通过点击“绘图”中不同的菜单项,弹出对话框,让用户输入绘图位置,在指定位置进行绘图。

五、实验结果: 六、实验主要代码 1、画直线:CClientDC *m_pDC;再在OnDraw函数里给变量初始化m_pDC=new CClientDC(this); 在OnDraw函数中添加: m_pDC=new CClientDC(this); m_pDC->MoveTo(10,10); m_pDC->LineTo(100,100); m_pDC->SetPixel(100,200,RGB(0,0,0)); m_pDC->TextOut(100,100); 2、画圆: void CMyCG::LineDDA2(int xa, int ya, int xb, int yb, CDC *pDC) { int dx = xb - xa; int dy = yb - ya; int Steps, k; float xIncrement,yIncrement; float x = xa,y= ya; if(abs(dx)>abs(dy))

计算机图形学实验--橡皮筋技术(完整代码,准确无误)

计算机图形学上机实验报告 橡皮筋技术 计算机科学与技术学院 姓名: xxx 完成日期: 2010-12-7

实验:橡皮筋技术 一、实验目的与要求 实验目的:1.学会使用OpenGL,进一步掌握基本图形的绘制方法, 2.理解glut程序框架 3.理解窗口到视区的变换 4.理解OpenGL实现动画的原理 5.学会基于鼠标和键盘实现交互的实现方法 二、实验内容: 利用OpenGL实现折线和矩形的皮筋绘制技术,并采用右键菜单实现功能的选择 实现方法:1.橡皮筋技术的实现采用双缓存技术,绘制图形时分别绘制到两个缓存,交替显示。 2.右键菜单控制选择绘制折线还是绘制矩形,实现方法:通过菜单注册函数创建一个弹出式菜单,然后使用函数加入菜单项,最后使用函数讲菜单与鼠标右键关联起来,GLUT通过为菜单提供一个整数标识符实现对菜单的管理,在main主函数通过标识符用函数指定对应的菜单为当前的菜单。 2. 折线的橡皮筋绘制技术实现:鼠标所在位置确定一个点,移动鼠标时,每次移动时将点的信息保存在数组中,连接当前鼠标所在点和前一个点的直线段。 3.矩形的橡皮筋绘制技术:每个矩形由两个点唯一确定,鼠标当前点为第一个点,移动鼠标确定第二个点的位置,由这两点的坐标绘制出举行的四条边(直线段),矩形即绘制完毕。 三、实验结果

图鼠标右键菜单 图绘制矩形 四、体会 1> 经过这次实验,逐步对opengl软件有了一定的了解,而且对于理论知识有了很好的巩固,并非仅仅会C语言就能编写画图程序,gult程序有自己特殊的框架与实现过程.在这次试验中,虽然没有完全理解其原理,但在一定程度上已经为我们今后的学习应用打下了基础. 2>初步了解了如何在OpenGL实现基本的绘图功能,以及鼠标和键 盘灯交互设备的实现,还有如何由初始生成元绘制分形物体。在这个过 程中遇到了很多问题,程序的调试也是困难重重,通过自己看书思考和 老师、同学的帮助最终完成了程序的调试,在这一过程中加深了对理论 知识的理解,以及理清了理论到实践转换的一点点思路,再一次体会到 理论与实践的结合的重要性,今后要多多提高提高动手能力。

计算机图形学实验报告

《计算机图形学》实验报告姓名:郭子玉 学号:2012211632 班级:计算机12-2班 实验地点:逸夫楼507 实验时间:15.04.10 15.04.17

实验一 1 实验目的和要求 理解直线生成的原理;掌握典型直线生成算法;掌握步处理、分析实验数据的能力; 编程实现DDA 算法、Bresenham 中点算法;对于给定起点和终点的直线,分别调用DDA 算法和Bresenham 中点算法进行批量绘制,并记录两种算法的绘制时间;利用excel 等数据分析软件,将试验结果编制成表格,并绘制折线图比较两种算法的性能。 2 实验环境和工具 开发环境:Visual C++ 6.0 实验平台:Experiment_Frame_One (自制平台) 3 实验结果 3.1 程序流程图 (1)DDA 算法 是 否 否 是 是 开始 计算k ,b K<=1 x=x+1;y=y+k; 绘点 x<=X1 y<=Y1 绘点 y=y+1;x=x+1/k; 结束

(2)Mid_Bresenham 算法 是 否 否 是 是 是 否 是 否 开始 计算dx,dy dx>dy D=dx-2*dy 绘点 D<0 y=y+1;D = D + 2*dx - 2*dy; x=x+1; D = D - 2*dy; x=x+1; x

3.2程序代码 //-------------------------算法实现------------------------------// //绘制像素的函数DrawPixel(x, y); (1)DDA算法 void CExperiment_Frame_OneView::DDA(int X0, int Y0, int X1, int Y1) { //----------请实现DDA算法------------// float k, b; float d; k = float(Y1 - Y0)/float(X1 - X0); b = float(X1*Y0 - X0*Y1)/float(X1 - X0); if(fabs(k)<= 1) { if(X0 > X1) { int temp = X0; X0 = X1; X1 = temp; }

计算机图形学实验报告,DOC

欢迎共阅

目录

实验一直线的DDA算法 一、【实验目的】 1.掌握DDA算法的基本原理。 2.掌握 3. 1.利用 2.加强对 四 { glClearColor(1.0f,1.0f,1.0f,1.0f); glMatrixMode(GL_PROJECTION); gluOrtho2D(0.0,200.0,0.0,150.0); } voidDDALine(intx0,inty0,intx1,inty1) { glColor3f(1.0,0.0,0.0); intdx,dy,epsl,k; floatx,y,xIncre,yIncre; dx=x1-x0;dy=y1-y0;

x=x0;y=y0; if(abs(dx)>abs(dy))epsl=abs(dx); elseepsl=abs(dy); xIncre=(float)dx/(float)epsl; yIncre=(float)dy/(float)epsl; for(k=0;k<=epsl;k++) { glPointSize(3); glBegin(GL_POINTS); glEnd(); } } { } { } { glutInitWindowSize(400,300); glutInitWindowPosition(100,120); glutCreateWindow("line"); Initial(); glutDisplayFunc(Display); glutReshapeFunc(winReshapeFcn); glutMainLoop(); return0; }

计算机图形学实验报告

目录

实验一直线的DDA算法 一、【实验目的】 1.掌握DDA算法的基本原理。 2.掌握DDA直线扫描转换算法。 3.深入了解直线扫描转换的编程思想。 二、【实验内容】 1.利用DDA的算法原理,编程实现对直线的扫描转换。 2.加强对DDA算法的理解和掌握。 三、【测试数据及其结果】 四、【实验源代码】 #include #include #include #include GLsizei winWidth=500; GLsizei winHeight=500; void Initial(void)

{ glClearColor(1.0f,1.0f,1.0f,1.0f); glMatrixMode(GL_PROJECTION); gluOrtho2D(0.0,200.0,0.0,150.0); } void DDALine(int x0,int y0,int x1,int y1) { glColor3f(1.0,0.0,0.0); int dx,dy,epsl,k; float x,y,xIncre,yIncre; dx=x1-x0; dy=y1-y0; x=x0; y=y0; if(abs(dx)>abs(dy)) epsl=abs(dx); else epsl=abs(dy); xIncre=(float)dx/(float)epsl; yIncre=(float)dy/(float)epsl; for(k=0;k<=epsl;k++) { glPointSize(3); glBegin(GL_POINTS); glVertex2i(int(x+0.5),(int)(y+0.5)); glEnd(); x+=xIncre;

计算机图形学实验二

实验报告 课程名称:计算机图形学 实验项目:区域填充算法 实验仪器:计算机 系别:计算机学院 专业:计算机科学与技术 班级姓名:计科1602/ 学号:2016011 日期:2018-12-8 成绩: 指导教师:

一.实验目的(Objects) 1.实现多边形的扫描线填充算法。 二.实验内容 (Contents) 实现多边形的扫描线填充算法,通过鼠标,交互的画出一个多边形,然后利用种子填充算法,填充指定的区域。不能使用任何自带的填充区域函数,只能使用画点、画线函数或是直接对图像的某个像素进行赋值操作;

三.实验内容 (Your steps or codes, Results) //widget.cpp //2016CYY Cprogramming #include"widget.h" #include #include #include using namespace std; #define H 1080 #define W 1920 int click = 0; //端点数量 QPoint temp; QPoint first; int result = 1; //判断有没有结束 int sign = 1; //2为画线 int length = 5; struct edge { int ymax; float x; float dx; edge *next; }; edge edge_; QVector edges[H]; QVector points;//填充用 bool fin = false; QPoint *Queue = (QPoint *)malloc(length * sizeof(QPoint)); //存放端点的数组 Widget::Widget(QWidget *parent) : QWidget(parent) { } Widget::~Widget() { } void Widget::mouseMoveEvent(QMouseEvent *event) { setMouseTracking(true); if (click > 0 && result != 0) { startPt = temp; endPt =event->pos(); sign = 2; update(); } } void Widget::mouseReleaseEvent(QMouseEvent *event) { if (event->button() == Qt::LeftButton) { } else if (event->button() == Qt::RightButton) { sign = 2;

计算机图形学实验指导书1

佛山科学技术学院计算机图形学实验指导书 李晓东编 电信学院计算机系 2011年11月

实验1 直线段的扫描转换 实验类型:设计性 实验类别:专业实验 实验目的 1.通过实验,进一步理解直线段扫描转换的DDA算法、中点bresenham算法及 bresenham算法的基本原理; 2.掌握以上算法生成直线段的基本过程; 3.通过编程,会在C/C++环境下完成用DDA算法、中点bresenham算法及 bresenham算法对任意直线段的扫描转换。 实验设备及实验环境 计算机(每人一台) VC++6.0或其他C/C++语言程序设计环境 实验学时:2学时 实验内容 用DDA算法中点bresenham算法及bresenham算法实现任意给定两点的直线段的绘制(直线宽度和线型可自定)。 实验步骤: 1、复习有关算法的基本原理,明确实验目的和要求; 2、依据算法思想,绘制程序流程图; 3、设计程序界面,要求操作方便; 4、用C/C++语言编写源程序并调试、执行; 5、分析实验结果 6、对程序设计过程中出现的问题进行分析与总结; 7、打印源程序或把源程序以文件的形式提交; 8、按格式要求完成实验报告。 实验报告要求: 1、各种算法的基本原理; 2、各算法的流程图 3、实验结果及分析(比较三种算法的特点,界面插图并注明实验条件) 4、实验总结(含问题分析及解决方法)

实验2 圆的扫描转换 实验类型:设计性 实验类别:专业实验 实验目的 1、通过实验,进一步理解和掌握中点bresenham画圆算法的基本原理; 2、掌握以上算法生成圆和圆弧的基本过程; 3、掌握在C/C++环境下完成用中点bresenham算法圆或圆弧的绘制方法。实验设备及实验环境 计算机(每人一台) VC++6.0或其他C/C++语言程序设计环境 实验学时:2学时 实验内容 用中点(Besenham)算法实现圆或圆弧的绘制。 实验步骤 1.复习有关圆的生成算法,明确实验目的和要求; 2.依据算法思想,绘制程序流程图(注意圆弧生成时的输入条件); 3.设计程序界面,要求操作方便; 4.用C/C++语言编写源程序并调试、执行; 5.分析实验结果 6.对程序设计过程中出现的问题进行分析与总结; 7.打印源程序或把源程序以文件的形式提交; 8.按格式要求完成实验报告。 实验报告要求: 1.分析算法的工作原理; 2.画出算法的流程图 3.实验结果及分析(比较圆与圆弧生成算法的不同) 4.实验总结(含问题分析及解决方法)

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

一、实验目的 1、掌握中点Bresenham直线扫描转换算法的思想。 2掌握边标志算法或有效边表算法进行多边形填充的基本设计思想。 3掌握透视投影变换的数学原理和三维坐标系中几何图形到二维图形的观察流程。 4掌握三维形体在计算机中的构造及表示方法 二、实验环境 Windows系统, VC6.0。 三、实验步骤 1、给定两个点的坐标P0(x0,y0),P1(x1,y1),使用中点Bresenham直线扫描转换算法画出连接两点的直线。 实验基本步骤 首先、使用MFC AppWizard(exe)向导生成一个单文档视图程序框架。 其次、使用中点Bresenham直线扫描转换算法实现自己的画线函数,函数原型可表示如下: void DrawLine(CDC *pDC, int p0x, int p0y, int p1x, int p1y); 在函数中,可通过调用CDC成员函数SetPixel来画出扫描转换过程中的每个点。 COLORREF SetPixel(int x, int y, COLORREF crColor ); 再次、找到文档视图程序框架视图类的OnDraw成员函数,调用DrawLine 函数画出不同斜率情况的直线,如下图:

最后、调试程序直至正确画出直线。 2、给定多边形的顶点的坐标P0(x0,y0),P1(x1,y1),P2(x2,y2),P3(x3,y3),P4(x4,y4)…使用边标志算法或有效边表算法进行多边形填充。 实验基本步骤 首先、使用MFC AppWizard(exe)向导生成一个单文档视图程序框架。 其次、实现边标志算法或有效边表算法函数,如下: void FillPolygon(CDC *pDC, int px[], int py[], int ptnumb); px:该数组用来表示每个顶点的x坐标 py :该数组用来表示每个顶点的y坐标 ptnumb:表示顶点个数 注意实现函数FillPolygon可以直接通过窗口的DC(设备描述符)来进行多边形填充,不需要使用帧缓冲存储。(边标志算法)首先用画线函数勾画出多边形,再针对每条扫描线,从左至右依次判断当前像素的颜色是否勾画的边界色,是就开始填充后面的像素直至再碰到边界像素。注意对顶点要做特殊处理。 通过调用GDI画点函数SetPixel来画出填充过程中的每个点。需要画线可以使用CDC的画线函数MoveTo和LineTo进行绘制,也可以使用实验一实现的画直线函数。 CPoint MoveTo(int x, int y ); BOOL LineTo(int x, int y ); 实现边标志算法算法需要获取某个点的当前颜色值,可以使用CDC的成员函数 COLORREF GetPixel(int x, int y ); 再次、找到文档视图程序框架视图类的OnDraw成员函数,调用FillPolygon 函数画出填充的多边形,如下: void CTestView::OnDraw(CDC* pDC) { CTestcoodtransDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc);

计算机图形学课程参考文献

《计算机图形学》课程参考文献 [1 Kenneth R. Castleman, “Digital Image Processing”, Prentice-Hall International,Inc, 1996 [2] James Sharman. The Marching Cubes Algorithm[EB]. https://www.doczj.com/doc/257891801.html,/. [3] William E. Lorensen, Harvey E. Cline. Marching Cubes: A High Resolution 3D Surface Construction Algrorithm[J].Computer Graphics, 1987, 21(4). [4] Jan Horn. Metaballs程序[CP]. http://www.sulaco.co.za. [5] 唐泽圣,等.三维数据场可视化[M].北京:清华大学出版社,1999.177-179. [6] 白燕斌,史惠康,等.OpenGL三维图形库编程指南[M].北京:机械工业出版社,1998. [7] 费广正,芦丽丹,陈立新.可视化OpenGL程序设计[M].北京:清华大学出版社,2001. [8] 田捷,包尚联,周明全.医学影像处理与分析[M].北京:电子工业出版社,2003. [9] 三维表面模型的重构、化简、压缩及其在计算机骨科手术模拟中的应用[R]. https://www.doczj.com/doc/257891801.html,/~yike/uthesis.pdf ; [10] 首套中国数字化可视人体二维图像[DB]. http://www.chinesevisiblehuman. com/ pic/pictype.asp [11] 季雪岗,王晓辉,张宏林,等.Delphi编程疑难详解[M].北京:人民邮电出版社,2000. [12] 郑启华.PASCAL程序设计(第二版)[M].北京:清华大学出版社,1996. [13] 涂晓斌,谢平,陈海雷,蒋先刚.实用微机工程绘图实验教程[M].西南交通大学出版社,2004,4. [14] David F.Rogers.计算机图形学算法基础[M].北京:电子工业出版社,2002. [15] 李信真,车刚明,欧阳洁,封建湖.计算方法[M].西安:西北工业大学出版社,2000. [16] Paul Bourke Polygonising a scalar field [CP]. http://astronomy. https://www.doczj.com/doc/257891801.html,.au/ ~pbourke/ modelling/polygonise/ [17] 刘骏.Delphi数字图像处理及高级应用[M].北京:科学出版社,2003. [18] 李弼程,彭天强,彭波,等.智能图像处理技术[M].北京:电子工业出版社,2004. [19] Kenneth R.Castleman著,朱志刚,石定机,等译.数字图像处理[M].北京:电子工业出版社,2002. [20] Milan Sonka, Vaclav Hlavac, Roger Boyle.Image Processing, Analysis, and Machine Vision [M].北京:人民邮电出版社,2003. [21] 阮秋奇.数字图像处理学[M]. 北京:电子工业出版社, 2001. [22] 刘宏昆,等.Delphi应用技巧与常见问题[M]. 北京:机械工业出版社, 2003. [23] 张增强,李鲲程,等.专家门诊—Delphi开发答疑300问[M].北京:人民邮电出版社,2003.6.

计算机图形学实验C++代码

一、bresenham算法画直线 #include #include #include void draw_pixel(int ix,int iy) { glBegin(GL_POINTS); glVertex2i(ix,iy); glEnd(); } void Bresenham(int x1,int y1,int xEnd,int yEnd) { int dx=abs(xEnd-x1),dy=abs(yEnd-y1); int p=2*dy-dx; int twoDy=2*dy,twoDyMinusDx=2*dy-2*dx; int x,y; if (x1>xEnd) { x=xEnd;y=yEnd; xEnd=x1; } else { x=x1; y=y1; } draw_pixel(x,y); while(x

} void myinit() { glClearColor(0.8,1.0,1.0,1.0); glColor3f(0.0,0.0,1.0); glPointSize(1.0); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0.0,500.0,0.0,500.0); } void main(int argc,char **argv ) { glutInit(&argc,argv); glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB); glutInitWindowSize(500,500); glutInitWindowPosition(200.0,200.0); glutCreateWindow("CG_test_Bresenham_Line example"); glutDisplayFunc(display); myinit(); glutMainLoop(); } 二、中点法绘制椭圆 #include #include #include inline int round(const float a){return int (a+0.5);} void setPixel(GLint xCoord,GLint yCoord) { glBegin(GL_POINTS); glVertex2i(xCoord,yCoord); glEnd(); } void ellipseMidpoint(int xCenter,int yCenter,int Rx,int Ry) { int Rx2=Rx*Rx; int Ry2=Ry*Ry; int twoRx2=2*Rx2; int twoRy2=2*Ry2; int p; int x=0; int y=Ry; int px=0; int py=twoRx2*y; void ellipsePlotPoints(int,int,int,int);

一种基于计算几何方法的最小包容圆求解算法.kdh

2007年 工 程 图 学 学 报2007 第3期 JOURNAL OF ENGINEERING GRAPHICS No.3一种基于计算几何方法的最小包容圆求解算法 张 勇, 陈 强 (清华大学机械工程系先进成形制造重点实验室,北京 100084) 摘要:为实现点集最小包容圆(最小外接圆)的求解,将计算几何中的α-壳的概 念应用到最小包容圆的计算过程,提出了一种精确有效的最小包容圆求解算法。根据α-壳定 义及最小包容圆性质,证明当1/α等于最小包容圆半径时点集的α-壳顶点共圆,1/α小于最小 包容圆半径时α-壳不存在,1/α大于最小包容圆半径时随着1/α减小α-壳顶点数逐渐减小的规 律。将α-壳顶点数目作为搜索最小包容圆半径的依据,实现了最小包容圆半径的搜索和最小包容圆的求解。 关键词:计算机应用;优化算法;计算几何;最小包容圆;α-壳 中图分类号:TP 391 文献标识码:A 文章编号:1003-0158(2007)03-0097-05 Algorithm for Minimum Circumscribed Circle Detection Based on Computational Geometry Technique ZHANG Yong, CHEN Qiang ( Key Laboratory for Advanced Manufacturing by Materials Processing Technology, Department of Mechanical Engineering, Tsinghua University, Beijing 100084, China ) Abstract: α-hulls are applied to calculate the minimum circumscribed circle (MCC) of point set and an accurate and effective method for MCC detection is established through finding the least squares circle of the point set and iteratively approaching the MCC with recursive subdivision. Several theorems concerning the properties of α-hulls are presented. If 1/α is equal to the radius of points’ MCC, all vertices of the α-hull will be on the same circle. When 1/α is larger than the MCC’s radius, the number of vertices of α-hulls will decrease with decreasing of 1/α, and the number of vertices’ number will reach zero when 1/α is smaller than MCC’s radius. From the above rules, an algorithm for detecting MCC is developed, and experimental results show this algorithm is reliable. Key words: computer application; optimized algorithm; computational geometry; minimum circumscribed circle; α-hull 收稿日期:2005-12-20 基金项目:国家自然科学基金资助项目(50275083);高校博士点基金资助项目(20020003053)

计算机图形学上机实验指导

计算机图形学上机实验指导 指导教师:张加万老师 助教:张怡 2009-10-10

目录 1.计算机图形学实验(一) – OPENGL基础 ..................................... - 1 - 1.1综述 (1) 1.2在VC中新建项目 (1) 1.3一个O PEN GL的例子及说明 (1) 2.计算机图形学实验(二) – OPENGL变换 ..................................... - 5 - 2.1变换 (5) 3.计算机图形学实验(三) - 画线、画圆算法的实现....................... - 9 - 3.1MFC简介 (9) 3.2VC6的界面 (10) 3.3示例的说明 (11) 4.计算机图形学实验(四)- 高级OPENGL实验...................... - 14 - 4.1光照效果 (14) 4.2雾化处理 (16) 5.计算机图形学实验(五)- 高级OPENGL实验........................ - 20 - 5.1纹理映射 (20) 5.2反走样 (24) 6.计算机图形学实验(六) – OPENGL IN MS-WINDOWS .......... - 27 - 6.1 实验目标: (27) 6.2分形 (28)

1.计算机图形学实验(一) – OpenGL基础 1.1综述 这次试验的目的主要是使大家初步熟悉OpenGL这一图形系统的用法,编程平台是Visual C++,它对OpenGL提供了完备的支持。 OpenGL提供了一系列的辅助函数,用于简化Windows操作系统的窗口操作,使我们能把注意力集中到图形编程上,这次试验的程序就采用这些辅助函数。 本次实验不涉及面向对象编程,不涉及MFC。 1.2在VC中新建项目 1.2.1新建一个项目 选择菜单File中的New选项,弹出一个分页的对话框,选中页Projects中的Win32 Console Application项,然后填入你自己的Project name,如Test,回车即可。VC为你创建一个工作区(WorkSpace),你的项目Test就放在这个工作区里。 1.2.2为项目添加文件 为了使用OpenGL,我们需要在项目中加入三个相关的Lib文件:glu32.lib、glaux.lib、opengl32.lib,这三个文件位于c:\program files\microsoft visual studio\vc98\lib目录中。 选中菜单Project->Add To Project->Files项(或用鼠标右键),把这三个文件加入项目,在FileView中会有显示。这三个文件请务必加入,否则编译时会出错。或者将这三个文件名添加到Project->Setting->Link->Object/library Modules 即可。 点击工具条中New Text File按钮,新建一个文本文件,存盘为Test.c作为你的源程序文件,再把它加入到项目中,然后就可以开始编程了。 1.3一个OpenGL的例子及说明 1.3.1源程序 请将下面的程序写入源文件Test.c,这个程序很简单,只是在屏幕上画两根线。 #include

计算机图形学 实验一:生成彩色立方体(含源代码)

实验一 实验目的:生成彩色立方体 实验代码://ColorCube1.java import java.applet.Applet; //可以插入html import java.awt.BorderLayout; //窗口采用BorderLayout方式布局import com.sun.j3d.utils.applet.MainFrame; //application import com.sun.j3d.utils.geometry.ColorCube;//调用生成ColorCube的Utility import com.sun.j3d.utils.geometry.Primitive; import com.sun.j3d.utils.universe.*; //观测位置的设置 import javax.media.j3d.*; //核心类 import javax.vecmath.*; //矢量计算 import com.sun.j3d.utils.behaviors.mouse.*; public class ColorCube1 extends Applet { public BranchGroup createSceneGraph() { BranchGroup objRoot=new BranchGroup(); //BranchGroup的一个对象objRoot(放置背景、灯光)BoundingSphere bounds=new BoundingSphere(new Point3d(0.0,0.0,0.0),100.0);//有效范围 TransformGroup objTrans=new TransformGroup(); objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); objRoot.addChild(objTrans); MouseRotate behavior = new MouseRotate(); behavior.setTransformGroup(objTrans); objRoot.addChild(behavior); behavior.setSchedulingBounds(bounds); MouseZoom behavior2 = new MouseZoom(); behavior2.setTransformGroup(objTrans); objRoot.addChild(behavior2); behavior2.setSchedulingBounds(bounds); MouseTranslate behavior3 = new MouseTranslate(); behavior3.setTransformGroup(objTrans); objRoot.addChild(behavior3); behavior3.setSchedulingBounds(bounds);

计算机图形学实验报告

计算机图形学 实验报告 学号:20072115 姓名: 班级:计算机 2班 指导老师:何太军 2010.6.19

实验一、Windows 图形程序设计基础 1、实验目的 1)学习理解Win32 应用程序设计的基本知识(SDK 编程); 2)掌握Win32 应用程序的基本结构(消息循环与消息处理等); 3)学习使用VC++编写Win32 Application 的方法。 4)学习MFC 类库的概念与结构; 5)学习使用VC++编写Win32 应用的方法(单文档、多文档、对话框); 6)学习使用MFC 的图形编程。 2、实验内容 1)使用WindowsAPI 编写一个简单的Win32 程序,调用绘图API 函数绘制若干图形。(可选任务) 2 )使用MFC AppWizard 建立一个SDI 程序,窗口内显示"Hello,This is my first SDI Application"。(必选任务) 3)利用MFC AppWizard(exe)建立一个SDI 程序,在文档视口内绘制基本图形(直线、圆、椭圆、矩形、多边形、曲线、圆弧、椭圆弧、填充、文字等),练习图形属性的编程(修改线型、线宽、颜色、填充样式、文字样式等)。定义图形数据结构Point\Line\Circle 等保存一些简单图形数据(在文档类中),并在视图类OnDraw 中绘制。 3、实验过程

1)使用MFC AppWizard(exe)建立一个SDI 程序,选择单文档; 2)在View类的OnDraw()函数中添加图形绘制代码,说出字符串“Hello,This is my first SDI Application”,另外实现各种颜色、各种边框的线、圆、方形、多边形以及圆弧的绘制; 3)在类视图中添加图形数据point_pp,pp_circle的类,保存简单图形数据,通过在OnDraw()函数中调用,实现线、圆的绘制。 4、实验结果 正确地在指定位置显示了"Hello,This is my first SDI Application"字符串,成功绘制了圆,椭圆,方形,多边形以及曲线圆弧、椭圆弧,同时按指定属性改绘了圆、方形和直线。成功地完成了实验。 结果截图: 5、实验体会 通过实验一,了解了如用使用基本的SDI编程函数绘制简单的图

计算机图形学实验报告

计算机图形学 实验报告 姓名:谢云飞 学号:20112497 班级:计算机科学与技术11-2班实验地点:逸夫楼507 实验时间:2014.03

实验1直线的生成 1实验目的和要求 理解直线生成的原理;掌握典型直线生成算法;掌握步处理、分析 实验数据的能力; 编程实现DDA算法、Bresenham中点算法;对于给定起点和终点的 直线,分别调用DDA算法和Bresenham中点算法进行批量绘制,并记 录两种算法的绘制时间;利用excel等数据分析软件,将试验结果编 制成表格,并绘制折线图比较两种算法的性能。 2实验环境和工具 开发环境:Visual C++ 6.0 实验平台:Experiment_Frame_One(自制平台)。 本实验提供名为 Experiment_Frame_One的平台,该平台提供基本 绘制、设置、输入功能,学生在此基础上实现DDA算法和Mid_Bresenham 算法,并进行分析。 ?平台界面:如错误!未找到引用源。所示 ?设置:通过view->setting菜单进入,如错误!未找到引 用源。所示 ?输入:通过view->input…菜单进入.如错误!未找到引用 源。所示 ?实现算法: ◆DDA算法:void CExperiment_Frame_OneView::DDA(int X0, int Y0, int X1, int Y1) Mid_Bresenham法:void CExperiment_Frame_OneView::Mid_Bresenham(int X0, int Y0, int X1, int Y1)

3实验结果 3.1程序流程图 1)DDA算法流程图:开始 定义两点坐标差dx,dy,以及epsl,计数k=0,描绘点坐标x,y,x增 量xIncre,y增量yIncre ↓ 输入两点坐标x1,y1,x0,y0 ↓ dx=x1-x0,dy=y1-y0; _________↓_________ ↓↓ 若|dx|>|dy| 反之 epsl=|dx| epsl=|dy| ↓________...________↓ ↓ xIncre=dx/epsl; yIncre=dy/epsl ↓ 填充(强制整形)(x+0.5,y+0.5); ↓←←←← 横坐标x+xIncre; 纵坐标y+yIncre; ↓↑ 若k<=epsl →→→k++ ↓ 结束 2)Mid_Bresenham算法流程图开始 ↓ 定义整形dx,dy,判断值d,以及UpIncre,DownIncre,填充点x,y ↓ 输入x0,y0,x1,y1 ______↓______ ↓↓ 若x0>x1 反之 x=x1;x1=x0;x0=x; x=x0;

相关主题
文本预览
相关文档 最新文档