文档库 最新最全的文档下载
当前位置:文档库 › 计算机图形学实验报告

计算机图形学实验报告

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

计算机图形学实验报告

第一次

目录

1.实验目的 (3)

2.实验内容 (3)

2.1.Bresenham画直线算法 (3)

2.2.Bresenham画圆算法 (3)

2.3.Bresenham画椭圆算法 (4)

2.4.多边形阴影线填充算法 (5)

2.5.多边形扫描转换算法 (5)

3.实验步骤 (6)

3.1.程序设计 (6)

3.1.1.画线段 (7)

3.1.2.画圆 (8)

3.1.3.画椭圆 (10)

3.1.4.多边形阴影线填充 (11)

3.1.5.多边形区域扫描填充 (15)

3.2.程序运行结果 (24)

3.2.1.画直线 (24)

3.2.2.画圆 (25)

3.2.3.画椭圆 (25)

3.2.4.多边形阴影线填充 (26)

3.2.5.多边形区域扫描填充 (27)

4.实验总结 (28)

1.实验目的

仅调用画点函数,设计实现一个图形函数库,具有以下功能:

1.画线段。

2.画圆弧。

3.画椭圆。

4.画多边形。

5.多边形区域的阴影线填充。

6.多边形扫描转换算法:颜色填充。

实验环境:DevC++

实验语言:C语言

2.实验内容

此次实验目的采用了以下算法实现。

2.1.Bresenham画直线算法

根据直线的斜率确定选择X或者Y方向作为计长方向, 在此方向上每次递增一个单位步长(或者一个像素单位), 另一个方向上是否同时产生一个单位增量由一个计算量很小的判别式来判断。

(以斜率在0~1之间的直线段为例)

这种情况下, 选择X方向为计长方向,即增量dx=1。

如下图所示,设P i(x i,y i)是已选定的离直线最近的像素, 现在要决定P i+1是T还是S。

若d<0.5, 则S比较靠近直线, 应选S;

若d>=0.5, 则应选T。(m=△y/△x)

令e=d-0.5(初值为m-0.5), 即有:

e<0时,选P i+1(x i+1,y i), 更新e=e+m;

e>=0时,选P i+1(x i+1,y i+1), 更新e=e+m-1。

2.2.Bresenham画圆算法

与Bresenham直线生成算法一样, 其基本方法是从一个起点出发, 利用判别式选择下一个显示点。判别式的值通过简单计算获得, 其符号用作判断。

(以位于第一象限的1/8圆弧为例)

此算法在每一步都选择一个离开理想圆周最近的点P i(x i,y i),使其误差项

|D(P i)|=|x i2 +y i2-R2|在每一步都是极小值。

设P i-1(x i-1,y i-1)已被选定为最靠近圆弧的点,下一步x=x i-1+1时, 参见下图:

要决定T还是S更接近理想的圆弧,令

D(S)=(x i-1+1)2+y i-12-R2

D(T)=(x i-1+1)2+(y i-1-1)2-R2

显然,|D(S)|>=|D(T)|时,应该取T点,反之则取S点。即若令

d i=|D(S)|-|D(T)|

则d i>=0,选择T点,否则选取S点。

结论:

d1=3-2R;

如果d i<0,选P i(x i,y i-1),将y i=y i-1代入求d i+1:

d i+1=d i+4x i+2=d i+4x i-1+6

如果d i>=0,选Pi(x i,y i-1-1),将y i=y i-1-1代入求d i+1:

d i+1=d i+4x i-4y i-1+6=d i+4(x i-1-y i-1)+10

2.3.Bresenham画椭圆算法

与Bresenham直线和圆生成算法原理一样,但是椭圆的生成的过程中要分为上半部与下半部的情况讨论。

在生成椭圆上部区域时,以x轴为步进方向,如图所示:

x每步进一个单位,就需要在判断y保持不变还是也步进减1,bresenham算法定义判别式为:

d i=d1-d2

如果d i<0,则取P1为下一个点,否则,取P2为下一个点。采用判别式d i,使得判别式规约为全整数运算,算法效率得到了很大的提升。根据椭圆方程,可以计算出d1和d2分别是:

d1=a2(y i2-y2)

d2=a2(y2-y i+12)

以(0,b)作为椭圆上部区域的起点,将其代入判别式d i可以得到如下递推关系:

当d i<0时,d i+1=d i+2b2(2x i+3)

当d i>=0时,d i+1=d i+2b2(2x i+3)-4a2(y i-1)

d1= 2b2–2a2b+a2

在生成椭圆下部区域时,以y轴为步进方向,如图所示:

y每步进减一个单位,就需要在判断x保持不变还是步进加一个单位,对于下部区域,计算出d1和d2分别是:

d1=b2(x i+12-x2)

d2=b2(x2-x i2)

以(x p,y p)作为椭圆下部区域的起点,将其代入判别式d i可以得到如下递推关系:

当d i<0时,d i+1= d i-4a2(y i-1)+2a2

当d i>=0时,d i+1= d i+2b2(x i+1)-4a2(y-1)+2a2+b2

d1=b2(x p+1)2+b2x p2-2a2b2+2a2(y p-1)2

2.4.多边形阴影线填充算法

算法步骤如下:

a.对于MN条棱边, 计算每一条棱边L i 的两个端点分别按阴影线斜率k=tgα引线得到的截距, 其中较小值放在B(1,i)中, 较大值放在B(2,i)中。

b.求出B min=minB(1,i),B max=maxB(2,i),i=1,2,...,MN。

c.取第一条阴影线截距为b=B min+△b(△b=h/|cosα|)。

d.初始化存放阴影线与各棱边交点的数组D(2,MN);判断当前阴影线与各棱边是否有交点, 若存在则计算出交点坐标并存入D数组;

按X/Y坐标排列D数组中的交点并生成阴影线段;

取下一条阴影线b=b+△b, 若b≠B max转d继续。

2.5.多边形扫描转换算法

算法步骤如下:

a. 非极值奇点的预处理。(极值奇点算作2个交点;非极值奇点算作1个交点)

b. 建立边的分类表ET。

c. 取扫描线初始值y为ET表中所列的最小y坐标值。

d. 边的活化链表AEL初始化, 使其为空。

e. 重复下列操作, 直至ET表和AEL表都变成空:

e1. 把ET表中纵坐标为y的链取下, 与AEL表合并,并保持AEL表中元素按x域值升序排列,x相同时,按△x域。

e2. 对于当前扫描线y, 从左到右, 将AEL表中元素两两配对,按每对两个x域定义的区段填充所需要的像素值。

e3. 将AEL表中满足y max=y的元素删除;

e4. 对于仍留在AEL表中的元素, 求下一条扫描线与边的交点, 即x域累加△x:

x=x+ △x。

e5. 取下一条扫描线作为当前扫描线:y=y+1。

3.实验步骤

3.1.程序设计

函数库的声明部分如下:

#include

#include

#include

#include

#define PI 3.1416

#define DEF -10000

#define MAX 100

struct list{

int ymax;

double x;

double dx;

struct list *next;

};

struct head{

int num;

struct list *start;

struct list *end;

};

typedef struct list L;

typedef struct head H;

typedef L * LP;

void DrawLine(HDC hdc,int x1,int y1,int x2,int y2,COLORREF color);

void DrawCircle(HDC hdc,int xc,int yc,int r,COLORREF color);

void DrawEllipse(HDC hdc,int xc,int yc,int a,int b,COLORREF color);

void DrawPolygon(HDC hdc,int p[][MAX],int point_num,int in_num,COLORREF color);

