计算机图形学实验指导

实验课程任务与要求

目的与任务:

计算机图形学实验教学是为了将学生的计算机操作能力、分析能力、工程设计能力与应用实践结合起来,引导学生由浅入深地掌握计算机图形学理论与算法,掌握交互构图能力,具备工程应用的图形学基础。

实验基本要求:(以软件设计为主要表现形式)

(1)上机前应准备好实验的程序设计算法描述与关键分析内容。

(2)准备好程序测试数据和设备操作步骤,上机调试、运行。

(3)完成每个实验后进行数据与程序对比分析。

(4)写出实验报告(含实验题目,不同顺序或本次算法的比较与效果分析,给出

运行结果。若实验未能通过,给出原因与今后改进措施)。

实验报告式样:

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

实验题目

一.设计目的及要求

二.理论基础

三.算法设计与分析

四.程序调试及运行结果的自我分析与自我评价

五.设计心得及建议

实验一 VC++6.0+OpenGL绘图环境及简单图形的输出

学时安排:(2学时)

要求:(1)掌握VC++6.0+OpenGL绘图环境的设置;

(2)利用OpenGL绘制简单图形并在设备上输出;

(3)用glut编C++程程序的方法。

实验指导:

MFC编程

1.开发环境的配置

(1)将“glut32.dll”文件拷贝到操作系统对应的目录中。

(2)将“glut32.h”文件拷贝到VC++6.0的Include文件夹中。

(3)将“glut32.lib”文件拷贝到VC++6.0的lib文件夹中。

2.启动VC6.0,新建一个单文档应用程序,如名称MySDOpenGL。

3.利用MFC ClassWizard为CMySDOpenGLView类添加消息WM_CREATE ,WM_DESTROY ,WM_SIZE,WM_TIMER的响应函数。

4.如下所示在MySDOpenGLView.h中加入源代码。

public: //添加成员函数与成员变量

BOOL RenderScene();

BOOL SetupPixelFormat(void);

void SetLogicalPalette(void);

BOOL InitializeOpenGL(CDC* pDC);

HGLRC m_hRC; //OpenGL绘制描述表

HPALETTE m_hPalette; //OpenGL调色板

CDC* m_pDC; //OpenGL设备描述表

5.如下所示在MySDOpenGLView.cpp中加入源代码。

BOOL CMySDOpenGLView::PreCreateWindow(CREATESTRUCT& cs)

{ 。。。。。。

cs.style |=WS_CLIPCHILDREN | WS_CLIPSIBLINGS; //设置窗口类型

。。。。。。

}

void CMySDOpenGLView::OnDraw(CDC* pDC)

{

。。。。。。

RenderScene(); //渲染场景

。。。。。。

}

int CMySDOpenGLView::OnCreate(LPCREATESTRUCT lpCreateStruct) {

if (CView::OnCreate(lpCreateStruct) == -1) return -1;

//初始化OpenGL和设置定时器

m_pDC = new CClientDC(this);

SetTimer(1, 20, NULL);

InitializeOpenGL(m_pDC);

return 0;

}

void CMySDOpenGLView::OnDestroy()

{

CView::OnDestroy();

//删除调色板和渲染上下文、定时器

::wglMakeCurrent(0,0);

::wglDeleteContext( m_hRC);

if (m_hPalette)

DeleteObject(m_hPalette);

if ( m_pDC ) { delete m_pDC; }

KillTimer(1);

}

void CMySDOpenGLView::OnSize(UINT nType, int cx, int cy) {

CView::OnSize(nType, cx, cy);

//添加窗口缩放时的图形变换函数

glViewport(0,0,cx,cy);

glMatrixMode (GL_PROJECTION);

glLoadIdentity ();

gluPerspective(60.0, (GLfloat) cx/(GLfloat) cy, 1.0, 20.0);

glMatrixMode(GL_MODELVIEW);

glLoadIdentity();

gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);

}

void CMySDOpenGLView::OnTimer(UINT nIDEvent)

{//添加定时器响应函数和场景更新函数

Invalidate(FALSE);

//year = (year + 5) % 360;day = (day + 10) % 360;

CView::OnTimer(nIDEvent);

}

void CMySDOpenGLView::SetLogicalPalette(void) //设置逻辑调色板

{

struct{

WORD Version;

WORD NumberOfEntries;

PALETTEENTRY aEntries[256];

} logicalPalette = { 0x300, 256 };

BYTE reds[] = {0, 36, 72, 109, 145, 182, 218, 255};

BYTE greens[] = {0, 36, 72, 109, 145, 182, 218, 255};

BYTE blues[] = {0, 85, 170, 255};

for (int colorNum=0; colorNum<256; ++colorNum)

{

logicalPalette.aEntries[colorNum].peRed =

reds[colorNum & 0x07];

logicalPalette.aEntries[colorNum].peGreen =

greens[(colorNum >> 0x03) & 0x07];

logicalPalette.aEntries[colorNum].peBlue =

blues[(colorNum >> 0x06) & 0x03];

logicalPalette.aEntries[colorNum].peFlags = 0;

}

m_hPalette = CreatePalette ((LOGPALETTE*)&logicalPalette);

}

BOOL CMySDOpenGLView::InitializeOpenGL(CDC* pDC) //初始化openGL场景{

m_pDC = pDC;

SetupPixelFormat();

m_hRC = ::wglCreateContext(m_pDC->GetSafeHdc());//生成绘制描述表

::wglMakeCurrent(m_pDC->GetSafeHdc(), m_hRC); //置当前绘制描述表

return TRUE;

}

BOOL CMySDOpenGLView::SetupPixelFormat()//设置像素格式

