计算机图形学实验报告

班级:10计科  姓名:敖智挺   学号:201030457117

实验一  直线生成与二次曲线拟合

实验内容:

应用 Bresenham画线算法实现一程序,完成直线生成。

实验目的:

1. 了解掌握VC下2D图元的扫描转换原理及VC实现;

2. 掌握图元属性原理及VC编程实现方法;

3. 掌握图元区域填充原理及模式,并验证实现相应的图元填充算法。

实验源代码:

#include<math.h>

#include <graphics.h>

#include <conio.h>

main()

{

 int driver=DETECT;

int mode;

int x1,y1,x2,y2;

initgraph(&driver,&mode,"");

 x1=100;y1=200;x2=400;y2=300;

 bsrline(x1,y1,x2,y2,4);

 getch();

closegraph();

}

bsrline(int x1,int y1,int x2,int y2,int c)

{

 int dx,dy;

 int x, y;

 int p;

int delta_p1,delta_p2;

  int inc;

 int tmp;

dx=x2-x1;

dy=y2-y1;

 if((dx>=0 && dy>=0)||(dx<0 && dy<0))

 inc=1;

else

 inc=-1;

  if(abs(dx)>abs(dy))

  {

f(dx<0)

  {

  tmp=x1;x1=x2;x2=tmp;

 tmp=y1;y1=y2;y2=tmp;

  dx=-dx;

 dy=-dy;

  }

 if(inc==-1)

 dy=-dy;

 p=2*dy-dx;

delta_p1=2*dy;

delta_p2=2*(dy-dx);

  x=x1;

 y=y1;

  putpixel(x,480-y,c);

while(x<x2)

 {

 x++;

  if(p<0)

 p+=delta_p1;

else

{

 y+=inc;

p+=delta_p2;

}

putpixel(x,480-y,c);

}

}

else

{

 if(dy<0)

{

 tmp=x1;x1=x2;x2=tmp;

 tmp=y1;y1=y2;y2=tmp;

dx=-dx;

 dy=-dy;

  }

 if(inc==-1)

 dx=-dx;

  p=2*dx-dy;

delta_p1=2*dx;

delta_p2=2*(dx-dy);

x=x1;

y=y1;

putpixel(x,480-y,c);    while(y<y2)

{

 y++;

 if(p<0)

 p+=delta_p1;

 else

  {

x+=inc;

p+=delta_p2;

  }

 putpixel(x,480-y,c);

}

}

实验结果:

实验小结:通过这第一次次实验让我理解怎样应用 Bresenham算法实现直线的画法,让我基本了解计算机图形学学习的方向。

实验二二维图元的几何变换

实验内容:

编写程序实现将一多边形绕指定坐标连续经过三中变换进行旋转。

实验目的:

1. 了解掌握VC下2D图元的几何变换的数学原理及公式;

2. 掌握2D 图元的三种基本几何变换的计算机实现方法。

实验源代码:

#include<windows.h>

#include <GL/glut.h>

#include <stdlib.h>

void init(void)

{

    glClearColor (0.0, 0.0, 0.0, 0.0);

    glShadeModel (GL_SMOOTH);

}

void draw_triangle(void)

{

    glShadeModel(GL_SMOOTH);

    glColor3f(0.2,0.7,0.30);

    glBegin (GL_TRIANGLES);//画出三角形,为混合色填充方式

        glVertex2f(50.0, 25.0);

        glColor3f(0.4,0.5,0.60);

        glVertex2f(150.0, 25.0);

        glColor3f(0.9,0.7,0.8);

        glVertex2f(100.0, 100.0);

    glEnd();

}

void display(void)

{

    glClear (GL_COLOR_BUFFER_BIT);

    glColor3f (1.0, 1.0, 1.0);

    glLoadIdentity ();

    glColor3f (1.0, 1.0, 1.0);

    glTranslatef(-100.0,-50.0,1.0);

    draw_triangle ();

    glLoadIdentity ();

    glTranslatef (0.0, 100.0, 1.0);

    glRotatef (90.0, 0.0, 0.0, 1.0);

    glScalef (0.5, 0.5, 1.0);

    draw_triangle ();//经过三种变换后画出图形

    glFlush ();

}

void reshape (int w, int h)

{

    glViewport (0, 0, (GLsizei) w, (GLsizei) h);

    glMatrixMode (GL_PROJECTION);

    glLoadIdentity ();

    if (w <= h)

        gluOrtho2D (-200.0, 250.0, -100.0*(GLfloat)h/(GLfloat)w,

                    200.0*(GLfloat)h/(GLfloat)w);//调整裁剪窗口

    else

        gluOrtho2D (-200.0*(GLfloat)w/(GLfloat)h,

                    250.0*(GLfloat)w/(GLfloat)h, -50.0, 200.0);

    glMatrixMode(GL_MODELVIEW);

}

int main(int argc, char** argv)

{

    glutInit(&argc, argv);

    glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);

    glutInitWindowSize (600, 600);

    glutInitWindowPosition (100, 100);

    glutCreateWindow (argv[0]);

    init ();

    glutDisplayFunc(display);

    glutReshapeFunc(reshape);

    glutMainLoop();

    return 0;

}

