计算机图形学.docx
- 文档编号:8523316
- 上传时间:2023-01-31
- 格式:DOCX
- 页数:44
- 大小:552.97KB
计算机图形学.docx
《计算机图形学.docx》由会员分享,可在线阅读,更多相关《计算机图形学.docx(44页珍藏版)》请在冰豆网上搜索。
计算机图形学
实验1:
直线与圆的生成算法
实验要求:
任选课本的直线扫描转换算法之一绘制一条斜率在0到1之间的直线,自己确定直线起点和终点,绘制点使用OpenGL里的glVertex()函数。
任选课本的圆扫描转换算法之一绘制一个圆,自己确定圆的圆心和半径,绘制点使用OpenGL里的glVertex()函数。
程序源代码
#defineGLUT_DISABLE_ATEXIT_HACK
#include
#include
#include"stdio.h"
#include
intm_DrawMode=4;//绘制模式1DDA算法画直线
//2中点Bresenham算法画直线
//3改进Bresenham算法画直线
//4八分法绘制圆
//5四分法绘制椭圆
//绘制坐标线
voidDrawCordinateLine(void)
{
inti=0;
//坐标线为黑色
glColor3f(0.0f,0.0f,0.0f);
glBegin(GL_LINES);
for(i=5;i<=250;i=i+5)
{
glVertex2f((float)(i),0.0f);
glVertex2f((float)(i),250.0f);
glVertex2f(0.0f,(float)(i));
glVertex2f(250.0f,(float)(i));
}
glEnd();
}
//绘制一个点,这里用一个正方形表示一个点。
voidputpixel(GLsizeix,GLsizeiy)
{
glRectf(5*x,5*y,5*x+5,5*y+5);
}
/////////////////////////////////////////////////////////////////////////
//DDA画线算法1//
//参数说明:
x0,y0起点坐标//
//x1,y1终点坐标//
//num扫描转换时从起点开始输出的点的数目,用于动画//
////////////////////////////////////////////////////////////////////////
voidDDACreateLine(GLsizeix0,GLsizeiy0,GLsizeix1,GLsizeiy1/*,GLsizeinum*/)
{
//设置颜色
glColor3f(1.0f,0.0f,0.0f);
//画线算法的实现
GLsizeidx,dy,epsl,k;
GLfloatx,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/epsl;
yIncre=(float)dy/epsl;
for(k=0;k<=epsl;k++){
putpixel((int)(x+0.5),(int)(y+0.5));
x+=xIncre;
y+=yIncre;
}
}
///////////////////////////////////////////////////////////////////////
//中点Bresenham算法画直线(0<=k<=1)2//
//参数说明:
x0,y0起点坐标//
//x1,y1终点坐标//
//num扫描转换时从起点开始输出的点的数目,用于动画//
///////////////////////////////////////////////////////////////////////
voidBresenhamLine(GLsizeix0,GLsizeiy0,GLsizeix1,GLsizeiy1/*,GLsizeinum*/)
{
glColor3f(1.0f,0.0f,0.0f);
GLsizeidx,dy,d,UpIncre,DownIncre,x,y;
if(x0>x1){
x=x1;x1=x0;x0=x;
y=y1;y1=y0;y0=y;
}
x=x0;y=y0;
dx=x1-x0;
dy=y1-y0;
d=dx-2*dy;
UpIncre=2*dx-2*dy;DownIncre=-2*dy;
while(x<=x1)
{
putpixel(x,y);
x++;
if(d<0){
y++;
d+=UpIncre;
}
elsed+=DownIncre;
}
}
/////////////////////////////////////////////////////////////////////////
//改进的Bresenham算法画直线(0<=k<=1)3//
//参数说明:
x0,y0起点坐标//
//x1,y1终点坐标//
//num扫描转换时从起点开始输出的点的数目,用于动画//
/////////////////////////////////////////////////////////////////////////
voidBresenham2Line(GLsizeix0,GLsizeiy0,GLsizeix1,GLsizeiy1/*,GLsizeinum*/)
{
glColor3f(1.0f,0.0f,0.0f);
GLsizeix,y,dx,dy,e;
dx=x1-x0;
dy=y1-y0;
e=-dx;
x=x0;
y=y0;
while(x<=x1){
putpixel(x,y);
x++;
e=e+2*dy;
if(e>0){
y++;
e=e-2*dx;
}
}
}
///////////////////////////////////////////////////////////////////////
//八分法画圆4//
//参数说明:
x,y圆上一点的坐标//
////
//num扫描转换时从起点开始输出的点的数目,用于动画//
///////////////////////////////////////////////////////////////////////
voidCirclePoint(GLsizeix,GLsizeiy)
{
glColor3f(1.0f,0.0f,0.0f);
putpixel(x+10,y+10);
putpixel(x+10,-y+10);
putpixel(y+10,-x+10);
putpixel(-y+10,-x+10);
putpixel(-x+10,-y+10);
putpixel(-x+10,y+10);
putpixel(-y+10,x+10);
putpixel(y+10,x+10);
}
///////////////////////////////////////////////////////////////////////
//Bresenham算法画圆5//
//参数说明:
x,y圆心坐标//
//R圆半径//
//num扫描转换时从起点开始输出的点的数目,用于动画//
///////////////////////////////////////////////////////////////////////
voidBresenhamCircle(GLsizeix,GLsizeiy,GLsizeiR/*,GLsizeinum*/)
{
glColor3f(1.0f,0.0f,0.0f);
GLsizeid;
x=0;y=R;d=1-R;
while(x<=y){
CirclePoint(x,y);
if(d<0)d+=2*x+3;
else{
d+=2*(x-y)+5;
y--;
}
x++;
}
}
//初始化窗口
voidInitial(void)
{
//设置窗口颜色为蓝色
glClearColor(1.0f,1.0f,1.0f,1.0f);
}
//窗口大小改变时调用的登记函数
voidChangeSize(GLsizeiw,GLsizeih)
{
if(h==0)h=1;
//设置视区尺寸
glViewport(0,0,w,h);
//重置坐标系统
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//建立修剪空间的范围
if(w<=h)
glOrtho(0.0f,250.0f,0.0f,250.0f*h/w,1.0,-1.0);
else
glOrtho(0.0f,250.0f*w/h,0.0f,250.0f,1.0,-1.0);
}
//在窗口中绘制图形
voidReDraw(void)
{
//用当前背景色填充窗口
glClear(GL_COLOR_BUFFER_BIT);
//画出坐标线
DrawCordinateLine();
switch(m_DrawMode)
{
case1:
DDACreateLine(1,2,20,48);
break;
case2:
BresenhamLine(0,2,20,15);
break;
case3:
Bresenham2Line(1,1,18,16);
break;
case4:
BresenhamCircle(10,10,10);//中点Bresenham画圆法
break;
default:
break;
}
glFlush();
}
//设置键盘回调函数
voidKeyboard(unsignedcharkey,intx,inty)
{
if(key=='1')m_DrawMode=1;
if(key=='2')m_DrawMode=2;
if(key=='3')m_DrawMode=3;
if(key=='4')m_DrawMode=4;
glutPostRedisplay();
}
intmain(intargc,char*argv[])
{
glutInit(&argc,argv);
//初始化GLUT库OpenGL窗口的显示模式
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowSize(600,600);
glutInitWindowPosition(100,100);
glutCreateWindow("基本图元绘制程序");
glutDisplayFunc(ReDraw);
glutReshapeFunc(ChangeSize);
glutKeyboardFunc(Keyboard);//键盘响应回调函数
//窗口初始化
Initial();
glutMainLoop();//启动主GLUT事件处理循环
return0;
}
运行结果:
实验2:
直线的2D变换
要求:
窗口的中心为坐标原点,绘制过坐标原点的一条水平线和垂直线,把窗口分为4个象限。
在第1象限里,选直线扫描转换算法之一绘制一条斜率在0到1之间的直线,然后利用直线两个端点的对称变换和直线扫描转换算法之一绘制其它3个象限的3条对称直线。
程序源代码:
#defineGLUT_DISABLE_ATEXIT_HACK
#include
#include
#include"stdio.h"
#include
classMatrix
{
public:
GLfloatx0,x1,x2;
GLfloaty0,y1,y2;
GLfloatw0,w1,w2;
};
voidPingyi(Matrix*Mat,GLfloatx,GLfloaty)
{
Mat->x0=Mat->x0+Mat->x2*x;
Mat->x1=Mat->x1+Mat->x2*y;
Mat->x2=Mat->x2;
Mat->y0=Mat->y0+Mat->y2*x;
Mat->y1=Mat->y1+Mat->y2*y;
Mat->y2=Mat->y2;
Mat->w0=Mat->w0+Mat->w2*x;
Mat->w1=Mat->w1+Mat->w2*y;
Mat->w2=Mat->w2;
}
voidDuichenX(Matrix*Mat)
{
Mat->x1=-Mat->x1;
Mat->y1=-Mat->y1;
Mat->w1=-Mat->w1;
}
voidDuichenY(Matrix*Mat)
{
Mat->x0=-Mat->x0;
Mat->y0=-Mat->y0;
Mat->w0=-Mat->w0;
}
voidDuichenYuandian(Matrix*Mat)
{
Mat->x0=-Mat->x0;
Mat->y0=-Mat->y0;
Mat->w0=-Mat->w0;
Mat->x1=-Mat->x1;
Mat->y1=-Mat->y1;
Mat->w1=-Mat->w1;
}
//绘制坐标线
voidDrawCordinateLine(void)
{
inti=0;
//坐标线为黑色
glColor3f(0.0f,0.0f,0.0f);
glBegin(GL_LINES);
for(i=5;i<=250;i=i+5)
{
glVertex2f((float)(i),0.0f);
glVertex2f((float)(i),250.0f);
glVertex2f(0.0f,(float)(i));
glVertex2f(250.0f,(float)(i));
}
glEnd();
glColor3f(1.0f,0.0f,0.0f);
glBegin(GL_LINES);
glVertex2f(125.0f,0.0f);
glVertex2f(125.0f,250.0f);
glVertex2f(0.0f,125.0f);
glVertex2f(250.0f,125.0f);
glEnd();
}
//绘制一个点,这里用一个正方形表示一个点。
voidputpixel(GLsizeix,GLsizeiy)
{
glRectf(5*x,5*y,5*x+5,5*y+5);
}
/////////////////////////////////////////////////////////////////////////
//DDA画线算法1//
//参数说明:
x0,y0起点坐标//
//x1,y1终点坐标//
////////////////////////////////////////////////////////////////////////
voidDDACreateLine(Matrix*Mat,GLsizeix0,GLsizeiy0,GLsizeix1,GLsizeiy1)
{
//设置颜色
glColor3f(1.0f,0.0f,0.0f);
x0=x0*Mat->x0+y0*Mat->y0+1*Mat->w0;
y0=x0*Mat->x1+y0*Mat->y1+1*Mat->w1;
x1=x1*Mat->x0+y1*Mat->y0+1*Mat->w0;
y1=x1*Mat->x1+y1*Mat->y1+1*Mat->w1;
//画线算法的实现
GLsizeidx,dy,epsl,k;
GLfloatx,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/epsl;
yIncre=(float)dy/epsl;
for(k=0;k<=epsl;k++){
putpixel((int)(x+0.5),(int)(y+0.5));
x+=xIncre;
y+=yIncre;
}
}
//初始化窗口
voidInitial(void)
{
//设置窗口颜色为蓝色
glClearColor(1.0f,1.0f,1.0f,1.0f);
}
//窗口大小改变时调用的登记函数
voidChangeSize(GLsizeiw,GLsizeih)
{
if(h==0)h=1;
//设置视区尺寸
glViewport(0,0,w,h);
//重置坐标系统
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//建立修剪空间的范围
if(w<=h)
glOrtho(0.0f,250.0f,0.0f,250.0f*h/w,1.0,-1.0);
else
glOrtho(0.0f,250.0f*w/h,0.0f,250.0f,1.0,-1.0);
}
//在窗口中绘制图形
voidReDraw(void)
{
//用当前背景色填充窗口
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
//画出坐标线
DrawCordinateLine();
glPushMatrix();
MatrixMat1={1,0,0,0,1,0,0,0,1};
DuichenX(&Mat1);
Pingyi(&Mat1,25,25);
DDACreateLine(&Mat1,2,3,19,23);
glPopMatrix();
glPushMatrix();
MatrixMat2={1,0,0,0,1,0,0,0,1};
Pingyi(&Mat2,25,25);
DDACreateLine(&Mat2,2,3,19,23);
glPopMatrix();
glPushMatrix();
MatrixMat3={1,0,0,0,1,0,0,0,1};
DuichenY(&Mat3);
Pingyi(&Mat3,25,25);
DDACreateLine(&Mat3,2,3,19,23);
glPopMatrix();
glPushMatrix();
MatrixMat4={1,0,0,0,1,0,0,0,1};
DuichenYuandian(&Mat4);
Pingyi(&Mat4,25,25);
DDACreateLine(&Mat4,2,3,19,23);
glPopMatrix();
glFlush();
}
intmain(intargc,char*argv[])
{
glutInit(&argc,argv);
//初始化GLUT库OpenGL窗口的显示模式
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowSize(600,600);
glutInitWindowPosition(100,100);
glutCreateWindow("基本图元绘制程序");
glutDisplayFunc(ReDraw);
glutReshapeFunc(ChangeSize);
//窗口初始化
Initial();
glutMainLoop();//启动主GLUT事件处理循环
return0;
}
实验结果:
实验3:
三角形的绘制与2D变换
要求:
窗口的中心为坐标原点,绘制过坐标原点的一条水平线和垂直线,把窗口分为4个象限。
在第1象限里,利用OpenGL画直线方法和画三角形方法
glBegin(GL_LINES)
glVertex()
glVertex()…
glEnd()
glBegin(GL_TRIANGLES)
glVertex()
glVertex()…
glVertex()…
glEnd()
绘制一个直角三角形,然后利用顶点的对称变换和OpenGL三角形绘制方法其它3个象限的3个对称三角形。
程序源代码:
#defineGLUT_DISABLE_ATEXIT_HACK
#include
#include
#include"stdio.h"
#include
classMatrix
{
public:
GLfloatx0,x1,x2;
GLfloaty0,y1,y2;
GLfloatw0,w1,w2;
};
voidPingyi(Matrix*Mat,GLfloatx,GLfloaty)
{
Mat->x0=Mat->x0+Mat->x2*x;
Mat->x1=Mat->x1+Mat->x2*y;
Mat->x2=Mat->x2;
Mat->y0=Mat->y0+Mat->y2*x;
Mat->y1=Mat->y1+Mat->y2*y;
Mat->y2=Mat->y2;
Mat->w0=Mat->w0+Mat->w2*x;
Mat->w1=Mat->w1+Mat
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 计算机 图形学
![提示](https://static.bdocx.com/images/bang_tan.gif)