{

PIXELFORMATDESCRIPTOR pfd = {

sizeof(PIXELFORMATDESCRIPTOR), // pfd结构的大小

1, // 版本号

PFD_DRAW_TO_WINDOW | // 支持在窗口中绘图

PFD_SUPPORT_OPENGL | // 支持OpenGL

PFD_DOUBLEBUFFER, // 双缓存模式

PFD_TYPE_RGBA, // RGBA 颜色模式

24, // 24 位颜色深度

0, 0, 0, 0, 0, 0, // 忽略颜色位

0, // 没有非透明度缓存

0, // 忽略移位位

0, // 无累加缓存

0, 0, 0, 0, // 忽略累加位

32, // 32 位深度缓存

0, // 无模板缓存

0, // 无辅助缓存

PFD_MAIN_PLANE, // 主层

0, // 保留

0, 0, 0 // 忽略层,可见性和损毁掩模};

int pixelformat;

pixelformat = ::ChoosePixelFormat(m_pDC->GetSafeHdc(), &pfd);//选择像素格式::SetPixelFormat(m_pDC->GetSafeHdc(), pixelformat, &pfd); //设置像素格式

if(pfd.dwFlags & PFD_NEED_PALETTE)

SetLogicalPalette(); //设置逻辑调色板

return TRUE;

}

BOOL CMySDOpenGLView::RenderScene()//场景绘制与渲染

{

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

/////////ADD Draw Code////////////////////////////////

//////////////////////////////////////////////////////

::SwapBuffers(m_pDC->GetSafeHdc()); //交互缓冲区

return TRUE;

}

至此,VC++6.0与OpenGL就关联在一起,进行绘制图形。

6. 下面利用OpenGL绘制简单图形

BOOL CMySDOpenGLView::RenderScene() //场景绘制与渲染

{

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

/////////ADD Draw Code////////////////////////////////

glBegin(GL_TRIANGLES);//绘制三角形

glColor3f (1.0, 0.0, 0.0);glVertex3f(0.0,1.0,0.0);

glColor3f (0.0, 1.0, 0.0);glVertex3f(-1.0,-1.0,0.0);

glColor3f (0.0, 0.0, 1.0);glVertex3f(1.0,-1.0,0.0);

glEnd();

//////////////////////////////////////////////////////

::SwapBuffers(m_pDC->GetSafeHdc()); //交互缓冲区

return TRUE;

}

用glut编C++程程序的方法

新建一win32 console project,然后加入下面的tut1.cpp:

#include

void display()

{

}

int main(int argc, char** argv)

{

glutInit(&argc, argv);

glutInitDisplayMode (GLUT_SINGLE | GLUT_RGBA);

//设置显示模式:单缓冲区, RGBA颜色模式

glutInitWindowSize (200, 200);

//设置窗口宽度、高度

glutCreateWindow (argv[0]);

//弹出窗口

glutDisplayFunc (display);

//设置窗口刷新的回调函数

glutMainLoop();

//开始主循环

return 0;

}

display()是窗口刷新的回调函数。每当被遮住的窗口再次暴露出来时,系统就调用此函数刷新窗口(即在窗口里作图)。因为我们的display() 什么也不干,因此你看到窗口里是它后面的背景。

我们先画个正方形。别的不变,只需要改display()

void display()

{

glClearColor(1,1,1,1);

//设置刷新背景色

glClear(GL_COLOR_BUFFER_BIT);

//刷新背景

glBegin(GL_LINE_LOOP);

glColor3f(1,0,0);

//设置当前颜色

glVertex3f(-0.9,-0.9,0);

glVertex3f(0.9,-0.9,0);

glVertex3f(0.9,0.9,0);

glVertex3f(-0.9,0.9,0);

glEnd();

glFlush();

//更新窗口

}

实验上述内容,写出实验报告。

实验二、基本图形学算法实验

学时安排:(2学时)

要求:

(1)分别用中点法、数值微分法、Bresenham法,绘制任意直线、圆,并比较各种算法的差别;

(2)种子填充算法、扫描填充算法进行区域填充与比较。

(3)改造圆的生成算法为填充算法将该实验加入到菜单中去。

实验指导:

1.直线的Bresenham算法实现

void BresenhamLine(int x1, int y1, int x2, int y2,int c)

{

int iTag=0;

int dx, dy, tx, ty, inc1, inc2, d, curx, cury;

set_pixel(x1,y1, c);

if(x1==x2 && y1==y2) return;

dx=abs(x2-x1); dy=abs(y2-y1);

if(dx

{

iTag=1; Swap(x1, y1); Swap(x2, y2); Swap(dx, dy);

}

tx=(x2-x1)>0?1:-1; ty=(y2-y1)>0?1:-1;

curx=x1; cury=y1; inc1=2*dy; inc2=2*(dy-dx); d=inc1-dx;

while(curx!=x2)

{

curx+=tx;

if(d<0) { d+=inc1; }

else {cury+=ty; d+=inc2; }

if(iTag)

set_pixel(cury, curx, c);

else

set_pixel(curx, cury, c);

}

}

void CMyDraw::Swap(int &a, int &b)

{

int temp;

temp=a; a=b; b=temp;

}

2.中点法绘圆算法实现

void MidCircle(int xc, int yc, int radious,int color)

{

int x,y;

float d;

x=0;

y=radious;

d=(float)1.25-(float)radious;

plot_circle_points(xc, yc, x, y, color);

while(x<=y)

{

if(d<0) d+=2*x+3;

else

{

d+=2*(x-y)+5; y--;

}

x++;

plot_circle_points(xc, yc, x, y, color);

}

}

void CMyDraw::plot_circle_points(int xc, int yc, int x, int y, int c)

{

set_pixel(xc+x, yc+y, c); set_pixel(xc-x, yc+y, c);

set_pixel(xc+x, yc-y, c); set_pixel(xc-x, yc-y, c);

set_pixel(xc+y, yc+x, c); set_pixel(xc-y, yc+x, c);

set_pixel(xc+y, yc-x, c); set_pixel(xc-y, yc-x, c);

}

3.扫描线填充算法实现

void SeedfloodScan_Fill(int x, int y, COLORREF oldColor, COLORREF newColor) {//填充区域

CRect rect;

m_pDC->GetWindow()->GetClientRect(&rect);

if(newColor==oldColor) return;

int px[1000],py[1000],xsave,xleft,xright,np=0;

px[np]=x; py[np]=y;

while(np>-1)

{

y=py[np];

x=xsave=px[np];

np--;

while(m_pDC->GetPixel(x, y)==oldColor && x

{

m_pDC->SetPixel( x, y, newColor);

x++;

}

xright=x; x=xsave-1;

while(m_pDC->GetPixel(x, y)==oldColor && x>=0)

{

m_pDC->SetPixel( x, y, newColor);

x--;

}

xleft=x; y++;

if(y

while(x

{

while(++xGetPixel(x, y)!=oldColor)

;

if(x==xright)

break;

while(++xGetPixel(x, y)==oldColor)

;

np++; px[np]=x; py[np]=y;

}

x=xleft; y-=2;

if(y>=0)

while(x

{

while(++xGetPixel(x, y)!=oldColor)

;

if(x==xright)

break;

while(++xGetPixel(x, y)==oldColor)

;

np++; px[np]=x; py[np]=y;

}

}

return;

}

4.较各算法,写出实验报告。

实验三、人机交互图形的操作实验

学时安排:(4学时)

要求:

(1)设计鼠标、对话框、菜单,实现人机交互方式控制图形简单操作。

(2)利用橡皮筋技术实现基本几何图形的绘制;

(3)将该实验加入到菜单中去;

实验指导:

1.利用鼠标绘图的实现

建立MFC的单文档应用程序Student,在CStudentView类种添加鼠标消息函数:void CStudentView::OnLButtonDown(UINT nFlags, CPoint point)

{

// TODO: Add your message handler code here and/or call default

CClientDC dc(this);

startPoint.x=point.x;startPoint.y=point.y;// startPoint为CStudentView成员变量

IsLButtonUp = false;

CView::OnLButtonDown(nFlags, point);

}

void CYybView::OnMouseMove(UINT nFlags, CPoint point)

{

// TODO: Add your message handler code here and/or call default

CClientDC dc(this);

CPen newpen(PS_SOLID,1,myColor);

CPen* oldPen=dc.SelectObject(&newpen);

endPoint.x = point.x ;

endPoint.y = point.y ;

if(!IsLButtonUp)

{

dc.MoveTo(startPoint);

dc.LineTo(endPoint.x,endPoint.y);

startPoint.x = endPoint.x ;

startPoint.y = endPoint.y ;

}

}

void CYybView::OnLButtonUp(UINT nFlags, CPoint point)

{

// TODO: Add your message handler code here and/or call default

IsLButtonUp = true;

}

2.橡皮筋技术绘制圆

void CStudentView::OnLButtonDown(UINT nFlags, CPoint point)

{

// TODO: Add your message handler code here and/or call default

CClientDC dc(this);

CPen newpen(PS_SOLID,1,myColor);//创建新的画笔

CPen* oldpen;SetCursor(m_csCross);

if(flag==0)//第一次按下鼠标

{

flag=1;

startPoint=endPoint=point;

}

else

{//第二次按下鼠标,将新画笔选进设备上下文中

oldpen=dc.SelectObject(&newpen);

dc.SetROP2(R2_XORPEN);//设置画线模式为异或

dc.MoveTo(startPoint);

dc.LineTo(endPoint);

BresenhamCircle(startPoint.x,startPoint.y,(int)sqrt((startPoint.x-endPoint.x)*(startPoint.x-endPoint.x)+ (startPoint.y-endPoint.y)*(startPoint.y-endPoint.y)),myColor);

}

endPoint=point;

dc.SetROP2(R2_COPYPEN);

BresenhamCircle(startPoint.x,startPoint.y,(int)sqrt((startPoint.x-endPoint.x)*(startPoint.x-endPoin t.x)+(startPoint.y-endPoint.y)*(startPoint.y-endPoint.y)),myColor);

dc.SelectObject(oldpen);

flag=0;

}

CView::OnLButtonDown(nFlags, point);

}

void CStudentView::OnMouseMove(UINT nFlags, CPoint point)

{

// TODO: Add your message handler code here and/or call default

CClientDC dc(this);

CPen newpen(PS_SOLID,1,myColor);

CPen* oldPen=dc.SelectObject(&newpen);

if(myelasticFlag)

{

dc.SetROP2(R2_XORPEN);SetCursor(m_csCross);

if(flag==1)//第二次按下鼠标

{

dc.MoveTo(startPoint);

dc.LineTo(endPoint);

BresenhamCircle(startPoint.x,startPoint.y,(int)sqrt((startPoint.x-endPoint.x)*(startPoint.x-endPoint.x)+ (startPoint.y-endPoint.y)*(startPoint.y-endPoint.y)),myColor);

}

endPoint=point;

dc.MoveTo(startPoint);

dc.LineTo(endPoint);

BresenhamCircle(startPoint.x,startPoint.y,(int)sqrt((startPoint.x-endPoint.x)*(startPoint.x-endPoint.x)+ (startPoint.y-endPoint.y)*(startPoint.y-endPoint.y)),myColor);

}

dc.SetROP2(R2_COPYPEN);

dc.SelectObject(oldPen);

CView::OnMouseMove(nFlags, point);

}

利用对话框可以实现参数的交互输入,如:直线的端点坐标通过对话框输入;

利用菜单控制鼠标绘图、橡皮筋绘圆等功能,是通过变量来控制的。

3.完成实验要求的各项内容,写出实验报告。

实验四、自由曲线、曲面的算法实验

学时安排:(2学时)

要求:(1)绘制三次Bezier 曲线、B 样条曲线和插值曲线,并掌握其应用;

(2) 绘制双三次Bezier 曲面、B 样条曲面;

(3) 利用追赶法反求B 样条曲线控制顶点的方法绘制三次B 样条曲线。 实验指导:

1.三次自由曲线的定义 a)三次Bezier 曲线

⎥⎥⎥⎥⎦

⎢⎢⎢⎢⎣⎡⎥⎥⎥⎥⎦⎤⎢

⎢⎢

⎢⎣⎡----=32102

300010033036313

31)1()(P P P P t t t t P b) 三次B 样条曲线

(

)

⎥⎥⎥⎥⎦

⎢⎢⎢⎢⎣⎡⎥⎥⎥⎥⎦⎤⎢

⎢⎢

⎢⎣⎡----=

32102

3

0141

03030363133116

1)(P P P P t t t t P c) 三次插值曲线

(

)

⎥⎥⎦

⎢⎢⎢⎢⎣⎡⎥⎥⎥⎥⎦⎤⎢⎢⎢

⎢⎣⎡=32102

3

1000

0100001000011)(P P P P t t t t P

2.双三次Bezier 曲面、B 样条曲面的实现

双三次Bezier 曲面:

(

)

⎥⎥⎥⎥⎥⎦

⎢⎢⎢⎢⎢⎣⎡⎥⎥⎥⎥⎦⎤⎢⎢⎢

⎢⎣⎡----⎥⎥⎥⎥⎦⎤⎢⎢⎢⎢⎣⎡⎥⎥⎥⎥⎦⎤⎢

⎢⎢

⎢⎣⎡----=100010033036313

310001

0033036313311),(233332

31

30

232221201312111003020100

2

3

v v v P P P P P P P P P P P P P P P P u u u v u P 双三次B 样条曲面:

(

)

⎥⎥⎥⎥⎥⎦

⎢⎢⎢⎢⎢⎣⎡⎥⎥⎥⎥⎦⎤⎢⎢⎢

⎢⎣⎡----⎥⎥⎥⎥⎦⎤⎢⎢⎢⎢⎣⎡⎥⎥⎥⎥⎦⎤⎢

⎢⎢

⎢⎣⎡----=101410303036313

310141

0303036313311),(233332

31

30

232221201312111003020100

2

3

v v v P P P P P P P P P P P P P P P P u u

u

v u P

下面是绘制三次Bezier 曲线、B 样条曲线和插值曲线的C++程序源代码。

#include typedef enum {

BEZIER,

INTERPOLATED, BSPLINE } curveType;

void keyboard(unsigned char key, int x, int y); void computeMatrix(curveType type, float m[4][4]); void vmult(float m[4][4], float v[4][3], float r[4][3]); /* Colors to draw them in */

GLfloat colors[][3] ={{ 1.0, 0.0, 0.0 },{ 0.0, 1.0, 0.0 }, { 0.0, 0.0, 1.0 }};

#define MAX_CPTS 300 /* Fixed maximum number of control points */ GLfloat cpts[MAX_CPTS][3]; int ncpts = 0;

static int width = 500, height = 500; /* Window width and height */ /* Matrix stuff */

/* This routine multiplies two 4 x 4 matrices. */

/* This routine multiplies a 4 x 4 matrix with a vector of 4 points. */ void vmult(float m[4][4], float v[4][3], float r[4][3]) {

int i, j, k;

for (i = 0; i < 4; i++) for (j = 0; j < 3; j++)

for (k = 0, r[i][j] = 0.0; k < 4; k++) r[i][j] += m[i][k] * v[k][j]; }

/* Interpolating to Bezier matrix */ static float minterp[4][4] = {

{ 1.0, 0.0, 0.0, 0.0 },{ -5.0/6.0, 3.0, -3.0/2.0, 1.0/3.0 }, { 1.0/3.0, -3.0/2.0, 3.0, -5.0/6.0 },{ 0.0, 0.0, 0.0, 1.0 }, };

/* B-spline to Bezier matrix */ static float mbspline[4][4] = {

{ 1.0/6.0, 4.0/6.0, 1.0/6.0, 0.0 },{ 0.0, 4.0/6.0, 2.0/6.0, 0.0 },

{ 0.0, 2.0/6.0, 4.0/6.0, 0.0 },{ 0.0, 1.0/6.0, 4.0/6.0, 1.0/6.0 },

};

static float midentity[4][4] =

{{ 1.0, 0.0, 0.0, 0.0},{ 0.0, 1.0, 0.0, 0.0},{ 0.0, 0.0, 1.0, 0.0},{ 0.0, 0.0, 0.0, 1.0}}; /* Calculate the matrix used to transform the control points */

void computeMatrix(curveType type, float m[4][4])

{

int i, j;

switch (type)

{

case BEZIER:

/* Identity matrix */

for (i = 0; i < 4; i++)

for (j = 0; j < 4; j++)

m[i][j] = midentity[i][j];

break;

case INTERPOLATED:

for (i = 0; i < 4; i++)

for (j = 0; j < 4; j++)

m[i][j] = minterp[i][j];

break;

case BSPLINE:

for (i = 0; i < 4; i++)

for (j = 0; j < 4; j++)

m[i][j] = mbspline[i][j];

break;

}

}

/* Draw the indicated curves using the current control points. */

static void drawCurves(curveType type)

{

int i,step;

GLfloat newcpts[4][3];

float m[4][4];

/* Set the control point computation matrix and the step size. */

computeMatrix(type, m);

if(type == BSPLINE)

step = 1;

else

step = 3;

glColor3fv(colors[type]);

/* Draw the curves */

i = 0;

while (i + 3 < ncpts)

{

/* Calculate the appropriate control points */

vmult(m, &cpts[i], newcpts);

/* Draw the curve using OpenGL evaluators */

glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, &newcpts[0][0]);

glMapGrid1f(30, 0.0, 1.0);

glEvalMesh1(GL_LINE, 0, 30);、

/* Advance to the next segment */

i += step;

}

glColor3f(1.0,0.0,0.0);

glLineWidth(2);

glFlush();

}