实验结果:

实验小结:

通过本次试验让我掌握了2D图元的几何变换的数学原理及公式,掌握2D 图元的三种基本几何变换的计算机实现方法。让我学会怎样应用代码实现二维图元的画法。

实验三  二维图元裁剪

实验内容:

设计和实现一个能生成和显示应用Cohen—Suherland 算法或梁友栋裁剪算法对

直线进行裁剪前后的直线段。

以不同的线型、线宽显示裁剪前后的直线段。

实验目的:

1. 了解掌握二维观察的原理及坐标变换过程;掌握窗口与视区的相互转

换过程及数学模型推导。

2. 掌握2D 图元裁剪的原理与计算机实现方法。

实验源代码:

void CMyView::OnDraw(CDC* pDC)

{

       CMyDoc* pDoc = GetDocument();

       ASSERT_VALID(pDoc);

       // TODO: add draw code for native data here

       Point FrameLT,FrameRB;

    Point P[5];

    FrameLT.x=150;FrameLT.y=150;

    FrameRB.x=320;FrameRB.y=320;

    pDC->Rectangle((int)FrameLT.x,(int)FrameLT.y,(int)FrameRB.x,(int)FrameRB.y);

       for(int i = 0; i < 5; i++)

       {

              P[i].x = (float)(260 + 150*cos(72*i*PI/180) +0.5);

              P[i].y = (float)(260 + 150*sin(72*i*PI/180) +0.5);           

       }

       pDC->MoveTo((int)P[0].x,(int)P[0].y);

       pDC->LineTo((int)P[2].x,(int)P[2].y);

       pDC->LineTo((int)P[4].x,(int)P[4].y); 

       pDC->LineTo((int)P[1].x,(int)P[1].y); 

       pDC->LineTo((int)P[3].x,(int)P[3].y); 

       pDC->LineTo((int)P[0].x,(int)P[0].y);

}

void CMyView::Code(Point FrameLT,Point FrameRB,Point P,unsigned char *Flag)

{

    unsigned char flag=0;

    if(P.x<FrameLT.x) flag+=1;

    if(P.x>FrameRB.x) flag+=2;

    if(P.y>FrameRB.y) flag+=4;

    if(P.y<FrameLT.y) flag+=8;

    (*Flag)=flag;

}

void CMyView::Clipping(Point FrameLT,Point FrameRB,Point LineSP,Point LineEP)

