视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
计算机图形学实验报告2
2025-09-26 21:42:51 责编:小OO
文档
青岛农业大学

实验报告

实验课程:                   

学生姓名:                    

       学    号:                   

专业班级:                   

                  2014年12月28日

目    录

        实验二   几何变换

        实验三   二维基本图形生成的算法实现.

        实验四   二维填充图的生成算法

        实验五   曲线的生成算法实现

   

                      

                         实验二

1.实验名称:  图形绘制

2.实验目的:

(1) 掌握二维图形基本的几何变换原理及变换矩阵;

(2) 掌握矩阵运算的程序设计。

3说明图形设计思想或程序流程图

(1) 掌握二维图形的齐次坐标表示方法;

(2)实现二维图形的基本变换,如进行平移变换等。

算法描述:

二维图形齐次坐标变换矩阵一般表达式:

这3×3 矩阵中各元素功能一共可分成四块,即

(4)程序结果分析

#include

#include

double x1,y1,x2,y2,x3,y3,x4,y4;

void pingyi(double d,double c)

{  double a1,b1,a2,b2;

  a1=x1+d;

  b1=y1+c;

  a2=x2+d;

  b2=y2+c;

  rectangle(a1,b1,a2,b2);

}

void suofang(double s)

{

 double a1,b1,a2,b2;

 a1=(double)x1*s;

 b1=(double)y1*s;

 a2=(double)x2*s;

 b2=(double)y2*s;

 rectangle(a1,b1,a2,b2);

}

void xuanzhuan(double b)

{

 double a1,b1,a2,b2;

 a1=x1*cos(b)-y1*sin(b);

 b1=y1*cos(b)+x1*sin(b);

 a2=x2*cos(b)-y2*sin(b);

 b2=y2*cos(b)+x2*sin(b);

 rectangle(a1,b1,a2,b2);

}

void cuoqie(double b,double d)

{

double a1,b1,a2,b2,a3,b3,a4,b4;

a1=x1+b*y1; a3=x3+b*y3;

b1=d*x1+y1; b3=d*x3+y3;

a2=x2+b*y2; a4=x4+b*x4;

b2=d*x2+y2; b4=d*x4+y4;

line(a1,b1,a3,b3);

line(a3,b3,a2,b2);

line(a2,b2,a4,b4);

line(a4,b4,a1,b1);

}

void duichenpoint()

{

 double a1,b1,a2,b2;

 a1=-x1;b1=-y1;a2=-x2;b2=-y2;

 rectangle(a1,b1,a2,b2);

}

void duichenx()

{

double a1,b1,a2,b2;

a1=x1;b1=-y1;a2=x2;b2=-y2;

rectangle(a1,b1,a2,b2);

}

void duicheny()

{

double a1,b1,a2,b2;

a1=-x1;b1=y1;a2=-x2;b2=y2;

rectangle(a1,b1,a2,b2);

}

void duichenxy()

{

double a1,b1,a2,b2;

a1=y1;b1=x1;a2=y1;b2=x2;

rectangle(a1,b1,a2,b2);

}

void duichenyx()

{

double a1,b1,a2,b2;

a1=-y1;b1=-x1;a2=-y2;b2=-x2;

rectangle(a1,b1,a2,b2);

}

main()

{ int gdriver,gmode;

int select=100;

double c,d,e;

 gdriver=DETECT;

 gmode=0;

 initgraph(&gdriver,&gmode,"d:\\\c20h\\\\bgi");

 x1=50;y1=50;x2=100;y2=100;

 x3=x2;y3=y1;x4=x1;y4=y2;

 printf("please input a rectangle's two point:(x1,y1,x2,y2)");

 scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);

 rectangle(x1,y1,x2,y2);

 getch();

 printf("1----pingyi\\n");

 printf("2----suofang");

 printf("3----xuanzhuan");

 printf("4----cuoqie");

 printf("5----guanyu yuandian duichen\\n");

 printf("6----guanyu x duichen \\n");

 printf("7----guanyu y duichen \\n");

 printf("8----guanyu y=x duichen \\n");

 printf("9----guanyu y=-x duichen \\n");

 printf("would you want to select what:(0 is exit system!) \\n");

 while(select!=0)

 {

 scanf("%d",&select);

 if(select==1)

 {

 printf("what's distance to pingyi?");

 printf("x: ");

 scanf("%lf",&d);

 printf("y: ");

 scanf("%lf",&c);

 pingyi(d,c);

 }

 else if(select==2)

 {

  printf("what's size of rectangle you want?");

  scanf("%lf",&e);

  suofang(e);

 }

 else if(select==3)

 {

 printf("xuanzhaun's size?");

 scanf("%lf",&e);

 xuanzhuan(e);

 }

 else if(select==4)

 {

   printf("cuoqie's size?");

   scanf("%lf%lf",&c,&d);

   cuoqie(c,d);

 }

 else if(select==5)

 duichenpoint();

 else if(select==6)

 duichenx();

 else if(select==7)

 duicheny();

 else if(select==8)

 duichenxy();

 else if(select==9)

 duichenyx();

 else

 printf("error please again! or input 0 to exit!\\n");

  }

 closegraph();

  system("pause");

}