void PolygonShadow(HDC hdc,int p[][MAX],int point_num,int in_num,double a,int h,COLORREF color);

void PolygonFill(HDC hdc,int p[][MAX],int point_num,int in_num,COLORREF color);

void PlotC(HDC hdc,int x,int y,int xc,int yc,COLORREF color);

void PlotE(HDC hdc,int x,int y,int xc,int yc,COLORREF color);

int LineIntersection(double k,int b,int x1,int y1,int x2,int y2);

void SortPoint(int d[][MAX],int d_num);

void PreProcessing(int p[][MAX],int point_num,int in_num);

int CreateET(int p[][MAX],int point_num,int in_num,int ymin,H ET[]); LP InsertList(int x1,int y1,int x2,int y2,LP h,LP *t);

LP DeleteList(LP head,LP current,LP *tail);

LP SortAEL(LP head);

各个函数与数据结构的定义见下文。

3.1.1.画线段

将2.1里提到的算法思想推广到所有象限,设计函数

void DrawLine(HDC hdc,int x1,int y1,int x2,int y2,COLORREF color) 其中参数意义如下:

HDC hdc 画图界面

int x1 线段一端横坐标

int y1 线段一端纵坐标

int x2 线段一端横坐标

int y2 线段一端横坐标

COLORREF color 直线的颜色

该部分实现代码如下:

void DrawLine(HDC hdc,int x1,int y1,int x2,int y2,COLORREF color) {

int i,interchange,s1,s2;

int x,y,dx,dy,dxy,d;

x=x1;

y=y1;

dx=abs(x2-x1);

dy=abs(y2-y1);

if(x2-x1>0){

s1=1;

}

else{

s1=-1;

}

if(y2-y1>0){

s2=1;

}

else{

s2=-1;

}

if(dy>dx){

dxy=dx;

dx=dy;

dy=dxy;

interchange=1;

}

else{

interchange=0;

}

d=2*dy-dx;

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

SetPixel(hdc,x,y,color);

while(d>=0){

if(interchange==1){

x=x+s1;

}

else{

y=y+s2;

}

d=d-2*dx;

}

if(interchange==1){

y=y+s2;

}

else{

x=x+s1;

}

d=d+2*dy;

}

}

3.1.2.画圆

将2.2中提到的算法思想根据圆的对称性推广到所有象限,其中函数void PlotC(HDC hdc,int x,int y,int xc,int yc,COLORREF color)

是根据圆的对称性画8个点的辅助函数。

其参数意义如下:

HDC hdc 画图界面

int x 当前扫描的点相对圆心的横坐标距离

int y 当前扫描的点相对圆心的纵坐标距离

int xc 圆心横坐标

int yc 圆心纵坐标

COLORREF color 圆的颜色

执行画圆的函数为

void DrawCircle(HDC hdc,int xc,int yc,int r,COLORREF color) 其参数意义如下:

HDC hdc 画图界面

int xc 圆心横坐标

int yc 圆心纵坐标

int r 圆的半径

COLORREF color 圆的颜色

该部分实现代码如下:

void PlotC(HDC hdc,int x,int y,int xc,int yc,COLORREF color) {

SetPixel(hdc,xc+x,yc+y,color);

SetPixel(hdc,xc+x,yc-y,color);

SetPixel(hdc,xc-x,yc+y,color);

SetPixel(hdc,xc-x,yc-y,color);

SetPixel(hdc,xc+y,yc+x,color);

SetPixel(hdc,xc+y,yc-x,color);

SetPixel(hdc,xc-y,yc+x,color);

SetPixel(hdc,xc-y,yc-x,color);

}

void DrawCircle(HDC hdc,int xc,int yc,int r,COLORREF color) {

int x,y,d;

y=r;

d=3-2*r;

x=0;

while(x<=y){

PlotC(hdc,x,y,xc,yc,color);

if(d<0){

d=d+4*x+6;

}

else{

d=d+4*(x-y)+10;

y--;

}

x++;

}

}

3.1.3.画椭圆

将2.3中提到的算法思想根据椭圆的对称性推广到所有象限,其中函数void PlotE(HDC hdc,int x,int y,int xc,int yc,COLORREF color)

是根据椭圆的对称性画4个点的辅助函数。

其参数意义如下:

HDC hdc 画图界面

int x 当前扫描的点相对椭圆心的横坐标距离

int y 当前扫描的点相对椭圆心的纵坐标距离

int xc 椭圆心横坐标

int yc 椭圆心纵坐标

COLORREF color 椭圆的颜色

执行画椭圆的函数为

void DrawEllipse(HDC hdc,int xc,int yc,int a,int b,COLORREF color)

其参数意义如下:

HDC hdc 画图界面

int xc 椭圆心横坐标

int yc 椭圆心纵坐标

int a 椭圆的长半轴长

int b 椭圆的短半轴长

COLORREF color 圆的颜色

该部分实现代码如下:

void PlotE(HDC hdc,int x,int y,int xc,int yc,COLORREF color)

{

SetPixel(hdc,xc+x,yc+y,color);

SetPixel(hdc,xc+x,yc-y,color);

SetPixel(hdc,xc-x,yc+y,color);

SetPixel(hdc,xc-x,yc-y,color);

}

void DrawEllipse(HDC hdc,int xc,int yc,int a,int b,COLORREF color)

{

int x,y,d,e;

y=b;

d=2*b*b-2*b*a*a+a*a;

x=0;

PlotE(hdc,x,y,xc,yc,color);

e=(int)((double)(a*a)/sqrt((double)(a*a+b*b)));

while(x<=e){

if(d<0){

d=d+2*b*b*(2*x+3);

}

else{

d=d+2*b*b*(2*x+3)-4*a*a*(y-1);

y--;

}

x++;

PlotE(hdc,x,y,xc,yc,color);

}

d=b*b*(x*x+x)+a*a*(y*y-y)-a*a*b*b;

while(y>=0){

PlotE(hdc,x,y,xc,yc,color);

y--;

if(d<0){

x++;

d=d-2*a*a*y-a*a+2*b*b*x+2*b*b;

}

else{

d=d-2*a*a*y-a*a;

}

}

}

3.1.

4.多边形阴影线填充

程序设计基于2.4中的算法原理。

该算法首先要画出多边形,执行画多边形的函数为

void DrawPolygon(HDC hdc,int p[][MAX],int point_num,int in_num,COLORREF color)

该函数遍历了多边形的各个定点,通过调用画线段函数

void DrawLine(HDC hdc,int x1,int y1,int x2,int y2,COLORREF color)

来达到效果(画线段函数详见3.1.1)。

该画多边形函数的参数意义如下:

HDC hdc 画图界面

int p[][MAX] 储存多边形各个定点的数组

int point_num 多边形的总定点数

int in_num 多边形的内部定点数

COLORREF color 多边形的颜色

在执行多边形阴影填充的过程中需要求填充阴影线与多边形棱边的交点,使用到函数int LineIntersection(double k,int b,int x1,int y1,int x2,int y2)

该函数的参数意义如下:

double k 填充阴影线的斜率

int b 填充阴影线的截距

int x1 该棱边的一个定点的横坐标

int y1 该棱边的一个定点的纵坐标

int x2 该棱边另一个定点的横坐标

int y2 该棱边另一个定点的纵坐标

返回值(类型int) 交点的横坐标

该过程还需要对一条阴影线与多边形产生的多个交点按照X坐标升序进行排列,使用到函数

void SortPoint(int d[][MAX],int d_num)