/* This routine displays the control points */

static void display(void)

{

int i;

glClear(GL_COLOR_BUFFER_BIT);

glFlush();

}

static void mouse(int button, int state, int x, int y)

{

float wx, wy;

/* We are only interested in left clicks */

if (button != GLUT_LEFT_BUTTON || state != GLUT_DOWN) return;

/* Translate back to our coordinate system */

wx = (2.0 * x) / (float)(width - 1) - 1.0;

wy = (2.0 * (height - 1 - y)) / (float)(height - 1) - 1.0;

/* See if we have room for any more control points */

if (ncpts == MAX_CPTS) return;

/* Save the point */

cpts[ncpts][0] = wx; cpts[ncpts][1] = wy; cpts[ncpts][2] = 0.0;

ncpts++;

/* Draw the point */

glColor3f(0.0, 0.0, 0.0); glPointSize(5.0);

glBegin(GL_POINTS);

glVertex3f(wx, wy, 0.0);

glEnd();

glFlush();

}

void keyboard(unsigned char key, int x, int y)

{

static curveType lasttype = BEZIER;

switch (key)

{

case'q': case'Q':

exit(0); break;

case'c': case'C':

ncpts = 0; glutPostRedisplay(); break;

case'e': case'E':

glutPostRedisplay(); break;

case'b': case'B':

drawCurves(BEZIER); lasttype = BEZIER; break;

case'i': case'I':

drawCurves(INTERPOLATED); lasttype = INTERPOLATED; break;

case's': case'S':

drawCurves(BSPLINE); lasttype = BSPLINE; break;

}

}

