Expérience 11—Monde interactif en 3D

1. But de l'expérience

1. Maîtriser davantage le concept de programmation 3D
2. Maîtriser principalement l'impact des changements de point de vue et de cible sur la génération de scènes
3. Maîtriser les compétences de base des scènes itinérantes 3D

2. Contenu expérimental

Le programme subsidiaire rotate_torus.cpp est un programme de rotation 3D dont le point de vue reste inchangé. La scène 3D est un anneau, une petite boule et une boîte englobante d'un mur carré avec un quadrilatère comme unité de base, et la petite boule et l'anneau sont dans le "mur carré" dans la boîte englobante de . Le point de vue est réglé pour observer l'objet directement devant, et la balle et l'anneau tournent autour d'un certain endroit autour du centre de l'anneau en continu.
Ajoutez une fonction de réponse au clavier, de sorte que :
1) Appuyez sur les touches "W" et "S" du clavier pour déplacer le point de vue vers l'avant et vers l'arrière (aller tout droit vers l'avant et vers l'arrière); (à ce moment, la distance entre le point de vue et le point cible doit rester inchangé et la direction de visée constante).
2) Appuyez sur les touches "A" et "D" du clavier pour faire pivoter le point de vue à gauche et à droite ; (à ce moment, le point de vue doit être fixe, le point cible tourne autour du point de vue et la distance entre le point de vue et le point cible reste inchangé).
3) Une fois le point de vue tourné à gauche et à droite d'un certain angle, appuyez sur les touches "W" et "S" du clavier pour obtenir une ligne de visée droite, c'est-à-dire pour marcher dans la direction de la ligne de visée tournée.
4) Une fois le programme modifié, observez l'effet et vérifiez-le avec le clavier. Écrivez les points clés et les codes de base pour aller tout droit en avant et en arrière et tourner à gauche et à droite dans le rapport d'expérience.
Modification du code :

void mykeyboard(unsigned char key,int x,int y){
    
    //重点在于视点和目标点的变化Y坐标不变化
	switch(key){
    
    
		case 'W':
		case 'w'://向前直走
			//代码
			eyex=eyex-step*sin(angle*PI/180.0);
			eyez=eyez-step*cos(angle*PI/180.0);
			atx=atx-step*sin(angle*PI/180.0);
			atz=atz-step*cos(angle*PI/180.0);
			break;
		case 'S':
		case 's'://向后退
			//代码
			eyex=eyex+step*sin(angle*PI/180.0);
			eyez=eyez+step*cos(angle*PI/180.0);
			atx=atx+step*sin(angle*PI/180.0);
			atz=atz+step*cos(angle*PI/180.0);
			break;
		case 'A':
		case 'a'://左看
			//代码
			angle+=1;
			atx=eyex-x*sin(angle*PI/180.0);
			atz=eyez-x*cos(angle*PI/180.0);
			break;
		case 'D':
		case 'd'://右看
			//代码
			angle-=1;
			atx=eyex-x*sin(angle*PI/180.0);
			atz=eyez-x*cos(angle*PI/180.0);
			break;
	}
	glutPostRedisplay();//参数修改后调用重画函数,屏幕图形将发送改变
} 

insérez la description de l'image ici
insérez la description de l'image ici
insérez la description de l'image ici
insérez la description de l'image ici
insérez la description de l'image ici
5) Si une théière qui tourne constamment est ajoutée au centre de l'anneau, comment implémenter le code ? Collez les captures d'écran de l'effet et le code principal dans le rapport d'expérience.
Modification du code :
ajout à la fin de void drawsphere();

glPushMatrix();
	glColor3f(0,0,1);
	glTranslatef(0,0,0);
	glRotatef(theta,1,0,0);
	glTranslatef(0,0,0);
	glutWireTeapot(30);
	glPopMatrix();

insérez la description de l'image ici
insérez la description de l'image ici
insérez la description de l'image ici
insérez la description de l'image ici
6) Modifiez la scène, ajoutez vos propres objets 3D dans la position prédéterminée de la scène et collez la capture d'écran de l'effet et le code principal dans le rapport d'expérience.
Réviser:

void drawsphere(){
    
    
	float tr;
	tr=(outer+3*inner);
	glRotatef(theta,0,1,0);
	glPushMatrix();
	 glPushMatrix();
	  glColor3f(1.0,0,0);
	  glRotatef(90,1,0,0);
	  glutWireTorus(inner,outer,30,50);
	 glPopMatrix();

	 glPushMatrix();
	 glColor3f(1.0,1,0);
	 glRotatef(45,1,0,0);
	 glutWireTorus(inner,outer-40,30,50);
	 glPopMatrix();
	 glPushMatrix();
	 glColor3f(0,1,0.5);
	  glRotatef(-45,1,0,0);
	  glutWireTorus(inner,outer-60,30,50);
	  glPopMatrix();

	  glPushMatrix();
	  glColor3f(0,1,0.5);
	  glRotatef(-45,1,0,0);
	  glutWireTorus(inner,outer-60,30,50);
	  glPopMatrix();

	  glPushMatrix();
	  glColor3f(1.0,0,1.0);
	  glutWireTorus(inner-20,outer-20,30,50);
	  glPopMatrix();

	  glPushMatrix();//小球饶outer点转,其实是x=outer这条相对于Y的轴
	  glTranslatef(outer,0,0);
	  glRotatef(theta,0,1,0);
	  glTranslatef(-outer,0,0);

	  glPushMatrix();//画小球,饶x轴转
	  glTranslatef(tr,0,0);
	  glRotatef(-45,1,0,0);
	  glColor3f(0.0,1.0,0);
	  glutSolidIcosahedron();
	  glPopMatrix();
	  glPopMatrix();
	  glPopMatrix();

	glPushMatrix();
	glColor3f(0,0,1);
	glTranslatef(0,0,0);
	glRotatef(theta,1,0,0);
	glTranslatef(0,0,0);
	glScalef(10,10,10);
	glutWireSphere(inner,20,20);
	glPopMatrix();
}

insérez la description de l'image ici
insérez la description de l'image ici

3. Questions de réflexion

1. Pourquoi la distance entre le plan de détourage éloigné et la caméra dans la fonction de projection en perspective est-elle définie sur 2 outer8 inner250 dans cet exemple ?
Réponse : gluperspective(90,l/h,10,2 extérieur+8 intérieur+250) ; la distance entre le plan de détourage éloigné et la caméra (point de vue) est de 2 extérieur8 intérieur250, et s=extérieur+4*intérieur+50 ; le plan de détourage éloigné La distance au point de vue doit être au moins 2 fois supérieure à la distance entre l'œil et le point cible, afin que l'objet puisse être affiché dans toute la fenêtre pendant le processus de rotation.
2. Si vous utilisez la souris pour vous déplacer (les coordonnées de la souris sont des coordonnées bidimensionnelles) pour faire glisser toute la scène vers la gauche, la droite, le haut et le bas (coordonnées mondiales tridimensionnelles), comment modifier le programme ?
Réponse : Si la scène est bidimensionnelle, modifiez les paramètres de l'axe z liés à j à l'axe y.
3. Sur cette base, l'objectif peut être agrandi et dézoomé, regardant vers le bas, etc. Comment modifier le programme ?
Réponse : Il est réalisé en changeant la matrice de transformation de projection.

4. Référence de fonction

Reportez-vous à l'expérience 9 et à l'expérience 10.

5. Programme de démonstration

