计算机图形学第三次上机——物体的移动和旋转(含视窗景深)

计算机图形学第二次上机实验 课程实验报告

目录

计算机图形学第二次上机实验 课程实验报告

一、实验目的

二、实验环境

三、实验内容

四,源代码



 

一、实验目的

  1. 掌握配置glut库的步骤
  2. 测试运行示例代码
  3. 掌握并编写中点线算法和中点圆算法

二、实验环境

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样条曲线多项式:

结果为

  • 其它
  1. 编写程序,使一物体沿着一条直线匀速移动。

 

 

为实现显示中的视觉效果

需要添加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. 编写程序,使一物体围绕屏幕上一点匀速旋转。

思想与第一问类似,结果如下

四,源代码

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

}

发布了47 篇原创文章 · 获赞 28 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qq_41122796/article/details/86640029