void reshape(int w, int h)

{

width = w; height = h;

/* Set the transformations */

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);

glMatrixMode(GL_MODELVIEW);

glViewport(0, 0, w, h);

}

main(int argc, char **argv)

{

/* Intialize the program */

glutInit(&argc, argv);

glutInitDisplayMode(GLUT_RGB);

glutInitWindowSize(width, height);

glutCreateWindow("curves");

/* Register the callbacks */

glutDisplayFunc(display);

glutMouseFunc(mouse);

glutKeyboardFunc(keyboard);

glutReshapeFunc(reshape);

glClearColor(1.0, 1.0, 1.0, 1.0);

glEnable(GL_MAP1_VERTEX_3);

glutMainLoop();

}

完成实验要求的内容,写出实验报告。

实验五、三维观察及几何变换实验

学时安排:(2学时)

要求:(1)进行三维观察流程设计,理解透视变换、观察体与三维裁剪的实现;

(2)行比例、平移、旋转等几何变换设计;

(3)对变化参数进行交互设计。

实验指导:

a)透视投影变换与观察(相机)设置

b)正投影变换

glOrtho(Gldouble left,Gldouble right,Gldouble bottom,Gldouble top,Gldouble near,Gldouble far);

视图体是一个长方体。

c)比例变换

glScalef(float x,float y,float z);

d)平移变换

glTranslatef(float x,float y,float z);

e)旋转变换

glRotatef(float that,float x,float y,float z);that为旋转角,

以度为单位;旋转轴为从(0,0,0)到(x,y,z)的线。

下面是实现一个球围绕另一个球旋转的C/C++程序。

#include

#include

static int year = 0, day = 0;

void init(void)

{

glClearColor (0.0, 0.0, 0.0, 0.0);

glShadeModel (GL_FLAT);

}

void display(void)

{

glClear (GL_COLOR_BUFFER_BIT);

glColor3f (1.0, 1.0, 1.0);

glPushMatrix();

glutWireSphere(1.0, 20, 16); /* draw sun */

glRotatef ((GLfloat) year, 0.0, 1.0, 0.0);

glTranslatef (2.0, 0.0, 0.0);

glRotatef ((GLfloat) day, 0.0, 1.0, 0.0);

glutWireSphere(0.2, 10, 8); /* draw smaller planet */

glPopMatrix();

glutSwapBuffers();

}

void reshape (int w, int h)

{

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

glMatrixMode (GL_PROJECTION);

glLoadIdentity ();

gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1.0, 20.0);

glMatrixMode(GL_MODELVIEW);

glLoadIdentity();

gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);

}

void keyboard (unsigned char key, int x, int y)

计算机图形学实验指导书(vc++版)

实验指导书 刘文涛 2013

目录 第一章图形学实验环境和要求 (4) 1.1 VC++实验环境 (4) 1.1.1 基本环境 (4) 1.1.1 开发图形程序的一般流程 (7) 1.1.3 基本绘图函数介绍 (11) 1.2 OpenGL (22) 1.2.1 OpenGL介绍 (22) 1.2.2 OpenGL开发环境 (24) 1.2.3 OpenGL函数 (24) 1.2.4 回调函数 (25) 1.2.4 一个典型OpenGL例程 (26) 1.3 实验要求 (29) 1.3.1 实验内容 (29) 1.3.2 实验方法 (29) 1.3.3 实验效果 (30) 第二章直线生成算法 (30) 2.1 实验原理 (30) 2.1.1 DDA算法 (30) 2.1.2 Bresenham算法 (30) 2.2 实验内容 (30) 2.3 参考示例程序 (30) 第三章圆和椭圆生成算法 (32) 3.1 实验原理 (32) 3.2 实验内容 (32) 3.3 参考示例程序1 (32) 3.4 参考示例程序2 (33) 第四章裁剪算法 (35) 4.1 实验原理 (35) 4.2 实验内容 (35) 4.3 示例程序 (35) 4.3.1 参考例子1 (35) 4.3.2参考例子2 (38) 第五章二维变换 (40) 5.1 实验原理 (40) 5.2 实验内容 (40) 5.3 示例程序 (40) 5.3.1参考例子1 (40) 第六章三维变换 (44)

6.1 实验原理: (44) 6.2 实验内容 (45) 6.3示例程序 (45) 第七章填充算法 (47) 7.1 实验原理: (47) 7.2 实验内容 (47) 7.3示例程序 (47) 第八章曲线曲面 (50) 8.1 实验原理 (50) 8.2 实验内容 (50) 8.3示例程序 (51) 8.3.1 参考例子(1) (51) 8.3.2 参考例子(2) (52) 8.3.3 参考例子(3) (54) 8.3.4 参考例子(4) (56) 第九章真实感图形绘制 (59) 9.1 实验原理 (59) 9.2 实验内容 (59) 9.3示例程序 (59) 9.3.1参考例子(1) (59) 9.3.2参考例子(2) (61) 9.3.3参考例子(3) (63) 第十章动画 (66) 10.1 实验原理 (66) 10.2 实验内容 (66) 10.3示例程序 (66) 10.3.1 参考例子 (66) 参考文献: (72)

计算机图形学实验报告