{

       CClientDC dc(this);

    unsigned char flagSP,flagEP,flagAND,flagOR;

    double k=(LineEP.y-LineSP.y)/(LineEP.x-LineSP.x);

    Code(FrameLT,FrameRB,LineSP,&flagSP);

    Code(FrameLT,FrameRB,LineEP,&flagEP);

    flagAND=flagSP & flagEP;

    if(flagAND!=0)return;

    while(flagSP!=0||flagEP!=0)

    {

        flagOR=flagSP|flagEP;

        if((flagOR&0x01)==1)

           {

            if((flagSP&0x01)==1)

                  {

                LineSP.y=(float)(LineSP.y+k*(FrameLT.x-LineSP.x));

                LineSP.x=FrameLT.x;

                Code(FrameLT,FrameRB,LineSP,&flagSP);

                  }

               else

                  {

                LineEP.y=(float)(LineEP.y+k*(FrameLT.x-LineEP.x));

                LineEP.x=FrameLT.x;

                Code(FrameLT,FrameRB,LineEP,&flagEP);

                  }

           }

        if((flagOR&0x02)==2)

           {

            if((flagSP&0x02)==2)

                  {

                LineSP.y=(float)(LineSP.y+k*(FrameRB.x-LineSP.x));

                LineSP.x=FrameRB.x;

                Code(FrameLT,FrameRB,LineSP,&flagSP);

                  }

               else

                  {

                LineEP.y=(float)(LineEP.y+k*(FrameRB.x-LineEP.x));

                LineEP.x=FrameRB.x;

                Code(FrameLT,FrameRB,LineEP,&flagEP);

                  }

           }

        if((flagOR&0x04)==4)

           {

            if((flagSP&0x04)==4)

                  {

                LineSP.x=(float)(LineSP.x+(FrameRB.y-LineSP.y)/k);

                LineSP.y=FrameRB.y;

                Code(FrameLT,FrameRB,LineSP,&flagSP);

                  }

               else

                  {

                LineEP.x=(float)(LineEP.x+(FrameRB.y-LineEP.y)/k);

                LineEP.y=FrameRB.y;

                Code(FrameLT,FrameRB,LineEP,&flagEP);

                  }

           }

        if((flagOR&0x08)==8)

           {

            if((flagSP&0x08)==8)

                  {

                LineSP.x=(float)(LineSP.x+(FrameLT.y-LineSP.y)/k);

                LineSP.y=FrameLT.y;

                Code(FrameLT,FrameRB,LineSP,&flagSP);

                  }

               else

                  {

                LineEP.x=(float)(LineEP.x+(FrameLT.y-LineEP.y)/k);

                LineEP.y=FrameLT.y;

                Code(FrameLT,FrameRB,LineEP,&flagEP);

                  }

            flagAND=flagSP&flagEP;

            if(flagAND!=0)return;

           }

        dc.MoveTo((int)LineSP.x,(int)LineSP.y);

              dc.LineTo((int)LineEP.x,(int)LineEP.y);

    }

}

void CMyView::OnCut() //裁剪

{

       CClientDC dc(this);

       CPen pen(PS_SOLID,1,RGB(255,255,255));

       CPen *pOldpen = dc.SelectObject(&pen);

       CBrush *pBrush=CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));

       dc.SelectObject(pBrush);

      

       Point FrameLT,FrameRB;

    Point P[5];

    FrameLT.x=150;FrameLT.y=150;

    FrameRB.x=320;FrameRB.y=320;

      

    dc.Rectangle((int)FrameLT.x,(int)FrameLT.y,(int)FrameRB.x,(int)FrameRB.y);

       for(int i = 0; i < 5; i++)

       {

              P[i].x = (float)(260 + 150*cos(72*i*PI/180) +0.5);

              P[i].y = (float)(260 + 150*sin(72*i*PI/180) +0.5);           

       }

       dc.MoveTo((int)P[0].x,(int)P[0].y);

       dc.LineTo((int)P[2].x,(int)P[2].y);

       dc.LineTo((int)P[4].x,(int)P[4].y);      

       dc.LineTo((int)P[1].x,(int)P[1].y);      

       dc.LineTo((int)P[3].x,(int)P[3].y);      

       dc.LineTo((int)P[0].x,(int)P[0].y);

    dc.SelectObject(pOldpen);    

       dc.Rectangle((int)FrameLT.x,(int)FrameLT.y,(int)FrameRB.x,(int)FrameRB.y);

              Clipping(FrameLT,FrameRB,P[0],P[2]);

       Clipping(FrameLT,FrameRB,P[2],P[4]);

       Clipping(FrameLT,FrameRB,P[4],P[1]);

       Clipping(FrameLT,FrameRB,P[1],P[3]);

       Clipping(FrameLT,FrameRB,P[3],P[0]);     

}

实验结果:

实验小结:

裁剪处理的主要步骤是:①图元关于窗口内外关系的判别;②图元与窗口的求交。通过这次试验,我对二维裁剪的步骤以及各种算法都有了一定的了解,包括直线段的裁剪和多边形的裁剪。也在实验过程中发现了学习中的很多不足之处并及时改正。

实验四  三维图形几何变换、显示

作业内容

1. 实现一个初步具有真实感的消隐后的球体。

2.球体的面片显示。

3.应用后向面判别算法进行消隐。

选作内容:PHONG 明暗处理、纹理与材料处理。

实验目的:

1. 了解掌握三维物体的存储、透视处理、消隐的原理及实现方法。

2. 掌握真实图形生成时的简单光照处理的原理与算法实现。

实验源代码:

实验结果:

实验小结:

通过本次试验让我更加了解掌握三维物体的存储、透视处理、消隐的原理及实现方法,更加了解怎样掌握真实图形生成时的简单光照处理的原理与算法实现。

相关推荐