排序原理为简单的选择排序。

该函数的参数意义如下:

int d[][MAX] 储存交点坐标的数组

int d_num 交点个数

进行多边形阴影线填充的主体函数为

void PolygonShadow(HDC hdc,int p[][MAX],int point_num,int in_num,double a,int h,COLORREF color)

该函数的参数意义如下:

HDC hdc 画图界面

int p[][MAX] 储存多边形各个定点的数组

int point_num 多边形的总定点数

int in_num 多边形的内部定点数

double a 阴影线与水平线的夹角

int h 阴影线之间的间隔

COLORREF color 填充阴影线的颜色

该部分实现代码如下:

void DrawPolygon(HDC hdc,int p[][MAX],int point_num,int in_num,COLORREF color)

{

int i;

for(i=0;i<=point_num-1-in_num;i++){

if(i==point_num-1-in_num){

DrawLine(hdc,p[0][i],p[1][i],p[0][0],p[1][0],color);

}

else{

DrawLine(hdc,p[0][i],p[1][i],p[0][i+1],p[1][i+1],color);

}

}

for(i=point_num-in_num;i<=point_num-1;i++){

if(i==point_num-1){

DrawLine(hdc,p[0][i],p[1][i],p[0][point_num-in_num],p[1][point_num-in_num],color);

}

else{

DrawLine(hdc,p[0][i],p[1][i],p[0][i+1],p[1][i+1],color);

}

}

}

int LineIntersection(double k,int b,int x1,int y1,int x2,int y2)

{

int b1,b2,min,max,x;

b1=y1-(int)(0.5+k*(double)x1);

b2=y2-(int)(0.5+k*(double)x2);

if(b1

min=b1;

max=b2;

}

else{

min=b2;

max=b1;

}

if(b>=min&&b<=max){

x=(x1*y2-y1*x2+b*(x2-x1))/((y2-y1)-(int)(0.5+k*(double)(x2-x1)));

return x;

}

else{

return DEF;

}

}

void SortPoint(int d[][MAX],int d_num)

{

int i,j,min,tempx,tempy;

for(i=0;i<=d_num-2;i++){

min=i;

for(j=i+1;j<=d_num-1;j++){

if(d[0][j]

min=j;

}

}

tempx=d[0][i];

tempy=d[1][i];

d[0][i]=d[0][min];

d[1][i]=d[1][min];

d[0][min]=tempx;

d[1][min]=tempy;

}

}

void PolygonShadow(HDC hdc,int p[][MAX],int point_num,int in_num,double a,int h,COLORREF color)

{

DrawPolygon(hdc,p,point_num,in_num,color);//按要求画出多边形

int i,db,b[MAX];

double k;

k=tan(a);

db=(int)(0.5+(double)h/cos(a));

for(i=0;i<=point_num-1;i++){

b[i]=(p[1][i]-p[1][0])-(int)(0.5+k*(double)(p[0][i]-p[0][0]));//对于每个顶点作阴影线求截距

}

int bmax,bmin;

bmax=b[0];

bmin=b[0];

for(i=1;i<=point_num-1;i++){//确认阴影线扫描范围

if(b[i]>bmax){

bmax=b[i];

}

if(b[i]

bmin=b[i];

}

}

int bc,d[2][MAX],d_num;

bc=bmin+db;

while(bc<=bmax){//扫描过程

d_num=0;

for(i=0;i<=point_num-1-in_num;i++){//求该条阴影线与多边形各条外部棱边的交点if(i==point_num-1-in_num){

d[0][d_num]=LineIntersection(k,bc,p[0][i]-p[0][0],p[1][i]-p[1][0],p[0][0]-p[0][0],p[1][0]-p[1][ 0]);

}

else{

d[0][d_num]=LineIntersection(k,bc,p[0][i]-p[0][0],p[1][i]-p[1][0],p[0][i+1]-p[0][0],p[1][i+1]-p[ 1][0]);

}

if(d[0][d_num]!=DEF){

d[1][d_num]=(int)(0.5+k*(double)d[0][d_num])+bc;

d[0][d_num]=d[0][d_num]+p[0][0];

d[1][d_num]=d[1][d_num]+p[1][0];

d_num++;

}

}

for(i=point_num-in_num;i<=point_num-1;i++){//求该条阴影线与多边形各条内部棱边的交点

if(i==point_num-1){

d[0][d_num]=d[0][d_num]=LineIntersection(k,bc,p[0][i]-p[0][0],p[1][i]-p[1][0],p[0][point_nu m-in_num]-p[0][0],p[1][point_num-in_num]-p[1][0]);

}

else{

d[0][d_num]=d[0][d_num]=LineIntersection(k,bc,p[0][i]-p[0][0],p[1][i]-p[1][0],p[0][i+1]-p[0][ 0],p[1][i+1]-p[1][0]);

}

if(d[0][d_num]!=DEF){

d[1][d_num]=(int)(0.5+k*(double)d[0][d_num])+bc;

d[0][d_num]=d[0][d_num]+p[0][0];

d[1][d_num]=d[1][d_num]+p[1][0];

d_num++;

}

}

SortPoint(d,d_num);//将交点按照X坐标升序排列

for(i=0;i

DrawLine(hdc,d[0][i],d[1][i],d[0][i+1],d[1][i+1],color);

}

bc=bc+db;//扫描下一条阴影线

}

}

3.1.5.多边形区域扫描填充

程序设计基于2.5中的算法原理。

算法首先要对多边形的各个点进行预处理,使用到函数

void PreProcessing(int p[][MAX],int point_num,int in_num)

该函数的参数意义如下:

int p[][MAX] 储存多边形各个定点的数组

int point_num 多边形的总定点数

int in_num 多边形的内部定点数

之后算法要创建ET表与AEL表。

程序的数据结构定义如下:

struct list{

int ymax;

double x;

double dx;

struct list *next;

};

struct head{

int num;

struct list *start;

struct list *end;

};

typedef struct list L;

typedef struct head H;

typedef L * LP;

其中,list结构中含有ymax、x、△x域以及指向下一个节点的指针,作为AEL表以及ET表中的链表部分。

而head结构的num用于标识ET表中的类号或者AEL表中的扫描线纵坐标,start和end 分别为相应链表的头结点和尾节点,该结构作为AEL表以及ET表中每个类的头部。

创建ET表使用到函数

int CreateET(int p[][MAX],int point_num,int in_num,int ymin,H ET[])

该函数的参数意义如下:

int p[][MAX] 储存多边形各个定点的数组

int point_num 多边形的总定点数

int in_num 多边形的内部定点数

int ymin 扫描线起点纵坐标

H ET[] 储存ET表表头部分的数组

返回值(类型int) ET表中多边形棱边信息的数量

在创建ET表的过程中,涉及到链表的插入操作,使用到函数

LP InsertList(int x1,int y1,int x2,int y2,LP h,LP *t)

该函数的参数意义如下:

int x1 当前棱边的一个定点的横坐标

int y1 当前棱边的一个定点的纵坐标

int x2 当前棱边另一个定点的横坐标

int y2 当前棱边另一个定点的纵坐标

LP h ET表中该类链表的头结点

LP *t ET表中该类链表的尾结点

返回值(类型LP) 更新操作后的ET表中该类链表的头结点

算法执行过程中要按照AEL表中的x域以及△x域进行升序排列,故需要涉及链表的排序操作,使用到函数

LP SortAEL(LP head)

排序原理为简单的选择排序。

该函数的参数意义如下:

LP head 待排序AEL表的头结点