计算机图形学 实验报告 学号: 姓名: 班级:计算机 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编程函数绘制简单的图

计算机图形学实验一

实验一二维基本图元的生成与填充 实验目的 1.了解并掌握二维基本图元的生成算法与填充算法。 2.实现直线生成的DDA算法、中点算法和Bresenham算法。 3.实现圆和椭圆生成的DDA和中点算法, 对几种算法的优缺点有感性认识。 二.实验内容和要求 1.选择自己熟悉的任何编程语言, 建议使用VC++6.0。 2.创建良好的用户界面,包括菜单,参数输入区域和图形显示区域。 3.实现生成直线的DDA算法、中点算法和Bresenham算法。 4.实现圆弧生成的中点算法。 5.实现多边形生成的常用算法, 如扫描线算法,边缘填充算法。 6.实现一般连通区域的基于扫描线的种子填充算法。 7.将生成算法以菜单或按钮形式集成到用户界面上。 8.直线与圆的坐标参数可以用鼠标或键盘输入。 6. 可以实现任何情形的直线和圆的生成。 实验报告 1.用户界面的设计思想和框图。 2.各种实现算法的算法思想。 3.算法验证例子。 4.上交源程序。 直线生成程序设计的步骤如下: 为编程实现上述算法,本程序利用最基本的绘制元素(如点、直线等),绘制图形。如图1-1所示,为程序运行主界面,通过选择菜单及下拉菜单的各功能项分别完成各种对应算法的图形绘制。 图1-1 基本图形生成的程序运行界面 2.创建工程名称为“基本图形的生成”单文档应用程序框架 (1)启动VC,选择“文件”|“新建”菜单命令,并在弹出的新建对话框中单击“工程”标签。 (2)选择MFC AppWizard(exe),在“工程名称”编辑框中输入“基本图形的生成”作为工程名称,单击“确定”按钮,出现Step 1对话框。 (3)选择“单个文档”选项,单击“下一个”按钮,出现Step 2对话框。 (4)接受默认选项,单击“下一个”按钮,在出现的Step 3~Step 5对话框中,接受默认选项,单击“下一个”按钮。 (5)在Step 6对话框中单击“完成”按钮,即完成“基本图形的生成”应用程序的所有选项,随后出现工程信息对话框(记录以上步骤各选项选择情况),如图1-2所示,单击“确定”按钮,完成应用程序框架的创建。 图1-2 信息程序基本 3.编辑菜单资源

计算机图形学实验

实验三 MFC画直线 最近自己在学习如何在VC 6.0 开发环境下的使用MFC AppWizard(exe)来绘画一条直线,虽然比较简单,通过这样的练习可以帮助你熟悉MFC的开发环境以及其中的消息传递机制,希望对于像我一样初入MFC图形绘制学习的人有帮 助 第一步:构建MFC窗体 打开Visual C++ 6.0编译器新建→工程→MFC AppWizard(exe),工程名以DrawLine为例,然后确定。为了方便,在MFC应用程序向导—步骤1当中选择“单文档”,其余所有的步骤都为默认值,直接“完成”。这样一个简单的MFC 窗体就构建好了,自己不妨Compile—Build—BuildExecute一下。 第二步:编辑菜单项 选择ResourceView视窗展开Menu文件夹,左键双击IDR_DRAWLITYPE,右边就会出现菜单图形编辑界面,为了简化,我们只在添加帮助→DrawLine功能选择项。双击空白会弹出“菜单项目属性”对话框。ID:ID_DRAW_LINE;标明: DrawLine(&D),其它的为缺省。 第三步:建立消息命令 如果此时运行该程序,你会发现帮助—DrawLine的功能选项是灰色的,原因就在于我们还没有添加该功能的消息命令相应函数。 通过“查看—Message Maps—Project:DrawLine—Class name:CDrawLineView—Object IDs:ID_DRAW_LINE—选定COMMAND—Add Function…”,其它为默认,最后确定完成。现在如果再重新运行该程序的话,会发现原来的灰色已经消除了。 第四步:添加鼠标消息响应 打开ClassView视窗,右键选定CDrawLineView,选择Add Windows Messsage Handler会弹出对话框,完成CDrawLineView类的WM_LBUTTONDOWN、 WM_MOUSEMOVE、WM_LBUTTONUP三个Windows消息事件的新建。 第五步:添加响应代码 首先,在ClassView视窗中双击CDrawLineView会定位到“DrawLineView.h : interface of the CDrawLineView class”的文件,添加CDrawLineView类的成员:protected: int m_Drag; POINT m_pPrev; POINT m_pOrigin;三个成员变量。视窗中展开CDrawLineView类,双击定位OnLBUTTONDOWN()函数。在该函数消息响应 处添加如下代码: //建立好绘图的设备环境 CClientDC dc(this); OnPrepareDC(&dc);

计算机图形学实验三

太原工业学院实验报告

GetClientRect(&rect);//获得客户区的大小 pDC->SetMapMode(MM_ANISOTROPIC);//pDC自定义坐标系 pDC->SetWindowExt(rect.Width(),rect.Height());//设置窗口范围 pDC->SetViewportExt(rect.Width(),-rect.Height());//设置视区范围,x轴水平向右,y轴垂直向上 pDC->SetViewportOrg(rect.Width()/2,rect.Height()/2);//客户区中心为原点 CDC memDC;//内存DC CBitmap NewBitmap,*pOldBitmap;//内存中承载的临时位图 memDC.CreateCompatibleDC(pDC);//创建一个与显示pDC兼容的内存memDC NewBitmap.CreateCompatibleBitmap(pDC,rect.Width(),rect.Height());//创建兼容位图 pOldBitmap=memDC.SelectObject(&NewBitmap);//将兼容位图选入memDC memDC.FillSolidRect(rect,pDC->GetBkColor());//按原来背景填充客户区,否则是黑色 memDC.SetMapMode(MM_ANISOTROPIC);//memDC自定义坐标系memDC.SetWindowExt(rect.Width(),rect.Height()); memDC.SetViewportExt(rect.Width(),-rect.Height()); memDC.SetViewportOrg(rect.Width()/2,rect.Height()/2); rect.OffsetRect(-rect.Width()/2,-rect.Height()/2); DrawWindowRect(&memDC);//绘制窗口 if(PtCount>=1) { memDC.MoveTo(Round(P[0].x),Round(P[0].y)); memDC.LineTo(Round(P[1].x),Round(P[1].y)); } pDC->BitBlt(rect.left,rect.top,rect.Width(),rect.Height(),&memDC,-rect.Width()/2,-rect.Height()/2,SRCCOPY);//将内存memDC中的位图拷贝到显示pDC中 memDC.SelectObject(pOldBitmap);//恢复位图 NewBitmap.DeleteObject();//删除位图 } (2)绘制裁剪窗口 void CTestView::DrawWindowRect(CDC* pDC)//绘制裁剪窗口 { // TODO: Add your message handler code here and/or call default pDC->SetTextColor(RGB(128,0,255)); pDC->TextOut(-10,Wyt+20,CString("窗口")); CPen NewPen3,*pOldPen3;//定义3个像素宽度的画笔 NewPen3.CreatePen(PS_SOLID,3,RGB(255,128,0)); pOldPen3=pDC->SelectObject(&NewPen3); pDC->Rectangle(Wxl,Wyt,Wxr,Wyb); pDC->SelectObject(pOldPen3); NewPen3.DeleteObject(); }

计算机图形学OpenGL版实验1-4