输入一个矩形,输入想要进行的操作,得到操作之后的结果。图形转换,错切那个地方的程序有错误,其他的函数接口都写得很好。

实验三

1.实验名称   二维基本图形生成的算法实现

2.实验目的

(1) 掌握直线的两种生成算法;

(2)掌握二维图形显示原理。

3.说明图形设计思想或程序流程图

(1)对各种生成算法进行效率及效果的分析和比较;

(2)实现直线的生成;

(3)学有余力的同学可在对现有算法理解的基础上,能自行设计二维图形的生成算法并编程实现。

算法描述:

1. 数值微分法(Digital Differential Analyzer,DDA)生成直线

(1) 算法思想:基于直线的微分方程来生成直线。

已知过端点P0 (x0, y0), P1(x1, y1)的直线段L:y=kx+b

直线斜率为

(2)数学描述

①k ≤1 时,在x的增量方向上走步,走步的方向决定于x的符号。

xi+1=xi+ x , 计算yi+1= kxi+1+ b                                

                    = kxi + b + kx

                    = yi + kx                             

当x =1;    yi+1 = yi+ k 

即:当x每递增1,y递增k(即直线斜率);

在这种情况下,x每增加1,y最多增加1。

②当 k 1时,在y的增量方向上走步,走步的方向决定于y的符号。

yi+1 = yi + 1

计算 xi = yi/k - b/k

    xi+1 = yi+1/k - b/k

         = (yi+1)/k - b/k

         = yi/k-b/k + 1/k

         = xi + 1/k

2. Bresenham算法生成直线

(1)算法思想

比较从理想直线到位于直线上方的像素的距离d2和相邻的位于直线下方的像素的距离d1,然后根据距离误差项的符号确定与理想直线最近的象素。

(2) 数学描述

1. 判别函数

设直线起点P0(x0,y0),终点P1(x1,y1),令e0=2y - x作为判别函数,根据e0的正负,可以确定走向:

① e0<0,Y 方向不走步

② e0>=0,Y方向走一步

(2) 递推公式

对于第i +1步(i=0,l,2,……,n)

如果ei ≥ 0,则Y方向走一步:

Xi+l= Xi+1  Yi+1 =Yi+1 

ei+1= ei + 2y - 2x

如果ei<0,则Y方向不走步:

Xi+l= Xi+1  Yi+1 =Yi

ei+1= ei+ 2y

(4)程序结果分析

#include

#include

double x,y;

double a[50];b[50];

void run(double k,int d)

{

int i;

if(abs(k)<=1)

   {

for(i=2;i<=10;i++)

     {

      a[i]=a[i-1]+d;

      b[i]=b[i-1]+k*d;

      putpixel(a[i],b[i],1);

      getch();

     }

   }

   else

   {

for(i=2;i<=10;i++)

    {

    a[i]=a[i-1]+1/k;

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

    putpixel(a[i],b[i],1);

    getch();

    }

   }

}

main()

{

int gdriver,gmode;

gdriver=DETECT;

gmode=0;

initgraph(&gdriver,&gmode,"d:\\\c20h\\\\bgi");

x=50;y=50;

putpixel(x,y,1);

getch();

a[1]=x;

b[1]=y;

run(2,2);

run(0.5,50);

  system("pause");

}

运用数值微分法得到一条直线,给定距离,斜率生成直线,这个实验简单,用了第一个算法,但是第二个算法更为精确。

实验四

1.实验名称  二维填充图的生成算法

2.实验目的

编程实现任一多边形的填充。

3.说明图形填充的思想或程序流程图

(1)算法思想

用水平扫描线从上到下扫描由点线段构成的多段构成的多边形。每根扫描线与多边形各边产生一系列交点,将这些交点按横坐标从小到大排序,将交点两两配对,并填充每一区段。多边形被扫描完毕后,填充也就完成。

(2)算法步骤:

为每一条扫描线建立新边表NET;将扫描线纵坐标y的初值置为NET中非空元素的最小序号;置活性边表AET为空;

执行下列步骤直至NET和AET都为空;

如果NET中的第y类非空,则将其中的所有边取出并插入AET中,在插入过程中进行排序;

对AET中的边两两配对,将每对边中x坐标按规则取整,获得有效的填充区段,再填充;

将当前扫描线纵坐标y值递增1,即y=1;

