计算机图形学实验报告

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

一、实验目的

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);

// TODO: add draw code for native data here

//绘制之前先把整个窗口涂上背景色(白色)以便于下面的填充

RECT Rt;

GetClientRect(&Rt);

pDC->FillSolidRect(&Rt, RGB(255,255,255));

int ptx[] = {10, 100, 200, 150, 80};

int pty[] = {10, 50, 80, 120, 70};

FillPolygon(pDC, ptx, pty, 5);

}

截图如下

3.在世界坐标系中定义一个立方体(由6个面组成),并给定观察点在世界坐标系中的位置(a,b,c)以及观察坐标系的方位角θ,俯仰角φ和姿态角α,另外再给定投影面离观察点的距离D,在屏幕上画出立方体的透视投影图形。

实验基本步骤

首先、使用MFC AppWizard(exe)向导生成一个单文档视图程序框架。

其次、由给定观察点在世界坐标系中的位置(a,b,c)以及观察坐标系的方位角θ,俯仰角φ和姿态角α求出观察变换矩阵Tv.

再次、将立方体的每一个面的顶点坐标与变换矩阵Tv相乘得到观察坐标系中的坐标,再由式(1)求得二维投影坐标。并用直线连接这些二维投影坐标点形成每一个面在投影面的图形,依次将立方体的6个面画出即可。

核心代码如下:

void CTestView::OnDraw(CDC* pDC)

{

CTestDoc* pDoc = GetDocument();

ASSERT_V ALID(pDoc);

// TODO: add draw code for native data here

CRect Rect;

GetClientRect(&Rect);

int MaxX=Rect.right;

int MaxY=Rect.bottom;

pDC->SetMapMode(MM_ANISOTROPIC);

pDC->SetWindowExt(1, 1);

pDC->SetViewportExt(1, -1);

pDC->SetViewportOrg(MaxX/2, MaxY/2);//设置视点原点在屏幕中心DrawObject(pDC);

}

void CTestView::ReadPoint()//读入8个顶点坐标

{

//每一行代表正方体每个顶点的x,y,z坐标

int a=200;//正方体边长

P[1][1]=-a/2;P[1][2]=-a/2;P[1][3]=-a/2;

P[2][1]=-a/2;P[2][2]=a/2;P[2][3]=-a/2;

P[3][1]=-a/2;P[3][2]=a/2;P[3][3]=a/2;

P[4][1]=-a/2;P[4][2]=-a/2;P[4][3]=a/2;

P[5][1]=a/2;P[5][2]=-a/2;P[5][3]=-a/2;

P[6][1]=a/2;P[6][2]=a/2;P[6][3]=-a/2;

P[7][1]=a/2;P[7][2]=a/2;P[7][3]=a/2;

P[8][1]=a/2;P[8][2]=-a/2;P[8][3]=a/2;

相关文档
最新文档