实验1 OpenGL初识 一、实验目的: 熟悉编程环境;了解光栅图形显示器的特点;了解计算机绘图的特点;利用VC+OpenGL作为开发平台设计程序,以能够在屏幕上生成任意一个像素点为本实验的结束。 二、实验内容: (1)了解和使用VC的开发环境,理解简单的OpenGL程序结构。 (2)掌握OpenGL提供的基本图形函数,尤其是生成点的函数。 三、该程序的作用是在一个黑色的窗口中央画一个矩形、三角形和三个点,如图所示。下面对各行语句进行说明: 首先,需要包含头文件#include ,这是GLUT的头文件。 然后看main函数。int main(int argc, char *argv[]),这个是带命令行参数的main函数。这种以glut开头的函数都是GLUT工具包所提供的函数,下面对用到的几个函数进行介绍; 1)glutInit,对GLUT进行初始化,这个函数必须在其它的GLUT使用之前调用一次。其格式比较固定,一般都是glutInit(&argc, argv)就行; 2) glutInitDisplayMode,设置显示方式,其中GLUT_RGB表示使用RGB颜色,与之对应的还有GLUT_INDEX(表示使用索引颜色)。GLUT_SINGLE表示使用单缓冲,与之对应的还有GLUT_DOUBLE(使用双缓冲)。更多信息,以后的实验教程会有讲解介绍; 3) glutInitWindowPosition,设置窗口在屏幕中的位置; 4) glutInitWindowSize,设置窗口的大小; 5) glutCreateWindow,根据前述设置的信息创建窗口。参数将被作为窗口的标题。注意:窗口被创建后,并不立即显示到屏幕上。需要调用glutMainLoop才能看到窗口; 6) glutDisplayFunc,设置一个函数,当需要进行画图时,这个函数就会被调用。(暂且这样理解); 7) glutMainLoop,进行一个消息循环。(现在只需知道这个函数可以显示窗口,并且等待窗口关闭后才会返回。) 在glutDisplayFunc函数中,我们设置了“当需要画图时,请调用myDisplay 函数”。于是myDisplay函数就用来画图。观察myDisplay中的三个函数调用,发现它们都以gl开头。这种以gl开头的函数都是OpenGL的标准函数,下面对用到的函数进行介绍: 1) glClearColor(0.0, 0.0, 0.0, 0.0) :将清空颜色设为黑色(为什么会有四个参数?); 2) glClear(GL_COLOR_BUFFER_BIT):将窗口的背景设置为当前清空颜色; 3) glRectf,画一个矩形。四个参数分别表示了位于对角线上的两个点的横、纵坐标; 4) glFlush,保证前面的OpenGL命令立即执行(而不是让它们在缓冲区中等待)。 四、实验代码: # include void mydisplay(void)

计算机图形学实验报告

计算机图形学实验报告 计算机图形学实验报告 引言 计算机图形学是研究计算机生成和处理图像的学科,它在现代科技和娱乐产业中扮演着重要的角色。本实验报告旨在总结和分享我在计算机图形学实验中的经验和收获。 一、实验背景 计算机图形学实验是计算机科学与技术专业的一门重要课程,通过实践操作和编程,学生可以深入了解图形学的基本原理和算法。本次实验主要涉及三维图形的建模、渲染和动画。 二、实验内容 1. 三维图形建模 在实验中,我们学习了三维图形的表示和建模方法。通过使用OpenGL或其他图形库,我们可以创建基本的几何体,如立方体、球体和圆柱体,并进行变换操作,如平移、旋转和缩放。这些基本操作为后续的图形处理和渲染打下了基础。 2. 光照和着色 光照和着色是图形学中重要的概念。我们学习了不同的光照模型,如环境光、漫反射和镜面反射,并了解了如何在三维场景中模拟光照效果。通过设置材质属性和光源参数,我们可以实现逼真的光照效果,使物体看起来更加真实。3. 纹理映射 纹理映射是一种将二维图像映射到三维物体表面的技术。通过将纹理图像与物

体的顶点坐标相对应,我们可以实现更加细致的渲染效果。在实验中,我们学 习了纹理坐标的计算和纹理映射的应用,使物体表面呈现出具有纹理和细节的 效果。 4. 动画和交互 动画和交互是计算机图形学的重要应用领域。在实验中,我们学习了基本的动 画原理和算法,如关键帧动画和插值技术。通过设置动画参数和交互控制,我 们可以实现物体的平滑移动和变形效果,提升用户体验。 三、实验过程 在实验过程中,我们首先熟悉了图形库的使用和基本的编程技巧。然后,我们 按照实验指导书的要求,逐步完成了三维图形建模、光照和着色、纹理映射以 及动画和交互等任务。在实验过程中,我们遇到了许多挑战和问题,但通过不 断的尝试和调试,最终成功实现了预期的效果。 四、实验结果 通过实验,我们成功实现了三维图形的建模、渲染和动画效果。我们可以通过 键盘和鼠标控制物体的移动和变形,同时观察到真实的光照效果和纹理映射效果。实验结果符合预期,并且在实验报告中附上了实验截图和代码片段供参考。 五、实验总结 通过本次计算机图形学实验,我深入了解了三维图形的建模和渲染原理,掌握 了OpenGL等图形库的使用方法。同时,我也学会了如何应用光照、纹理映射 和动画等技术,使图形更加真实和生动。通过实验,我不仅提升了编程能力, 还培养了团队合作和问题解决的能力。 六、展望未来

计算机图形学OpenGL版实验5-8

实验5 OpenGL模型视图变换 一、实验目的: 理解掌握OpenGL程序的模型视图变换。 二、实验内容: (1)阅读实验原理,运行示范实验代码,理解掌握OpenGL程序的模型视图变换;(2)根据示范代码,尝试完成实验作业; 三、实验原理: 在代码中,视图变换必须出现在模型变换之前,但可以在绘图之前的任何时候执行投影变换和视口变换。 1.display()程序中绘图函数潜在的重复性强调了:在指定的视图变换之前,应该使用glLoadIdentity()函数把当前矩阵设置为单位矩阵。 2.在载入单位矩阵之后,使用gluLookAt()函数指定视图变换。如果程序没有调用gluLookAt(),那么照相机会设定为一个默认的位置和方向。在默认的情况下,照相机位于原点,指向Z轴负方向,朝上向量为(0,1,0)。 3.一般而言,display()函数包括:视图变换 + 模型变换 + 绘制图形的函数(如glutWireCube())。display()会在窗口被移动或者原来先遮住这个窗口的东西被一开时,被重复调用,并经过适当变换,保证绘制的图形是按照希望的方式进行绘制。 4.在调用glFrustum()设置投影变换之前,在reshape()函数中有一些准备工作:视口变换 + 投影变换 + 模型视图变换。由于投影变换,视口变换共同决定了场景是如何映射到计算机的屏幕上的,而且它们都与屏幕的宽度,高度密切相关,因此应该放在reshape()中。reshape()会在窗口初次创建,移动或改变时被调用。 OpenGL中矩阵坐标之间的关系:物理坐标*模型视图矩阵*投影矩阵*透视除法*规范化设备坐标——〉窗口坐标 (1)视图变换函数gluLookAt(0.0,0.0,5.0,0.0,0.0,0.0,0.0,1.0,0.0,)设置照相机的位置。把照相机放在(0,0,5),镜头瞄准(0,0,0),朝上向量定为(0,1,0)朝上向量为照相机指定了一个唯一的方向。如果没有调用gluLookAt,照相机就设定一个默认的位置和方向,在默认情况下,照相机位于原点,指向Z轴的负方向,朝上向量为(0,1,0)glLoadIdentity()函数把当前矩阵设置为单位矩阵。 (2)使用模型变换的目的是设置模型的位置和方向 (3)投影变换,指定投影变换类似于为照相机选择镜头,可以认为这种变换的目的是确定视野,并因此确定哪些物体位于视野之内以及他们能够被看到的程度。除了考虑视野之外,投影变换确定物体如何投影到屏幕上,OpenGL提供了两种基本类型的投影,1、透视投影:远大近小;2、正投影:不影响相对大小,一般用于建筑和CAD应用程序中 (4)视口变换视口变换指定一个图象在屏幕上所占的区域 (5)绘制场景 四、实验代码: #include #include