将AET中满足y=ymax边删去;

     E、 对AET中剩下的每一条边的x递增deltax,即x=x+deltax

(3)程序结果分析

#include

#include

#include

#include

void draw(int x1,int y1,int x2,int y2,int delta)

{int nx1,ny1,nx2,ny2;

nx1=x1,ny1=y2-delta,nx2=x1+delta,ny2=y2;

while((ny1>=y1)&&(nx2<=x2))

 {line(nx1,ny1,nx2,ny2);

  getch();

  ny1-=delta; nx2+=delta; }

if(nx2>x2)

{ny2-=nx2-x2; nx2=x2;

while(ny1>y1)

{line(nx1,ny1,nx2,ny2);

getch();

ny1-=delta; ny2-=delta; }

 nx1+=y1-ny1; ny1=y1;

while(nx1{line(nx1,ny1,nx2,ny2);

getch();

nx1+=delta; ny2-=delta; }

}

else

{nx1+=y1-ny1; ny1=y1;

while(nx2 {line(nx1,ny1,nx2,ny2);

 getch();

 nx2+=delta; nx1+=delta; }

ny2-=nx2-x2; nx2=x2;

while(ny2>y1)

 {line(nx1,ny1,nx2,ny2);

 getch();

 ny2-=delta; nx1+=delta; }

}

 }

int main(void)

{int x1,y1,y2,x2,delta;

int driver=DETECT,mode;

printf("Please input lefttop(x1,y1) and rightbottom(x2,y2) of rectangle and delta:\\n");

 scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&delta);

initgraph (&driver,&mode,"d:\\\c20h\\\\bgi"); /*这里*/rectangle(x1,y1,x2,y2);

getch();

 draw(x1,y1,x2,y2,delta);

 gotoxy(1,1);

printf("Press any key to exit!");

getch();

closegraph();

return 0;

}

利用活性边表,对图形进行填充,网上有这种算法的模板,稍加修改就可以形成图形,做这个实验的时候,增加了一点知识,getch()是和C语言中的getchar()是一个意思,都是吸收字符用的,但在这个软件中按理来说就是C语言编程工具,但是用getchar()却不可以,软件之间还是有点差别吧。

实验五 

1.实验名称  曲线的生成算法实现

2.实验目的

(1) 掌握B样条曲线、Bezier曲线的定义;

(2) 能编程实现N 次B样条曲线、Bezier曲线的绘制与显示。 

3.说明图形设计思想或程序流程图

贝塞尔曲线的参数向量表达式

通常,n+1个顶点定义一个n次多项式。

其中

称为伯恩斯坦(Bernstain)基函数。

4.程序结果分析

#include

struct point

{

  double x;

  double y;

}coeff[50],coeffa[50];

struct point decas(int degree,double t)

{

 int r,i;

 double t1;

 t1=1.0-t;

for(i=1;i<=degree+1;i++)

 {

  coeffa[i]=coeff[i];

 }

for(r=2;r<=degree;r++)

 {

for(i=1;i<=degree+1;i++)

  {

    coeffa[i].x=t1*coeffa[i].x+t*coeffa[i+1].x;

    coeffa[i].y=t1*coeffa[i].y+t*coeffa[i+1].y;

  }

 }

 return (coeffa[1]);

}

main()

{

int gdriver,gmode;

struct point p;

int i;

gdriver=DETECT;

gmode=1;

initgraph(&gdriver,&gmode,"d:\\\c20h\\\\bgi");

coeff[1].x=50;coeff[1].y=50;

coeff[2].x=60;coeff[2].y=60;

coeff[3].x=70;coeff[3].y=75;

coeff[4].x=30;coeff[4].y=50;

moveto(coeff[1].x,coeff[1].y);

getch();

for(i=1;i<=3;i++)

{

 lineto(coeff[i+1].x,coeff[i+1].y);

 getch();

}

for(i=1;i<=4-2;i++)

{

   p=decas(3,0.2);

   lineto(p.x,p.y);

   getch();

 }

closegraph();

  system("pause");

}

用到贝塞尔曲线生成算法,生成一条曲线,开始编程的时候,没有考虑到该算法的本质,贝塞尔算法是四点决定一个曲线段。我以为是所有点进行遍历。从这次论文中我收获到很多。经过了一阶段计算机图形学的学习,对于图形学中基本图形的生成算法有了一定的了解。深度研究图形学,需要高深的数学知识且每一个细化的方向需要的知识也不一样。图形学是计算机科学与技术学科的活跃前沿学科,被广泛的应用到生物学、物理学、化学、天文学、地球物理学、材料科学等领域。我深深感到这门学科涉及的领域之广是惊人的,可以说博大精深。在这个计算机的时代什么都要用到计算机技术,图形也是我们生活中重要的部分。所以我们得好好学好图形学。

 下载本文

显示全文
专题