返回值(类型LP) 排序后AEL表的头结点

算法执行过程中要删去AEL表中ymax=y的成员,故需要涉及链表的删除操作,使用到函数

LP DeleteList(LP head,LP current,LP *tail);

该函数的参数意义如下:

LP head 待操作AEL表的头结点

LP current 待删除节点

LP *tail 待操作AEL表的尾结点

返回值(类型LP) 删除操作后AEL表的头结点

进行多边形区域扫描填充算法的主体函数为

void PolygonFill(HDC hdc,int p[][MAX],int point_num,int in_num,COLORREF color)

该函数的参数意义如下:

HDC hdc 画图界面

int p[][MAX] 储存多边形各个定点的数组

int point_num 多边形的总定点数

int in_num 多边形的内部定点数

COLORREF color 填充的颜色

该部分实现代码如下:

void PreProcessing(int p[][MAX],int b[][MAX],int point_num,int in_num)

{

int i;

for(i=0;i<=point_num-1-in_num;i++){

if(i==point_num-1-in_num){

if(p[1][i]

b[0][i]=-1;

b[1][0]=1;

}

else if(p[1][i]==p[1][0]){

b[0][i]=0;

b[1][0]=0;

}

else{

b[0][i]=1;

b[1][0]=-1;

}

}

else{

if(p[1][i]

b[0][i]=-1;

b[1][i+1]=1;

}

else if(p[1][i]==p[1][i+1]){

b[0][i]=0;

b[1][i+1]=0;

}

else{

b[0][i]=1;

b[1][i+1]=-1;

}

}

}

for(i=point_num-in_num;i<=point_num-1;i++){ if(i==point_num-1){

if(p[1][i]

b[0][i]=-1;

b[1][point_num-in_num]=1;

}

else if(p[1][i]==p[1][point_num-in_num]){

b[0][i]=0;

b[1][point_num-in_num]=0;

}

else{

b[0][i]=1;

b[1][point_num-in_num]=-1;

}

}

else{

if(p[1][i]

b[0][i]=-1;

b[1][i+1]=1;

}

else if(p[1][i]==p[1][i+1]){

b[0][i]=0;

b[1][i+1]=0;

}

else{

b[0][i]=1;

b[1][i+1]=-1;

}

}

}

}

int CreateET(int p[][MAX],int point_num,int in_num,int ymin,H ET[])