//3D_Rota
#include "Shiyan11-1.h"
#include "stdafx.h"
#include <math.h>
#include <gl/glut.h>
#include "stdafx.h"
#define PI 3.14159
float theta=-90;
int inner=10,outer=80;
float s=outer+4*inner+50;
float eyex=0,eyey=0,eyez=s;
float atx=0,aty=0,atz=0;
int ww,hh;
bool flag=true;
double angle=0;//漫游移动旋转角
float step=0.1*s;//步长为视点到目标点的距离
void display(void);
void reshape(int w,int h);
void mytime(int value);
void drawground();
void drawsphere();
void drawwall();
void init();
void mykeyboard(unsigned char key,int x, int y);
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPTSTR lpCmdLine,int nCmdShow){
    
    
	UNREFERENCED_PARAMETER(hPrevInstance);
	UNREFERENCED_PARAMETER(lpCmdLine);
	char* argv[] = {
    
     (char*)"hello ",(char*)" " };
	int argc = 2;		//argv中的字符串数
	glutInit(&argc, argv);  //初始化GLUT库
	glutInitWindowSize(800, 800);                       //设置显示窗口大小 
	int sheight = glutGet(GLUT_SCREEN_WIDTH);
	int swidth = glutGet(GLUT_SCREEN_HEIGHT);
	glutInitWindowPosition(sheight / 2 - 400, swidth / 2 - 400);  //窗口左上角在屏幕的位置
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);        //设置显示模式(注意双缓存 )
	glutCreateWindow("Rotating 3D world");						
	glutReshapeFunc(reshape); 
	init();						
	glutDisplayFunc(display);                           //用于绘制当前窗口
	glutKeyboardFunc(mykeyboard);
	glutTimerFunc(100,mytime,10);
	glutMainLoop();                                     //开始运行程序
	return 0;
}
void init() {
    
    
	glClearColor(1,1,1,1);
	glPixelStorei(GL_PACK_ALIGNMENT,1);
	glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); 
}
void mykeyboard(unsigned char key,int x,int y){
    
    //重点在于视点和目标点的变化Y坐标不变化
	switch(key){
    
    
		case 'W':
		case 'w'://向前直走
			//代码
			eyex=eyex-step*sin(angle*PI/180.0);
			eyez=eyez-step*cos(angle*PI/180.0);
			atx=atx-step*sin(angle*PI/180.0);
			atz=atz-step*cos(angle*PI/180.0);
			break;
		case 'S':
		case 's'://向后退
			//代码
			eyex=eyex+step*sin(angle*PI/180.0);
			eyez=eyez+step*cos(angle*PI/180.0);
			atx=atx+step*sin(angle*PI/180.0);
			atz=atz+step*cos(angle*PI/180.0);
			break;
		case 'A':
		case 'a'://左看
			//代码
			angle+=1;
			atx=eyex-x*sin(angle*PI/180.0);
			atz=eyez-x*cos(angle*PI/180.0);
			break;
		case 'D':
		case 'd'://右看
			//代码
			angle-=1;
			atx=eyex-x*sin(angle*PI/180.0);
			atz=eyez-x*cos(angle*PI/180.0);
			break;
	}
	glutPostRedisplay();//参数修改后调用重画函数,屏幕图形将发送改变
}
void display(void) {
    
    
	glClear(GL_COLOR_BUFFER_BIT); 
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	gluLookAt(eyex,eyey,eyez,atx,aty,atz,0,1,0);
	glPushMatrix();
	glColor3f(0,0,1);
	drawwall();
	glColor3f(1,0,0);
	drawground();
	drawsphere();
	glPopMatrix();
	glutSwapBuffers();
}
void drawsphere(){
    
    
	float tr;
	tr=(outer+3*inner);
	glRotatef(theta,0,1,0);
	glPushMatrix();
	 glPushMatrix();
	  glColor3f(1.0,0,0);
	  glRotatef(90,1,0,0);
	  glutWireTorus(inner,outer,30,50);
	 glPopMatrix();

	 glPushMatrix();
	 glColor3f(1.0,1,0);
	 glRotatef(45,1,0,0);
	 glutWireTorus(inner,outer-40,30,50);
	 glPopMatrix();
	 glPushMatrix();
	 glColor3f(0,1,0.5);
	  glRotatef(-45,1,0,0);
	  glutWireTorus(inner,outer-60,30,50);
	  glPopMatrix();

	  glPushMatrix();
	  glColor3f(0,1,0.5);
	  glRotatef(-45,1,0,0);
	  glutWireTorus(inner,outer-60,30,50);
	  glPopMatrix();

	  glPushMatrix();
	  glColor3f(1.0,0,1.0);
	  glutWireTorus(inner-20,outer-20,30,50);
	  glPopMatrix();

	  glPushMatrix();//小球饶outer点转,其实是x=outer这条相对于Y的轴
	  glTranslatef(outer,0,0);
	  glRotatef(theta,0,1,0);
	  glTranslatef(-outer,0,0);

	  glPushMatrix();//画小球,饶x轴转
	  glTranslatef(tr,0,0);
	  glRotatef(-45,1,0,0);
	  glColor3f(0.0,1.0,0);
	  glutSolidIcosahedron();
	  glPopMatrix();
	  glPopMatrix();
	  glPopMatrix();
	glPushMatrix();
	glColor3f(0,0,1);
	glTranslatef(0,0,0);
	glRotatef(theta,1,0,0);
	glTranslatef(0,0,0);
	glScalef(10,10,10);
	glutWireSphere(inner,20,20);
	glPopMatrix();
}
void drawground(){
    
    
	//ground
	for(int i=-outer-4*inner;i<outer+4*inner;i+=2*inner)
		for(int j=-outer-4*inner;j<outer+4*inner;j+=2*inner){
    
    
			glBegin(GL_QUADS);
			  glVertex3d(j,-outer-4*inner,i);
			  glVertex3d(j,-outer-4*inner,i+2*inner);
			  glVertex3d(j+2*inner,-outer-4*inner,i+2*inner);
			  glVertex3d(j+2*inner,-outer-4*inner,i);
			glEnd();
		}
	//top
	for(int i=-outer-4*inner;i<outer+4*inner;i+=2*inner)
		for(int j=-outer-4*inner;j<outer+4*inner;j+=2*inner){
    
    
			glBegin(GL_QUADS);
			  glVertex3d(j,outer+4*inner,i);
			  glVertex3d(j,outer+4*inner,i+2*inner);
			  glVertex3d(j+2*inner,outer+4*inner,i+2*inner);
			  glVertex3d(j+2*inner,outer+4*inner,i);
			glEnd();
		}
}
void drawwall(){
    
    
	int i,j;
	glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
	//left
	for(i=-outer-4*inner;i<outer+4*inner;i+=2*inner)
		for(j=-outer-4*inner;j<outer+4*inner;j+=2*inner){
    
    
			glBegin(GL_QUADS);
			  glVertex3d(-outer-4*inner,j,i);
			  glVertex3d(-outer-4*inner,j+2*inner,i);
			  glVertex3d(-outer-4*inner,j+2*inner,i+2*inner);
			  glVertex3d(-outer-4*inner,j,i+2*inner);
			glEnd();
		}
	//right
	for(i=-outer-4*inner;i<outer+4*inner-2*inner;i+=2*inner)
		for(j=-outer-4*inner;j<outer+4*inner-2*inner;j+=2*inner){
    
    
			glBegin(GL_QUADS);
			  glVertex3d(outer+4*inner,j,i);
			  glVertex3d(outer+4*inner,j+2*inner,i);
			  glVertex3d(outer+4*inner,j+2*inner,i+2*inner);
			  glVertex3d(outer+4*inner,j,i+2*inner);
			glEnd();
		}
			glColor3f(1,1,0);
	//front
	for(i=-outer-4*inner;i<outer+4*inner-2*inner;i+=2*inner)
		for(j=-outer-4*inner;j<outer+4*inner-2*inner;j+=2*inner){
    
    
			glBegin(GL_QUADS);
			  glVertex3d(j,i,-outer-4*inner);
			  glVertex3d(j+2*inner,i,-outer-4*inner);
			  glVertex3d(j+2*inner,i+2*inner,-outer-4*inner);
			  glVertex3d(j,i+2*inner,-outer-4*inner);
			glEnd();
		}
}
void mytime(int value){
    
    
	theta+=0.5;
	if(theta>360)theta=-360;
	glutPostRedisplay();
	glutTimerFunc(100,mytime,10);
}
void reshape(GLsizei w, GLsizei h) {
    
    
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(90, w / h, 10, 2*outer+8*inner+250); //定义透视投影投影观察体大小
	glViewport(0, 0, w, h);
	glMatrixMode(GL_MODELVIEW);
	ww=w;
	hh=h;
}

insérez la description de l'image ici

Je suppose que tu aimes

Origine blog.csdn.net/weixin_52030647/article/details/130730105
conseillé
Classement