计算机图形学-实验五直线和多边形的裁剪

大学实验报告 学院:计算机科学与信息学院专业:软件工程班级:102班 ** 实验组实验时间指导教师成绩实验工程名称实验五直线和多边形的裁剪 实 验 目 的 掌握直线段的裁剪算法以及多边形的裁剪算法 实 验要求熟练掌握直线段的裁剪算法以及多边形的裁剪算法的根本原理,并编写测试代码进展实验。 实验原理 Cohen-Sutherland直线剪裁算法 以区域编码为根底,将窗口及其周围的,8个方向以4 bit的二进制数进展编码。 右图所示的编码方法将窗口及其邻域 分为5个区域: ⑴域:区域(0000)。 ⑵上域:区域(1001, 1000, 1010)。 ⑶下域:区域(0101, 0100, 0110)。 ⑷左域:区域(1001, 0001, 0101)。 ⑸右域:区域(1010, 0010, 0110)。 当线段的两个端点的编码的逻辑"与〞非零时,线段为显然不可见的,对*线段的两个端点的区号进展位与运算,可知这两个端点是否同在视区的上、下、左、右; Cohen-Sutherland直线剪裁算法的算法思想是: 对于每条线段P1P2分为三种情况处理。〔1〕假设P1P2完全在窗口,则显示该线段P1P2简称"取〞之。〔2〕假设P1P2明显在窗口外,则丢弃该线段,简称"弃〞之。〔3〕假设线段既不满足"取〞的条件,也不满足"弃〞的条件,则在交点处把线段分为两段。其

while (code1 != 0 || code2 != 0) { if ((code1 & code2) != 0) {// 两端点的编码相与不为0,表示直线在窗口外return; } if (code1 != 0) { code = code1; } else { code = code2; } if ((LEFT & code) != 0) {// 直线的端点与矩形窗口的左边编码相与!=0 * = *L; y = y1 + (y2 - y1) * (*L - *1) / (*2 - *1);// 求直线与矩形窗口的左边界的交点 } elseif ((RIGHT & code) != 0) {// 直线的端点与矩形窗口的右边编码相与!=0 * = *R; y = y1 + (y2 - y1) * (*R - *1) / (*2 - *1);// 求直线与矩形窗口的右边界的交点 } elseif ((BOTTOM & code) != 0) {// 直线的端点与矩形窗口的下边编码相与!=0 y = YB; * = *1 + (*2 - *1) * (YB - y1) / (y2 - y1);// 求直线与矩形窗口的下边界的交点 } elseif ((TOP & code) != 0) {// 直线的端点与矩形窗口的上边编码相与!=0 y = YT; * = *1 + (*2 - *1) * (YT - y1) / (y2 - y1);// 直线的端点与矩形窗口的上

《计算机图形学》实验指导书

湖北汽车工业学院实验报告 班级学号姓名 课程名称完成日期 实验一熟悉Visual C++绘图应用程序的开发过程 一、实验目的 1、熟悉VC6.0开发环境; 2、掌握MFC编程; 3、掌握CDC图形程序库; 4、掌握VC6.0下的简单图形程序的开发过程。 二、实验性质 验证性 三、实验要求 1、认真阅读本次实验的目的,了解本次实验要求掌握的内容; 2、能够根据实验指导书的要求,完成相关的内容; 3、务必掌握绘图程序的开发流程,为今后复杂的图形程序开发做好准备。 四、实验内容 (一)生成绘图应用程序的框架 开发绘图应用程序的第一步是使用AppWizard(程序生成向导)来建立程序的基本框架。AppWizard为框架的建立提供了一系列对话框及多种选项,用户可以根据不同的选项生成自己所需要的应用程序框架。具体步骤如下: 1、从“文件”菜单选择“新建”菜单项,在“新建”对话框中选择“工程”选项卡,从项目类型中选择MFC AppWizard(.exe)。在“位置”文本框中,可直接输入目录名称,或者单击“…”按钮选择已有的目录。在“工程名称”文本框中输入项目的名称,如Draw,其他采用默认值,这时确定按钮变亮,如下图所示:

2、单击确定按钮,弹出“MFC应用程序向导步骤1”对话框,如图所示,选择单文档单选按钮和“中文[中国]”选项,表示要生成以中文为用户界面的单文档(SDI绘图程序)。 3、点击下一步,在随后出现的几个对话框中,都点击下一步,表示采用各项的默认设置,直到出现“MFC应用程序向导步骤6”对话框,如图所示。

4、“MFC应用程序向导步骤6”对话框中默认设置确定了类得名称及其所在文件的名称。用户可以改CdrawApp、CmainFrame和CdrawDoc的文件名称,但不可以改变它们的基类。 单击完成按钮,应用程序向导显示将要创建的文件清单,再单击确定,MFC应用程序向导就自动生成绘图程序的各项源文件了。 MFC应用程序向导设置完后,点击组建按钮,然后再点击执行按钮,就会出现MFC 应用程序向导生成的完整应用程序的基本框架。

计算机图形学实验报告

计算机图形学实验报告 引言 计算机图形学是计算机科学中一个重要的研究领域,它涉及了计算机图像的生成、处理和显示等方面的技术。本次实验旨在通过实际操作学习计算机图形学的相关知识,并利用图形学算法实现一些有趣的效果。 实验目的 1. 了解计算机图形学的基本概念和发展历程; 2. 掌握图形学中的基本几何变换,如平移、旋转和缩放等; 3. 实现一些常见的图形学算法,如光照模型、三角形剪裁和绘制等。 实验准备 在开始实验之前,我们需要准备一些实验所需的工具和环境。首先,确保计算机上安装了图形学相关的软件,如OpenGL或

DirectX等。其次,为了编写和运行图形学程序,我们需要掌握基 本的编程技巧,如C++或Python语言,并了解相关的图形库和API。 实验过程 1. 实现平移、旋转和缩放 首先,我们需要掌握图形学中的基本几何变换,如平移、旋转 和缩放。通过矩阵运算,我们可以很方便地实现这些变换。例如,对于一个二维点P(x, y),我们可以通过以下公式实现平移: P' = T * P 其中,P'是平移后的点,T是平移矩阵。类似地,我们可以用 旋转矩阵和缩放矩阵来实现旋转和缩放效果。 2. 实现光照模型

光照模型是指在计算机图形学中模拟现实光照效果的一种方法。它可以提供更真实的视觉效果,让计算机生成的图像更加逼真。 其中,常用的光照模型有环境光照、漫反射光照和镜面光照等。 通过计算每个像素的光照强度,我们可以实现阴影效果和光源反 射等功能。 3. 实现三角形剪裁 三角形剪裁是计算机图形学中一种常用的几何算法,用于确定 哪些像素需要绘制,哪些像素需要剔除。通过对三角形的边界和 视口进行比较,我们可以快速计算出剪裁后的三角形顶点,以提 高图形渲染的效率。 4. 实现图形绘制 图形绘制是计算机图形学中的核心内容,它包括了点、线和面 的绘制等。通过设定顶点坐标和属性(如颜色、纹理等),我们 可以使用算法绘制出各种形状的图像。其中,常用的绘制算法有Bresenham算法和扫描线算法等。

计算机图形学实验(全)

实验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 ; gdriver = DETECT; initgraph(&gdriver , &gmode ,"C:\\TC20\\BGI"); DDALine(0,0,35,26,4); getch ( ); closegraph ( ); } Bresenham: #include #include void BresenhamLine(int x0,int y0,int x1,int y1,int color) { int x,y,dx,dy,e; dx=x1-x0; dy=y1-y0; e=-dx;x=x0;y=y0; while(x<=x1){ putpixel(x,y,color); x++; e=e+2*dy; if(e>0){ y++; e=e-2*dx; } } } main(){ int gdriver ,gmode ; gdriver = DETECT; initgraph(&gdriver , &gmode ,"c:\\TC20\\BGI"); BresenhamLine(0, 0 , 120, 200,5 ); getch ( ); closegraph ( ); }

计算机图形学基础实验指导书

《计算机图形学基础》实验指导书 课程名称:计算机图形学基础 英文名称:Computer Graphics 课程性质:必修 课程编号: 适应专业:计算机科学与技术;软件工程 学时学分:总学时48,实验学时102,总学分2 编写人:王创存 一、实验课程任务与要求 1. 目的与任务: 计算机图形学实验教学是为了将学生的计算机操作能力、分析能力、工程设计能力与应用实践结合起来,引导学生由浅入深地掌握计算机图形学理论与算法,掌握交互构图能力,具备工程应用的图形学基础。本实验教学主要内容是要求学生用Visual Basic编程实现各种图形的绘制,强化学生的程序设计能力和程序调试能力,使学生巩固所学各种图形的生成算法的理论知识。实践教学共包括十项内容。 2. 实验基本要求:(以软件设计为主要表现形式) 上机前应准备好实验的程序设计算法描述与关键分析内容; 准备好程序测试数据和设备操作步骤,上机调试、运行; 完成每个实验后进行数据与程序对比分析,给出运行结果。 二、实验内容与学时安排 实验一、图形输入/输出设备的操作使用及简单图形的输出(2学时) 要求:(1)掌握图形设备的操作过程;测试图形设备的分辨率、性能; (2)图形软件包与外部设备的连接参数配置; (3)利用图形软件包绘制简单图形并在设备上输出; (4)设计菜单,实现人机交互方式控制图形设备进行简单操作 实验二、编程环境及图形绘制基础练习(2学时) 题目:绘制分形树 基本要求: )数据输入项为:树干的起点坐标,树干长度,树枝倾斜角度,树枝层数,最短树枝;)结果直接输出在窗体中。 附加要求:(1)通过用户输入可改变线型(实线、虚线与点划线)。 (2)通过用户输入可改变线宽。 实验三、直线的绘制(2学时) 题目:用逐点比较法或中点Bresenham法实现直线的绘制 基本要求: )数据输入项为:直线的起点与终点坐标; )直线与圆输出在PictureBox控件中; )保存图形绘制结果,将该实验加入到菜单中去。 实验四、圆的绘制(2学时) 题目:用逐点比较法或中点Bresenham法实现圆的绘制