{

int i,down,e_num,b[2][MAX];

e_num=0;

PreProcessing(p,b,point_num,in_num);

for(i=0;i<=point_num-1-in_num;i++){

if(i==point_num-1-in_num){

if(p[1][i]!=p[1][0]){

if(p[1][i]

down=p[1][i];

if(b[0][i]*b[1][i]==-1){

down++;

}

}

else{

down=p[1][0];

if(b[0][0]*b[1][0]==-1){

down++;

}

}

ET[down-ymin].start=InsertList(p[0][i]-p[0][0],p[1][i]-p[1][0],p[0][0]-p[0][0],p[1][0]-p[1][0],E T[down-ymin].start,&ET[down-ymin].end);

e_num++;

}

}

else{

if(p[1][i]!=p[1][i+1]){

if(p[1][i]

down=p[1][i];

if(b[0][i]*b[1][i]==-1){

down++;

}

}

else{

down=p[1][i+1];

if(b[0][i+1]*b[1][i+1]==-1){

down++;

}

}

ET[down-ymin].start=InsertList(p[0][i]-p[0][0],p[1][i]-p[1][0],p[0][i+1]-p[0][0],p[1][i+1]-p[1][0 ],ET[down-ymin].start,&ET[down-ymin].end);

e_num++;

}

}

}

for(i=point_num-in_num;i<=point_num-1;i++){

if(i==point_num-1){

if(p[1][i]!=p[1][point_num-in_num]){

if(p[1][i]

down=p[1][i];

if(b[0][i]*b[1][i]==-1){

down++;

}

}

else{

down=p[1][point_num-in_num];

if(b[0][point_num-in_num]*b[1][point_num-in_num]==-1){

down++;

}

}

ET[down-ymin].start=InsertList(p[0][i]-p[0][0],p[1][i]-p[1][0],p[0][point_num-in_num]-p[0][0 ],p[1][point_num-in_num]-p[1][0],ET[down-ymin].start,&ET[down-ymin].end);

e_num++;

}

}

else{

if(p[1][i]!=p[1][i+1]){

if(p[1][i]

down=p[1][i];

if(b[0][i]*b[1][i]==-1){

down++;

}

}

else{

down=p[1][i+1];

if(b[0][i+1]*b[1][i+1]==-1){

down++;

}

}

ET[down-ymin].start=InsertList(p[0][i]-p[0][0],p[1][i]-p[1][0],p[0][i+1]-p[0][0],p[1][i+1]-p[1][0

计算机图形学实验报告

《计算机图形学》实验报告姓名:郭子玉 学号: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; }

研究生计算机图形学课程室内场景OpenGL--实验报告Word版

《高级计算机图形学》实验报告 姓名:学号:班级: 【实验报告要求】 实验名称:高级计算机图形学室内场景 实验目的:掌握使用OpenGL生成真实感复杂对象的方法,进一步熟练掌握构造实体几何表示法、扫描表示法、八叉树法、BSP树法等建模方法。 实验要求:要求利用OpenGL生成一个真实感的复杂对象及其周围场景,并显示观测点变化时的几何变换,要具备在一个纹理复杂的场景中漫游功能。要求使用到光线跟踪算法、 纹理映射技术以及实时绘制技术。 一、实验效果图 图1:正面效果图

图2:背面效果图 图4:背面效果图

图4:室内场景细节效果图 图5:场景角度转换效果图

二、源文件数据代码: 共6个文件,其实现代码如下: 1、DlgAbout.cpp #include "StdAfx.h" #include "DlgAbout.h" CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) { } void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); } BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) END_MESSAGE_MAP() 2、FormCommandView.cpp #include "stdafx.h" #include "Tool.h" #include "MainFrm.h" #include "FormCommandView.h" #include "ToolDoc.h" #include "RenderView.h" // Download by https://www.wendangku.net/doc/a914937180.html, #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif // CFormCommandView IMPLEMENT_DYNCREATE(CFormCommandView, CFormView) CFormCommandView::CFormCommandView() : CFormView(CFormCommandView::IDD) { //{{AFX_DATA_INIT(CFormCommandView)

计算机图形学实验

实验1 直线的绘制 实验目的 1、通过实验,进一步理解和掌握DDA和Bresenham算法; 2、掌握以上算法生成直线段的基本过程; 3、通过编程,会在TC环境下完成用DDA或中点算法实现直线段的绘制。实验环境 计算机、Turbo C或其他C语言程序设计环境 实验学时 2学时,必做实验。 实验内容 用DDA算法或Besenham算法实现斜率k在0和1之间的直线段的绘制。 实验步骤 1、算法、原理清晰,有详细的设计步骤; 2、依据算法、步骤或程序流程图,用C语言编写源程序; 3、编辑源程序并进行调试; 4、进行运行测试,并结合情况进行调整; 5、对运行结果进行保存与分析; 6、把源程序以文件的形式提交; 7、按格式书写实验报告。 实验代码:DDA: # include # include

void DDALine(int x0,int y0,int x1,int y1,int color) { 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++) { putpixel((int)(x+0.5),(int)(y+0.5),4); x+=xIncre; y+=yIncre; } } main(){ int gdriver ,gmode ;

(完整版)计算机图形学发展综述

计算机图形学发展综述 报告 专业 班级 学生 学号

计算机图形学发展综述 一、计算机图形学历史 1950年,第一台图形显示器作为美国麻省理工学院(MIT)旋风I(Whirlwind I)计算机的附件诞生了。该显示器用一个类似于示波器的阴极射线管(CRT)来显示一些简单的图形。1958年美国Calcomp公司由联机的数字记录仪发展成滚筒式绘图仪,GerBer公司把数控机床发展成为平板式绘图仪。在整个50年代,只有电子管计算机,用机器语言编程,主要应用于科学计算,为这些计算机配置的图形设备仅具有输出功能。计算机图形学处于准备和酝酿时期,并称之为:“被动式”图形学。到50年代末期,MIT的林肯实验室在“旋风”计算机上开发SAGE空中防御体系,第一次使用了具有指挥和控制功能的CRT显示器,操作者可以用笔在屏幕上指出被确定的目标。与此同时,类似的技术在设计和生产过程中也陆续得到了应用,它预示着交互式计算机图形学的诞生。 1962年,MIT林肯实验室的Ivan E.Sutherland 发表了一篇题“Sketchpad:一个人机交互通信的图形系统”的博士论文,他在论文中首次使用了计算机图形学Computer Graphics”这个术语,证明了交互计算机图形学是一个可行的、有用的研究领域,从而确定了计算机图形学作为一个崭新的科学分支的独立地位。他在论文中所提出的一些基本概念和技术,如交互技术、分层存储符号的数据结构等至今还在广为应用。1964年MIT的教授Steven A. Coons提出了被后人称为超限插值的新思想,通过插值四条任意的边界曲线来构造曲面。同在60年代早期,法国雷诺汽车公司的工程师Pierre Bézier发展了一套被后人称为Bézier曲线、曲面的理论,成功地用于几何外形设计,并开发了用于汽车外形设计的

计算机图形学实验报告 (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))

计算机图形学课程设计报告

一、设计内容与要求 1.1、设计题目 算法实现时钟运动 1.2、总体目标和要求 (1)目标:以图形学算法为目标,深入研究。继而策划、设计并实现一个能够表现计算机图形学算法原理的或完整过程的演示系统,并能从某些方面作出评价和改进意见。通过完成一个完整程序,经历策划、设计、开发、测试、总结和验收各阶段,达到巩固和实践计算机图形学课程中的理论和算法;学习表现计算机图形学算法的技巧;培养认真学习、积极探索的精神。 (2)总体要求:策划、设计并实现一个能够充分表现图形学算法的演示系统,界面要求美观大方,能清楚地演示算法执行的每一个步骤。(3)开发环境:Viusal C++ 6.0 1.3、设计要求 内容: (1)掌握动画基本原理; (2)实现平面几何变换; 功能要求: (1)显示时钟三个时针,实现三根时针间的相互关系;

(2)通过右键菜单切换时钟背景与时针颜色; 1.4设计方案 通过使用OpenGL提供的标准库函数,综合图形学Bresenham画线和画圆的算法,OpenGL颜色模型中颜色表示模式等实现指针式时钟运动,并通过点击右键菜单实习时钟背景与时针颜色的转换。根据Bresenham画线和画圆的算法,画出时钟的指针和表盘。再根据OpenGL颜色模型定义当前颜色。设置当时钟运行时交换的菜单,运行程序时可变换时钟背景与时针的颜色。最后再设置一个恢复菜单恢复开始时表盘与指针的颜色。

二、总体设计 2.1、过程流程图

2.2、椭圆的中点生成算法 1、椭圆对称性质原理: (1)圆是满足x轴对称的,这样只需要计算原来的1/2点的位置;(2)圆是满足y轴对称的,这样只需要计算原来的1/2点的位置; 通过上面分析可以得到实际上我们计算椭圆生成时候,只需要计算1/4个椭圆就可以实现对于所有点的生成了。 2、中点椭圆算法内容: (1)输入椭圆的两个半径r1和r2,并且输入椭圆的圆心。设置初始点(x0,y0)的位置为(0,r2); (2)计算区域1中央决策参数的初始值 p = ry*ry - rx*rx*ry + 1/4*(rx*rx); (3)在区域1中的每个Xn为止,从n = 0 开始,直到|K|(斜率)小于-1时后结束; <1>如果p < 0 ,绘制下一个点(x+1,y),并且计算 p = p + r2*r2*(3+2*x); <2>如果P >=0 ,绘制下一个点(x+1,y-1),并且计算 p = p + r2*r2*(3+2*point.x) - 2*r1*r1*(y-1) (4)设置新的参数初始值; p = ry*ry(X0+1/2)*(X0+1/2) + rx*rx*(Y0-1) - rx*rx*ry*ry; (5)在区域2中的每个Yn为止,从n = 0开始,直到y = 0时结束。 <1>如果P>0的情况下,下一个目标点为(x,y-1),并且计算 p = p - 2rx*rx*(Yn+1) + rx*rx;

计算机图形学实验二报告

计算机科学与通信工程学院 实验报告 课程计算机图形学 实验题目曲线拟合 学生姓名 学号 专业班级 指导教师 日期

成绩评定表

曲线拟合 1. 实验内容 1. 绘制三次Bezier曲线 (1)给定四个已知点P1—P4,以此作为控制顶点绘制一段三次Bezier曲线。 (2)给定四个已知点P1—P4,以此作为曲线上的点绘制一段三次Bezier曲线。 2. 绘制三次B样条曲线 给定六个已知点P1—P6,以此作为控制顶点绘制一条三次B样条曲线。 2. 实验环境 软硬件运行环境:Windows XP 开发工具:visual studio 2008 3. 问题分析 1. 绘制三次Bezier曲线 Bezier曲线是用N+1个顶点(控制点)所构成的N根折线来定义一根N阶曲线。本次实验中的三次Bezier曲线有4个顶点,设它们分别为P0,P1,P2,P3,那么对于曲线上各个点Pi(x,y)满足下列关系: P(t)=[(-P0+3P1-3P2+3P3)t3+(3P0-6P1+3P2)t2+(-3P0+3P2)t+(P0+4P1+P2)]/6 X(t)=[(-X0+3X1-3X2+3X3)t3+(3X0-6X1+3X2)t2+(-3X0+3X2)t+(X0+4X1+X2)]/6 Y(t)=[(-Y0+3Y1-3Y2+3Y3)t3+(3Y0-6Y1+3Y2)t2+(-3Y0+3Y2)t+(Y0+4Y1+Y2)]/6 其中P0、P1、P2、P3为四个已知的点,坐标分别为(X0、Y0)、(X1、Y1)、(X1、Y2) 、(X3、Y3)。所以只要确定控制点的坐标,该曲线可通过编程即可绘制出来。 2. 绘制三次B样条曲线 三次B样条函数绘制曲线的光滑连接条件为:对于6个顶点,取P1、P2、P3、P4 4个顶点绘制在第一段三次样条曲线,再取P2、P3、P4、P5 这4个顶点绘制在第二段三次样条曲线,总计可绘制3段光滑连接的三次样条曲线。 4. 算法设计 程序框架 //DiamondView.h class CDiamondView : public CView { ……

计算机图形学实验报告

目录

实验一直线的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); glV ertex2i(int(x+0.5),(int)(y+0.5)); glEnd(); x+=xIncre; y+=yIncre; } } void Display(void) { glClear(GL_COLOR_BUFFER_BIT); DDALine(100,100,200,180); glFlush(); }

计算机图形学实验报告记录

计算机图形学实验报告记录

————————————————————————————————作者:————————————————————————————————日期:

计算机图形学实验报告 姓名:___ __________ 学号:_____ ________ 班级:______ _______ 时间:_____2016年12月_________

实验一OpenGL编程与图形绘制 1.实验目的 了解OpenGL编程,并熟悉OpenGL的主要功能、绘制流程和基本语法。学会配置OpenGL环境,并在该环境中编程绘图。 2.实验内容 OpenGL的主要功能:模型绘制、模型观察、颜色模式、光照应用、图像效果增强、位图和图像处理、纹理映射、实时动画和交互技术。 OpenGL的绘制流程分为两个方面:一个完整的窗口系统的OpenGL图形处理系统的结构为:最底层为图形硬件,第二层为操作系统,第三层为窗口系统,第四层为OpenGL,最上面的层为应用软件;OpenGL命令将被放在一个命令缓冲区中,这样命令缓冲区中包含了大量的命令、顶点数据和纹理数据。当缓冲区被清空时,缓冲区中的命令和数据都将传递给流水线的下一个阶段。 OpenGL的基本语法中相关库有:OpenGL核心库:gl、OpenGL实用程序库:glu、OpenG 编程辅助库:aux、OpenGL实用程序工具包(OpenGL utility toolkit,GLUT):glut、Windows 专用库:wgl。 OpenGL的基本语法中命名规则为:OpenGL函数都遵循一个命名约定,即采用以下格式:<库前缀><根命令><可选的参数个数><可选的参数类型>。 了解了上述基础知识后,配置好OpenGL环境,然后在该环境中编程练习图形的绘制,本次实验主要是对点的绘制、直线的绘制和多边形面的绘制。 3.实验代码及结果 3.1点的绘制: #include 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 Display(void) {

计算机图形学课程设计书

计算机图形学课程设计 书 文档编制序号:[KKIDT-LLE0828-LLETD298-POI08]

课程设计(论文)任务书 理学院信息与计算科学专业2015-1班 一、课程设计(论文)题目:图像融合的程序设计 二、课程设计(论文)工作: 自2018 年1 月10 日起至2018 年1 月12日止 三、课程设计(论文) 地点: 2-201 四、课程设计(论文)内容要求: 1.本课程设计的目的 (1)熟悉Delphi7的使用,理论与实际应用相结合,养成良好的程序设计技能;(2)了解并掌握图像融合的各种实现方法,具备初步的独立分析和设计能力;(3)初步掌握开发过程中的问题分析,程序设计,代码编写、测试等基本方法;(4)提高综合运用所学的理论知识和方法独立分析和解决问题的能力; (5)在实践中认识、学习计算机图形学相关知识。 2.课程设计的任务及要求 1)基本要求: (1)研究课程设计任务,并进行程序需求分析; (2)对程序进行总体设计,分解系统功能模块,进行任务分配,以实现分工合作;(3)实现各功能模块代码; (4)程序组装,测试、完善系统。 2)创新要求: 在基本要求达到后,可进行创新设计,如改进界面、增加功能或进行代码优化。

