计算机图形学第二次上机实验 课程实验报告
目录
一、实验目的
- 掌握配置glut库的步骤
- 测试运行示例代码
- 掌握并编写中点线算法和中点圆算法
二、实验环境
1.codeblocks-17.12
2.Windows10 SDK 10.0.17134.0
三、实验内容
- 绘制曲线
1. 证明如下的两条三次曲线段具有C1连续性,但没有G1连续性,并画出两条曲线段。
证明:
P11=[2t-2,3t2-4t=1],P21=[2t,3t2]
所以 P11|t=1=[0,0] , P21|t=0=[0,0]
所以P1,P2有C1连续,
因为[0,0]的方向不定,所以没有G1连续
实验结果
2. 假定一条三次Hermite曲线的两个端点P1=<0,1>,P4=<3,0>,端点处切向量R1=<0,1>,R4=<-3,0>,请写出Hermite多项式形式,并绘出最后曲线,改变切向量,观察曲线形状变化。
Hermite多项式形式为:
实验结果为
3. 已知4点P1(0,0,0)、P2(1,1,1)、 P3(2,-1,-1)、P4(3,0,0),用其作为特征多边形分别构造一条Bezier曲线、一条B样条曲线,并绘制出曲线。
Bezier曲线多项式:
结果为
B样条曲线多项式:
结果为
- 其它
- 编写程序,使一物体沿着一条直线匀速移动。
为实现显示中的视觉效果
需要添加gluPerspective和gluLookAt函数
具体代码如下:
gluPerspective(60,ratio,start,depth);//透视矩阵压入堆栈,进行透视变换,四个参数依次为,眼睛睁开角度、宽高比、前透视面距离、后透视面距离(填正值,但其实该透视体处于z负轴)
glEnable(GL_DEPTH_TEST);//开启更新深度缓冲区功能
gluLookAt(20,10,40,0,0,0,0,1,0);//相机从(0,10,40)看向(0,0,0,),(0,1,0)为正方向
glMatrixMode(GL_MODELVIEW);//投影变换完了进入绘图模式
- 编写程序,使一物体围绕屏幕上一点匀速旋转。
思想与第一问类似,结果如下
四,源代码
1.
#include "windows.h"
#include<glut.h>
typedef struct{
float x,y,z;
}Point;
//Point ctrlpoints[4]= {{-4.0,-4.0,0.0},{-2.0,4.0,0.0},{2.0,-4.0,0.0},{4.0,4.0,0.0}};
void init()
{
glClearColor(1.0,1.0,1.0,1.0);
}
void DrawCurve(int n)
{
Point p;
double t,deltat,t2,t3,et,et2,et3;
int i;
deltat = 1.0/(n-1);
glBegin(GL_LINE_STRIP);
for(i=0;i<100;i++)
{
t = i*deltat;
et = 1-t;
t2 = t*t;
et2 = et*et;
t3 = t*t2;
et3 = et*et2;
p.x=et2;
p.y=t3-2*t2+t;
p.z=0;
glVertex3f(p.x,p.y,p.z);
}
glEnd();
//glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0,1,0);
glBegin(GL_LINE_STRIP);
for(i=0;i<100;i++)
{
t=i*deltat;
t2=t*t;
t3=t2*t;
glVertex3f(t2,t3,0);
}
glEnd();
}
void RenderScence()
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0,0.0,0.0);
DrawCurve(100);
glFlush();
}
void ChangeSize(GLsizei w,GLsizei h)
{
GLfloat aspectRatio;
if(h==0)
h = 1;
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
aspectRatio = (GLfloat)w/(GLfloat)h;
float s=2;
if(w<=h)
glOrtho(-s,s,-s/aspectRatio,s/aspectRatio,1.0,-1.0);
else
glOrtho(-s*aspectRatio,s*aspectRatio,-s,s,1.0,-1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
int main()
{
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutCreateWindow("DrawBezier");
init();
glutDisplayFunc(RenderScence);
glutReshapeFunc(ChangeSize);
glutMainLoop();
return 0;
}
2.
#include "windows.h"
#include<glut.h>
#include<string>
typedef struct{
float x,y;
}Point;
void init()
{
glClearColor(1.0,1.0,1.0,1.0);
}
void displayc(double x,double y,char str[])//显示字符函数
{
glColor3f(0, 0, 0);
//glClear(GL_COLOR_BUFFER_BIT);
glRasterPos2d(x,y);
for(int i=0;i<sizeof(str);i++)
{
glutBitmapCharacter(GLUT_BITMAP_8_BY_13,str[i]);
}
glFlush();
}
void DrawHermite2D(int n,Point P[],Point R[])
{
Point p;
double t,deltat,t2,t3;
int i;
deltat = 1.0/(n-1);
glBegin(GL_LINE_STRIP);
for(i=0;i<100;i++)
{
t = i*deltat;
t2 = t*t;
t3 = t*t2;
double BH1=2*t3-3*t2+1;
double BH2=-2*t3+3*t2;
double BH3=t3-2*t2+t;
double BH4=t3-t2;
p.x=P[0].x*BH1+P[1].x*BH2+R[0].x*BH3+R[1].x*BH4;
p.y=P[0].y*BH1+P[1].y*BH2+R[0].y*BH3+R[1].y*BH4;
glVertex2f(p.x,p.y);
}
glEnd();
//glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0,1,0);
glPointSize(3);
glBegin(GL_POINTS);
for(i=0;i<2;i++)
{
glVertex2d(P[i].x,P[i].y);
glVertex2d(P[i].x+R[i].x,P[i].y+R[i].y);
}
glEnd();
displayc(P[0].x,P[0].y+0.2,"P1\0");
displayc(P[1].x,P[1].y-0.5,"P4\0");
displayc(P[0].x+R[0].x,P[0].y+R[0].y+0.2,"R1\0");
displayc(P[1].x+R[1].x,P[1].y+R[1].y,"R4\0");
}
void RenderScence()
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0,0.0,0.0);
Point P[2]={{0,1},{3,0}};//p1和p4端点
Point R[2]={{1,2},{-1,1}};//两端点处的切向量
DrawHermite2D(100,P,R);
glFlush();
}
void ChangeSize(GLsizei w,GLsizei h)
{
GLfloat aspectRatio;
if(h==0)
h = 1;
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
aspectRatio = (GLfloat)w/(GLfloat)h;
float s=8;
if(w<=h)
glOrtho(-s,s,-s/aspectRatio,s/aspectRatio,1.0,-1.0);
else
glOrtho(-s*aspectRatio,s*aspectRatio,-s,s,1.0,-1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
int main()
{
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutCreateWindow("DrawBezier");
init();
glutDisplayFunc(RenderScence);
glutReshapeFunc(ChangeSize);
glutMainLoop();
return 0;
}
3.
#include "windows.h"
#include<glut.h>
#include<string>
#include<iostream>
typedef struct{
float x,y,z;
}Point;
int flag=1;//1为bezier曲线,2为B样条曲线
void init()
{
glClearColor(1.0,1.0,1.0,1.0);
}
void displayc(double x,double y,char str[])//显示字符函数
{
glColor3f(0, 0, 0);
//glClear(GL_COLOR_BUFFER_BIT);
glRasterPos2d(x,y);
for(int i=0;i<sizeof(str);i++)
{
glutBitmapCharacter(GLUT_BITMAP_8_BY_13,str[i]);
}
glFlush();
}
void DrawBezier3D(int n,Point P[])
{
Point p;
double t,deltat,t2,t3,et,et2,et3;
int i;
deltat = 1.0/(n-1);
glBegin(GL_LINE_STRIP);
for(i=0;i<100;i++)
{
t = i*deltat;
et = 1-t;
t2 = t*t;
et2 = et*et;
t3 = t*t2;
et3 = et*et2;
p.x = et3*P[0].x+3*t*et2*P[1].x+3*t2*et*P[2].x+t3*P[3].x;
p.y = et3*P[0].y+3*t*et2*P[1].y+3*t2*et*P[2].y+t3*P[3].y;
p.z = et3*P[0].z+3*t*et2*P[1].z+3*t2*et*P[2].z+t3*P[3].z;
glVertex3f(p.x,p.y,p.z);
}
glEnd();
//glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0,1,0);
glPointSize(3);
glBegin(GL_POINTS);
for(i=0;i<4;i++)
{
glVertex2d(P[i].x,P[i].y);
}
glEnd();
displayc(P[0].x,P[0].y,"P1\0");
displayc(P[1].x,P[1].y,"P2\0");
displayc(P[2].x,P[2].y,"P3\0");
displayc(P[3].x,P[3].y,"P4\0");
}
void DrawB3D(int n,Point P[])
{
Point p;
double t,deltat,t2,t3,et,et2,et3;
int i;
deltat = 1.0/(n-1);
glBegin(GL_LINE_STRIP);
for(i=0;i<100;i++)
{
t = i*deltat;
et = 1-t;
t2 = t*t;
et2 = et*et;
t3 = t*t2;
et3 = et*et2;
p.x = et3*P[0].x/6+(3*t3-6*t2+4)*P[1].x/6+(-3*t3+3*t2+3*t+1)*P[2].x/6+t3*P[3].x/6;
p.y = et3*P[0].y/6+(3*t3-6*t2+4)*P[1].y/6+(-3*t3+3*t2+3*t+1)*P[2].y/6+t3*P[3].x/6;
p.z = et3*P[0].z/6+(3*t3-6*t2+4)*P[1].z/6+(-3*t3+3*t2+3*t+1)*P[2].z/6+t3*P[3].z/6;
glVertex3f(p.x,p.y,p.z);
}
glEnd();
//glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0,1,0);
glPointSize(3);
glBegin(GL_POINTS);
for(i=0;i<4;i++)
{
glVertex2d(P[i].x,P[i].y);
}
glEnd();
displayc(P[0].x,P[0].y+0.2,"P1\0");
displayc(P[1].x,P[1].y-0.5,"P2\0");
displayc(P[2].x,P[2].y+0.2,"P3\0");
displayc(P[3].x,P[3].y,"P4\0");
}
void RenderScence()
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0,0.0,0.0);
Point P[4]={{0,0,0},{1,1,1},{2,-1,-1},{3,0,0}};//p1到p4端点
if(flag==1)
DrawBezier3D(100,P);
else
DrawB3D(100,P);
glFlush();
}
void ChangeSize(GLsizei w,GLsizei h)
{
GLfloat aspectRatio;
if(h==0)
h = 1;
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
aspectRatio = (GLfloat)w/(GLfloat)h;
float s=5;
if(w<=h)
glOrtho(-s,s,-s/aspectRatio,s/aspectRatio,1.0,-1.0);
else
glOrtho(-s*aspectRatio,s*aspectRatio,-s,s,1.0,-1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
int main()
{
using namespace std;
cout<<"1为bezier曲线,2为B样条曲线"<<endl;
cin>>flag;
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutCreateWindow("DrawBezier");
init();
glutDisplayFunc(RenderScence);
glutReshapeFunc(ChangeSize);
glutMainLoop();
return 0;
}
4.
#include<windows.h>
#include<gl.h>
#include<glu.h>
#include<glut.h>
#include<stdlib.h>
#include<stdio.h>
#include<string>
#include<iostream>
double z=40;//球的z坐标
double speed=0.05;//球移动速度
int depth=500;//投影视体的深度
int start=40;
int enable=1;//运动的使能信号
void myinit();
void Rendscene();
void Changesize(GLsizei w,GLsizei h);
void mykey(unsigned char key, int x, int y);
void specialkey(int key,int x,int y);
void displayc(double x,double y,double z,char str[]);
int main(int argc,char **argv)
{
glutInit(&argc,argv);//初始化固定格式
glutInitWindowPosition(300,200);//初始化窗口位置
glutInitWindowSize(300,300);//初始化窗口宽度和高度
glutCreateWindow(argv[0]);//以主程序入口地址作为标题
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB|GLUT_DEPTH);//初始化显示模式:双缓存窗口、RGB色彩空间、深度缓存
myinit();//自己定义的初始化函数,设置背景颜色
glutDisplayFunc(Rendscene);//注册显示回调函数
glutReshapeFunc(Changesize);//注册窗口重塑回调函数
glutKeyboardFunc(mykey);//注册键盘回调函数
glutSpecialFunc(specialkey);
glutMainLoop();//进入事件处理循环
}
void myinit()
{
glClearColor(1,1,1,1);//RGBA形式最后一个为透明度,1表示窗体颜色不透明
}
void Changesize(GLsizei w,GLsizei h)
{
float ratio;
if(h==0)
h=1;
ratio=(float)w/(float)h;
glViewport(0,0,w,h);//定义视口
glMatrixMode(GL_PROJECTION);
glLoadIdentity();//定义矩阵模式为投影矩阵,并将矩阵堆栈单位化
gluPerspective(60,ratio,start,depth);//透视矩阵压入堆栈,进行透视变换,四个参数依次为,眼睛睁开角度、宽高比、前透视面距离、后透视面距离(填正值,但其实该透视体处于z负轴)
glEnable(GL_DEPTH_TEST);//开启更新深度缓冲区功能
gluLookAt(20,10,40,0,0,0,0,1,0);//相机从(0,10,40)看向(0,0,0,),(0,1,0)为正方向
glMatrixMode(GL_MODELVIEW);//投影变换完了进入绘图模式
glLoadIdentity();
}
void Rendscene()
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);//清除颜色缓存
glColor3f(1,0,0);
glMatrixMode(GL_MODELVIEW);//投影变换完了进入绘图模式
glLoadIdentity();
if(z>depth)
z=40;
else
z=z+speed;
glTranslated(0.0,0.0,-z);//把整个场景移到到视图中
glutWireSphere(10,180,180);//画半径为10,经度渲染180条和纬度渲染180的球,由于是矩阵堆栈,所以是先移动后转
char str[]="MySphere";
displayc(-30,12,-z,str);
glLoadIdentity();
//画两条平行线当做路
glBegin(GL_LINES);
glColor3f(0,0,0);
glVertex3d(-10,-5,30);
glVertex3d(-15,-5,-depth);
glEnd();
glBegin(GL_LINES);
glColor3f(0,0,0);
glVertex3d(10,-5,30);
glVertex3d(15,-5,-depth);
glEnd();
glFlush();
glutSwapBuffers();//交换缓冲区保证有流畅动画
glLoadIdentity();
if(enable==1)
glutPostRedisplay();//回调生产动画
}
void mykey( unsigned char key, int x, int y) //响应ASCII对应键,鼠标的当前x和y位置也被返回。
{
switch(key)
{
case 'r':enable=1;
glutPostRedisplay();
break;
case 's':enable=0;
glutPostRedisplay();
break;
case 27: exit(-1);
}
}
void specialkey(int key,int x,int y)
{
switch(key)
{
case GLUT_KEY_UP:
speed+=0.01;
break;
case GLUT_KEY_DOWN:
speed-=0.01;
break;
}
}
void displayc(double x,double y,double z,char str[])//显示字符函数
{
glColor3f(0, 0, 0);
//glClear(GL_COLOR_BUFFER_BIT);
glRasterPos3d(x,y,z);
for(int i=0;i<strlen(str);i++)
{
glutBitmapCharacter(GLUT_BITMAP_8_BY_13,str[i]);
}
//glFlush();
}
5.
#include<windows.h>
#include<gl.h>
#include<glu.h>
#include<glut.h>
#include<stdlib.h>
#include<stdio.h>
#include<string>
#include<iostream>
double z=0;//旋转角度
double speed=0.05;//旋转速度
int depth=500;//投影视体的深度
int start=40;
int enable=1;//运动的使能信号
void myinit();
void Rendscene();
void Changesize(GLsizei w,GLsizei h);
void mykey(unsigned char key, int x, int y);
void specialkey(int key,int x,int y);
void displayc(double x,double y,double z,char str[]);
int main(int argc,char **argv)
{
glutInit(&argc,argv);//初始化固定格式
glutInitWindowPosition(300,200);//初始化窗口位置
glutInitWindowSize(300,300);//初始化窗口宽度和高度
glutCreateWindow(argv[0]);//以主程序入口地址作为标题
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB|GLUT_DEPTH);//初始化显示模式:双缓存窗口、RGB色彩空间、深度缓存
myinit();//自己定义的初始化函数,设置背景颜色
glutDisplayFunc(Rendscene);//注册显示回调函数
glutReshapeFunc(Changesize);//注册窗口重塑回调函数
glutKeyboardFunc(mykey);//注册键盘回调函数
glutSpecialFunc(specialkey);
glutMainLoop();//进入事件处理循环
}
void myinit()
{
glClearColor(1,1,1,1);//RGBA形式最后一个为透明度,1表示窗体颜色不透明
}
void Changesize(GLsizei w,GLsizei h)
{
float ratio;
if(h==0)
h=1;
ratio=(float)w/(float)h;
glViewport(0,0,w,h);//定义视口
glMatrixMode(GL_PROJECTION);
glLoadIdentity();//定义矩阵模式为投影矩阵,并将矩阵堆栈单位化
gluPerspective(60,ratio,start,depth);//透视矩阵压入堆栈,进行透视变换,四个参数依次为,眼睛睁开角度、宽高比、前透视面距离、后透视面距离(填正值,但其实该透视体处于z负轴)
glEnable(GL_DEPTH_TEST);//开启更新深度缓冲区功能
gluLookAt(0,10,40,0,0,0,0,1,0);//相机从(0,10,40)看向(0,0,0,),(0,1,0)为正方向
glMatrixMode(GL_MODELVIEW);//投影变换完了进入绘图模式
glLoadIdentity();
}
void Rendscene()
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);//清除颜色缓存
glColor3f(1,0,0);
glMatrixMode(GL_MODELVIEW);//投影变换完了进入绘图模式
glLoadIdentity();
if(z>360)
z=0;
else
z=z+speed;
glTranslated(0.0,-40,-200);//把整个场景移到到视图中
glRotated(z,0,1,0);
glutWireTeapot(60);//画80大小的球,由于是矩阵堆栈,所以是先转
char str[]="MyTeapot";
displayc(-30,80,20,str);
glFlush();
glutSwapBuffers();//交换缓冲区保证有流畅动画
glLoadIdentity();
if(enable==1)
glutPostRedisplay();//回调生产动画
}
void mykey( unsigned char key, int x, int y) //响应ASCII对应键,鼠标的当前x和y位置也被返回。
{
switch(key)
{
case 'r':enable=1;
glutPostRedisplay();
break;
case 's':enable=0;
glutPostRedisplay();
break;
case 27: exit(-1);
}
}
void specialkey(int key,int x,int y)
{
switch(key)
{
case GLUT_KEY_UP:
speed+=0.01;
break;
case GLUT_KEY_DOWN:
speed-=0.01;
break;
}
}
void displayc(double x,double y,double z,char str[])//显示字符函数
{
glColor3f(0, 0, 0);
//glClear(GL_COLOR_BUFFER_BIT);
glRasterPos3d(x,y,z);
for(int i=0;i<strlen(str);i++)
{
glutBitmapCharacter(GLUT_BITMAP_8_BY_13,str[i]);
}
//glFlush();
}