计算机图形学实验一:画直线

贵州大学实验报告 学院:计算机科学与技术专业:计算机科学与技术班级:计科131

如果 d<0,则M在理想直线下方,选右上方P1点; 如果 d=0,则M在理想直线上,选P1/ P2点。 由于d是xi和yi的线性函数,可采用增量计算提高运算效率。 1.如由pi点确定在是正右方P2点(d>0).,则新的中点M仅在x方向加1,新的d值为: d new=F(xi+2,yi+0.5)=a(xi+2)+b(yi+0.5)+c 而 d old=F(xi+1,yi+0.5)=a(xi+1)+b(yi+0.5)+c d new=d old+a= d old-dy 2.如由pi点确定是右上方P1点(d<0),则新的中点M在x和y方向都增加1,新的d值为 d new=F(xi+2,yi+1.5)=a(xi+2)+b(yi+1.5)+c 而 d old=F(xi+1,yi+0.5)=a(xi+1)+b(yi+0.5)+c d new=d old+a+b= d old-dy+dx 在每一步中,根据前一次第二迭中计算出的d值的符号,在正右方和右上方的两个点中进行选择。d的初始值: d0=F(x0+1,y0+0.5)=F(x0,y0)+a+b/2=a+b/2=-dy+dx/2 F(x0,y0)=0,(x0,y0)在直线上。 为了消除d的分数,重新定义 F(x,y)=2(ax+by+c) 则每一步需要计算的d new 是简单的整数加法 dy=y1-y0,dx=x1-x0 d0=-2dy+dx d new=d old-2*dy,当 d old>=0 d new=d old-2(dy-dx),当d old<0 Bresenham画线算法 算法原理: 与DDA算法 相似,Bresenham 画线算法也要在 每列象素中找到 与理想直线最逼 近的象素点。 根据直线的 斜率来确定变量 在x或y方向递 增一个单位。另 一个方向y或x

计算机图形学--实验四-几何变换

贵州大学实验报告 学院:计算机科学与信息学院专业:软件工程班级: 102班姓名学号实验组实验时间指导教师成绩实验项目名称实验四几何变换 实 验目的掌握二维图形的几何变换的基本原理。二维图形的基本几何变换:位置改变(平移、旋转)和变形(缩放、错切,反射、投影等)以及复合变换。 了解三维图形的错切变换 实验要求根据本实验的特点、要求和具体条件,掌握二维图形的几何变换的基本原理,了解三维图形的错切变换,并成功编写测试代码进行实验。 1.设有一三角形ABC,其中三个顶点为A(5,10),B(1,2),C(8,5),如三角形的顶点A不变,将AB和AC边缩小一倍后,求缩小后的三角形对于直线-2x+4y+3=0的对称变换后的结果图。 2.将一四边形以原点为中心,以15°为间隔旋转。 3.在三维坐标中,对长度为1的标准立方体做错切变换,错切单位为2; 实验原理一、实验原理:标准齐次坐标(x,y,1) 二维变换的矩阵表示 平移变换 旋转变换 [][][]),( 1 1 1 1 1 1 y x y x t t T y x t t y x y x⋅ = ⎥ ⎥ ⎥ ⎦ ⎤ ⎢ ⎢ ⎢ ⎣ ⎡ = ' '记为 [][][] cos sin0 1x y1sin cos01() 001 x y x y R θθ θθθ ⎡⎤ ⎢⎥ ''=-= ⎢⎥ ⎢⎥ ⎣⎦ 记为

[][][]00110 01(,) 1x y x y s x y x y s x y S s s ∆⎡⎤⎢⎥''==⎢⎥⎢⎥⎣⎦ 放缩变换 平移变换只改变图形的位置,不改变图形的大小。 旋转变换不改变图形的形状 放缩变换引起图形形状的变化。 复合变换结果与变换的顺序有关(矩阵乘法不可交换) 二、Java3D 在java3D 中坐标轴的显示如下所示: Java3D 的编程思想显示如下: ()⎥⎥⎥⎦ ⎤ ⎢⎢ ⎢⎣ ⎡-=10 00cos sin 0sin cos θθθθ θR ⎥⎥⎥⎦ ⎤⎢⎢⎢⎣⎡=10 00 00),(y x y x s s s s S

相关文档
最新文档