3)课程设计论文编写要求 (1)要按照书稿的规格打印誊写课程设计论文 (2)论文包括封面、设计任务书(含评语)、摘要、目录、设计内容、设计小结(3)论文装订按学校的统一要求完成 4)参考文献: (1)David ,《计算机图形学的算法基础》,机械工业出版社 (2)Steve Cunningham,《计算机图形学》,机械工业出版社 (3) 5)课程设计进度安排 内容天数地点 程序总体设计 1 实验室 软件设计及调试 1 实验室 答辩及撰写报告 1 实验室、图书馆 学生签名: 2018年1月12日 摘要 图像融合是图像处理中重要部分,能够协同利用同一场景的多种传感器图像信息,输出一幅更适合于人类视觉感知或计算机进一步处理与分析的融合图像。它可明显的改善单一传感器的不足,提高结果图像的清晰度及信息包含量,有利于更为准确、更为可靠、更为全面地获取目标或场景的信息。图像融合主要应用于军事国防上、遥感方面、医学图像处理、机器人、安全和监控、生物监测等领域。用于较多也较成熟的是红外和可见光的融合,在一副图像上显示多种信息,突出目标。一般情况下,图像融合由

计算机图形学报告

中南大学 计算机图形学 实验报告 学生姓名谭淼 学号23 专业班级应数1102班 指导老师刘圣军 数学与统计学院 2013年12月 实验目的:设计并实现一个简单动画(二维或三维)。熟悉并应用画线的基本算法—Bresenham算法。 实验过程: 1、实验步骤: (1)打开Visual Studio 2010,新建一个MFC项目,取名为tuxingxue,设置为单文档。 (2)打开类视图,添加一个名为Cline2D的类,在该类中添加BresenhamLine(CDC* pDC, int xa,float ya,int xb,float yb) DrawPixel(CDC* pDC, int x, float y, unsigned int color, int size); BresenhamLine1(CDC* pDC, int xa,float ya,int xb,float yb);

BresenhamLine2(CDC* pDC, int xa,float ya,int xb,float yb); BresenhamLine3(CDC* pDC, int xa,float ya,int xb,float yb); BresenhamLine4(CDC* pDC, int xa,float ya,int xb,float yb); 以上函数的返回值类型均为void型。在中,分别在其中添加代码实现画线的功能,具体代码见附录中的源代码。 (3)画出基本图形。在中定义CLine2D 的一个对象为line1,以便调用CLine2D中的函数,此时在调用的函数中赋初始值即可画出最基本的图形,即为一颗大五角星以及三颗小的五角星。 (4)让画出的五角星动起来。从类视图中CtuxingxueView下添加名为OnTimer的消息处理函数,在中添加bool型变量m_flag,在OnTimer函数下添加代码,具体代码见附录。在添加变量int m_x1、int m_y1、int m_x2、int m_y2、int m_x3、int m_y3、int m_x4、int m_y4、int m_x5、int m_y5、int m_x6、int m_y6、int m_x7、int m_y7、int m_x8、int m_y8、int m_x9、int m_y9、int m_x10、int m_y10、 int m_x11、int m_y11、int m_x12、int m_y12。在中为这些变量赋初始值,将第三步中函数赋的初值用这些变量代替,这样变量的值可以改变,在资源视图中menu下IDR_MAINFRAME中添加名为绘图的菜单项,在绘图下添加名为运行的选项,其ID号为ID_run,添加事件处理程序,函数处理程序名称为Onrun,将其类选为C tuxingxueView,此时,在Onrun中添加代码,再运行就可以让图形动起来了。 2、实验中遇到的问题及处理方法

计算机图形学 课程设计作品

《计算机图形学Visual c++版》考试作业报告 题目:计算机图形学图形画板 专业:推荐IT学长淘宝日用品店530213 班级:推荐IT学长淘宝日用品店530213 学号:推荐IT学长淘宝日用品店530213 姓名:推荐IT学长淘宝日用品店530213 指导教师:推荐IT学长淘宝日用品店530213 完成日期: 2015年12月2日

一、课程设计目的 本课程设计的目标就是要达到理论与实际应用相结合,提高学生设计图形及编写大型程序的能力,并培养基本的、良好的计算机图形学的技能。 设计中要求综合运用所学知识,上机解决一些与实际应用结合紧密的、规模较大的问题,通过分析、设计、编码、调试等各环节的训练,使学生深刻理解、牢固掌握计算机图形学基本知识和算法设计的基本技能术,掌握分析、解决实际问题的能力。 通过这次设计,要求在加深对课程基本内容的理解。同时,在程序设计方法以及上机操作等基本技能和科学作风方面受到比较系统和严格的训练。 二、设计内容推荐IT学长淘宝日用品店530213 设计一个图形画板,在这个图形画板中要实现: 1,画线功能,而且画的线要具备反走样功能。 2, 利用上面的画线功能实现画矩形,椭圆,多边形,并且可以对这些图形进行填充。 3,可以对选中区域的图形放大,缩小,平移,旋转等功能。 三、设计过程 程序预处理:包括头文件的加载,常量的定义以及全局变量的定义 #include "stdafx.h" #include "GraDesign.h" #include "GraDesignDoc.h" #include "GraDesignView.h" #include "math.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif //******自定义全局变量 int type = -1; CPoint point1; CPoint point2; CPoint temp[2];

计算机图形学报告

数字媒体技术专业 计算机图形学课程设计报告 院系:印包学院 专业班级:媒体121 学生学号: 3120342001 学生姓名:孔祥倩 指导教师:吴学毅 2014年秋季学期

目录 一.课程设计的目的 (2) 二.课程系统描述实现及步骤 (2) 三.设计内容 (3) 四.源程序代码 (4) 五.总结 (19) 六.参考文献 (20) 七.附录 (20)

一、课程设计的目的 OpenGL即开放性图形库,它是一种高性能的开放式且功能强大的3D图形库,具有几百个指令和函数。本文讨论了两种将常见三维模型转入OpenGL 中实现交互的方法,首先对文件进行分析,然后给出转化的思路。从而将三维建模软件产生的三维模型移植到三维场景中,实现仿真. 本课程主要内容包括计算机图形学的研究内容、发展与应用,图形输入输出设备,图形显示原理,图形软件标准,基本图形生成算法,图形几何变换与裁剪,自由曲线和曲面三维实体造型,分形几何造型,分形艺术,隐藏面消除,光照模型,颜色模型,光线跟踪,纹理细节模拟,常用的计算机动画技术和软件等。在学期期末时按课程要求进行运动,提高学生对计算机图形学知识的了解与运用技巧同时通过此次课程设计提高动手实践能力与学习分析能力这就是本次的课 OpenGL的英文全称是“Open Graphics Library”即“开放的图形程序接口”,因为其良好的可移植性和跨平台性,已逐渐成为高性能图形开发和交互式视景仿真的国际图形标准。它是一种高性能的开放式且功能强大的3D图形库,具有几百个指令和函数。使用这些指令和函数可以构造出高质量的静止物体模型和动态图像,并且可以实现对模型的实时交互操作过程。但是OpenGL中并没有提供建模的高级命令,其实现过程也是通过基本的几何图元点、线和多边形来建立三维立体模型的,过程比较繁琐,编程量较大。 二.课程系统描述实现及步骤 此次课程设计的课题为利用VC++6.0和插件OPENGL制作三维模型。本设计主要通过建立MFC工程,在工程里建立一个三维模型,来建立一个动态的三维模型。设计一个小院子,其中有房子,树木,桌凳,月亮的一系列景物。运行程序,实现在这个小院子中的漫游。 主要步骤如下: 1:工程的建立 2:三维模型的建立和映射 3:三维模型的运动 一:工程的建立 1:系统配置。先对机子安装VC++6.0.在建立工程前,本实验需要添加OPENGL插件,故需要在Windows环境下安装GLUT 步骤如下: 1、将下载的压缩包解开,将得到5个文件 2、在“我的电脑”中搜索“gl.h”,并找到其所在文件夹(如果是VisualStudio2005,则应该是其安装目录下面的“VC\PlatformSDK\include\gl文件夹”)。把解压得到的glut.h放到这个文件夹。 3、把解压得到的glut.lib和glut32.lib放到静态函数库所在文件夹(如果是VisualStudio2005,则应该是其安装目录下面的“VC\lib”文件夹)。 4、把解压得到的glut.dll和glut32.dll放到操作系统目录下面的system32文件夹内。(典型的位置为:C:\Windows\System32)然后建立

计算机图形学实验报告

计算机图形学 实验报告 姓名:谢云飞 学号: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;

计算机图形学课程设计报告简单图形的绘制-

《计算机图形学》课程设计 报告 学生姓名:学号: 学院: 班级: 题目: 简单图形的绘制 职称2015年7月1日

目录 目录............................................................................................... I 一、选题背景 (1) 二、算法设计 (2) 2.1 绘制直线、圆、椭圆、抛物线 (2) 2.1.1 绘制直线 (2) 2.1.2 绘制圆 (2) 2.1.3 绘制椭圆 (2) 2.1.4 绘制抛物线 (2) 2.2 三维几何变换 (2) 三、程序及功能说明 (5) 3.1 绘制直线、圆、椭圆、抛物线...... (5) 3.1.1 绘制直线 (5) 3.1.2 绘制圆 (5) 3.1.3 绘制椭圆 (5) 3.1.4 绘制抛物线 (6) 3.2 图形的平移 (6) 3.3 图形的旋转 (6) 3.4 图形的缩放 (7) 四、结果分析 (7) 4.1 绘制直线、圆、椭圆、抛物线 (7) 4.1.1 直线 (7) 4.1.2 圆 (8)

4.1.3 椭圆 (8) 4.1.4 抛物线 (8) 4.2 图形的平移 (9) 4.3 图形的旋转 (10) 4.4 图形的缩放 (11) 五、总结 (10) 六、课程设计心得体会 (14) 参考文献 (15) 源程序 (16)

一、选题背景

二、算法设计 2.1 绘制直线、圆、椭圆、抛物线 2.1.1 绘制直线 通过两个点的坐标来绘制直线。计算机图形学中二维图形在显示输出之前需要扫描转换,生成直线的算法一般有DDA 算法和中点算法。 2.1.2 绘制圆 通过运用圆的参数方程cos ;sin x a r y b r θθ=+=+来绘制圆的图形,其中[0,2]θπ∈, (a,b )为圆心,r 为半径,运用参数方程,只需要确定半径的长度和圆心的位置,即可绘制出圆。 2.1.3 绘制椭圆 通过运用椭圆的参数方程cos ;sin x a y b θθ==来绘制椭圆的图形,其中 [0,2]θπ∈,是已知的变量,a ,b 分别为长半轴,短半轴,当确定a 和b 后,通过参数方程即可得到这个椭圆的方程。 2.1.4 绘制抛物线 根据点绘制抛物线图像是通过拟合完成,根据三个点的坐标,通过数据拟合,得到经过这三个点的函数关系式,从而再根据这个函数关系式绘制出抛物线上其他的点,形成一条连续的抛物线;或直接根据已知函数绘制图像是通过已知函数画出图像。 2.2 三维几何变换 三维几何变换是二维几何变换的推广。二维几何变换在齐次坐标空间中 可用3?3的变换矩阵表示,类似的,三维几何变换在齐次坐标空间中可用4?4的变换矩阵表示。三维空间中的点(),,x y z 的齐次坐标定义为(),,h h h x y z ,其中,h 为不等与零的任意常数,h x hx =,h y hy =,h z hz =。亦即点(),,x y z 对应4维齐次坐标空间的一条直线:

计算机图形学课程设计

《计算机图形学》课程设计报告题目名称:球体背面剔除消隐算法 专业计算机科学与技术 班级计科15升-1班 学号 1516353004 姓名 指导教师王玉琨 2016 年 06 月 07 日

目录 设计内容与要求 (03) 总体目标和要求 (03) 内容与要求 (03) 总体设计 (03) 2.1 球的消隐处理基本原理 (03) 2.2 具体设计实现 (04) 详细设计 (04) 3.1调试后正确的程序清单 (04) 功能实现 (08) 4.1程序运行结果 (09) 4.2 功能实现及分析 (09) 总结 (09) 参考文献 (10)

球体背面剔除消隐算法 第 1章设计内容与要求 1.1 总体目标和要求 课程设计的目的:以图形学算法为目标,深入研究。继而策划、设计并实现一个能够表现计算机图形学算法原理的或完整过程的演示系统, 并能从某些方面作出评价和改进意见。 通过完成一个完整程序,经历策划、设计、开发、测试、总结和验收各阶段,达到: 1) 巩固和实践计算机图形学课程中的理论和算法; 2) 学习表现计算机图形学算法的技巧; 3) 培养认真学习、积极探索的精神; 4) 具备通过具体的平台实现图形算法的设计、编程与调试的能力; 5) 完成对实验结果分析、总结及撰写技术报告的能力。 总体要求:策划、设计并实现一个能够充分表现图形学算法的演示系统,界面要求美观大方,能清楚地演示算法执行的每一个步骤。 开发环境:Viusal C++ 6.0 1.2 内容与要求 球体背面剔除消隐算法 内容:(1)掌握背面剔除消隐算法原理; (2)实现矢量点积与叉积运算; (3)透视投影变换 (4)曲面体经纬线划分方法 功能要求: (1)绘制球体线框模型的透视投影图,使用背面剔除算法实现动态消隐; (2)通过右键菜单显示消隐效果,右键菜单有两个选项:未消隐与消隐; (3)使用键盘的上下左右控制键旋转消隐前后的球体; (4)单击左键增加视距,右击缩短视距; 第2章总体设计 2.1 球的消隐处理基本原理 球体的曲面通常采用一组网格多边形来表示,即把曲面离散成许多小平面片,用平面逼近曲面,一般使用许多四边形来逼近曲面。 网格四边形愈多,逼近曲面的精度就愈高,逼近效果就愈好,曲面看起来就越光滑。一般根据实际需要来确定合适的逼近精度即网格多边形数目。 当曲面表示为一组网格多边形时,消隐处理的主要工作是确定各网格多边形的可见性,由此可用平面立体的算法对曲面进行消隐处理。 球面的参数方程为:

《计算机图形学基础》第三次大作业实验报告共3页文档

第三次实验 1. 实验目的 实现用 Phong 光照明模型显示网格模型(*.smf)。分别实现不使用/使用增量式光强/法 向插值算法,比较三种不同的显示效果和效率。 Phong模型中各参数可调,观察它们的作用。 与用户的交互方式为图形用户界面,操作简单,界面友好。 2. 算法描述 2.1. 基于扫描线算法的Phong 模型实现 上一次大作业中我没有完成扫描线 ZBuffer 算法,使得程序的效率很低,这次作业考虑 到各种计算对时间的消耗会更大,所以我首先完成了扫描线算法再进行这次作业代码的编写。 对扫描线Z-Buffer算法这里不作详细描述,主要介绍 Phong模型的实现。基于扫描线算 法的 Phong 模型实现是非常方便的,因为最基本的 Phong 模型中每个面的颜色是法向量的 函数,因此每个面的颜色是相同的,这样在扫描线算法之前我首先初始化了一个数组,将各 个面的颜色根据用户提供的参数以及 Phong 模型公式计算出来保存在这个数组里,每一项 对应一个面,这样在具体扫描线算法的执行过程中每一个点颜色的获取

都仅仅是对数组的读 取操作,是O(1)的复杂度,不会消耗太多时间。 算法如下: 1.对物体表面上的每个点P,均需计算光线L的反射方向R, R=2N(N·L)-L。 为了减少计算量,假设: 2.光源在无穷远处,L为常向量 3.视点在无穷远处,V为常向量 4.用(H?N)近似(R?V),H为L与V的平分向量 5.Phong光照明模型的RGB颜色模型形式 2.2. 双线性光强差值算法 考虑到双线性光强差值算法的核心思想是由顶点的光强插值计算各边的光强,然后由各 边的光强插值计算出多边形内部点的光强,结合之前实现的扫描线ZBuffer 算法,我使用了 增量的方式实现这个算法,也就是将它和扫描线算法结合起来,在扫描线算法每个面的边表 中多加几个个域来表示当前的光强、光强在X 方向的单位增量和光强在 Y 方向的单位增量, 这样在扫描到每个点的时候就可以根据前一个点的光强以及光强增量获得该点的光强,另外 在扫描线改变的时候光强也需要根据Y方向的增量来进行相应的修改。

计算机图形学实验报告 课程设计 大作业

安徽建筑工业学院 计算机图形学实验报告 院(系)名称: 专业: 班级: 姓名: 学号: 指导老师:

实验一实现任意直线的中点画线算法 【实验目的】 掌握直线的中点画线算法; 【实验环境】 VC++6.0 【实验内容】 利用任意的一个实验环境,编制源程序,实现直线的中点画线法。 【实验原理】 假定直线斜率k在0~1之间,当前象素点为(x p,y p),则下一个象素点有两种可选择点P1(x p+1,y p)或P2(x p+1,y p+1)。若P1与P2的中点(x p+1,y p+0.5)称为M,Q为理想直线与x=x p+1垂线的交点。当M在Q的下方时,则取P2应为下一个象素点;当M在Q的上方时,则取P1为下一个象素点。这就是中点画线法的基本原理。 图2.1.2 中点画线法每步迭代涉及的象素和中点示意图 下面讨论中点画线法的实现。过点(x0,y0)、(x1, y1)的直线段L的方程式为F(x, y)=ax+by+c=0,其中,a=y0-y1, b=x1-x0, c=x0y1-x1y0,欲判断中点M在Q点的上方还是下方,只要把M代入F(x,y),并判断它的符号即可。为此,我们构造判别式: d=F(M)=F(x p+1, y p+0.5)=a(x p+1)+b(y p+0.5)+c

当d<0时,M在L(Q点)下方,取P2为下一个象素; 当d>0时,M在L(Q点)上方,取P1为下一个象素; 当d=0时,选P1或P2均可,约定取P1为下一个象素; 注意到d是x p, y p的线性函数,可采用增量计算,提高运算效率。 若当前象素处于d 0情况,则取正右方象素P1(x p+1, y p),要判下一个象素位置,应计 算d1=F(x p+2, y p+0.5)=a(x p+2)+b(y p+0.5)=d+a,增量为a。 若d<0时,则取右上方象素P2(x p+1, y p+1)。要判断再下一象素,则要计算d2= F(x p+2, y p+1.5)=a(x p+2)+b(y p+1.5)+c=d+a+b ,增量为a+b。画线从(x0, y0)开始,d的初值d0=F(x0+1, y0+0.5)=F(x0, y0)+a+0.5b,因F(x0, y0)=0,所以d0=a+0.5b。 由于我们使用的只是d的符号,而且d的增量都是整数,只是初始值包含小数。因此,我们可以用2d代替d来摆脱小数,写出仅包含整数运算的算法程序。 【实验程序】 void Midpoint Line (int x0,int y0,int x1, int y1,int color) { int a, b, d1, d2, d, x, y; a=y0-y1; b=x1-x0;d=2*a+b; d1=2*a;d2=2* (a+b); x=x0;y=y0; drawpixel(x, y, color); while (x

相关文档
相关文档 最新文档