实现鼠标对立体图的控制

实现鼠标对立体图的控制非常重要,比如可以要求转动鼠标使得立体图形跟着旋转,以看清立体图的全貌

首先是转动,就是拖动鼠标,图形可以跟着转

我暂时想到了两种办法可以实现这一点,第一种是不改变立体图形,改变观察点的位置,第二是不改变观察点的位置,对立体进行旋转。

我也是真的是没想到这个问题越来越复杂,说白了还是数学没学好

不过经过一天的努力,好多计划我已经放弃了,不过现在先挖几个坑,之后再填。。当然更希望CSDN上的大神可以帮帮我解决一下。。


第一种是改变观察点的位置,先上代码~~

</pre><pre name="code" class="cpp">#include<GL/GLUT.H>    
#include <windows.h>        
#include <math.h>        
#include <gl/GL.h>        

static const GLfloat vertex_list[][3] = {
	-0.5f, -0.5f, -0.5f,
	0.5f, -0.5f, -0.5f,
	0.5f, 0.5f, -0.5f,
	-0.5f, 0.5f, -0.5f,
	-0.5f, -0.5f, 0.5f,
	0.5f, -0.5f, 0.5f,
	0.5f, 0.5f, 0.5f,
	-0.5f, 0.5f, 0.5f,
};

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

static const GLint index_list[][4] = {
	0, 1, 2, 3,//bottem      
	0, 3, 7, 4,//left      
	2, 3, 7, 6,//front      
	1, 2, 6, 5,//right      
	0, 1, 5, 4,//back      
	4, 5, 6, 7//top      
};

float M_PI=3.14159265f;


static float c = M_PI/180.0f; //弧度和角度转换参数
static int du = 90, oldmy = -1, oldmx = -1; //du是视点绕y轴的角度,opengl里默认y轴是上方向
static float r = 1.75f, h = 0.0f; //r是视点绕y轴的半径,h是视点高度即在y轴上的坐标

void display(void)
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glEnable(GL_DEPTH_TEST);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(80.0f,1.0f, 1.0f, 1000.0f);
	glMatrixMode(GL_MODELVIEW);


	//printf("At:%.2f %.2f %.2f\n",r*cos(c*du),h,r*sin(c*du)); //这就是视点的坐标
	glLoadIdentity();
	gluLookAt(r*cos(c*du), h, r*sin(c*du), 0, 0, 0, 0, 1, 0); //从视点看远点,y轴方向(0,1,0)是上方向


	for (int i = 0; i < 6; ++i)      // 有六个面,循环六次      
	{
		glColor3f(colors[i][0], colors[i][1], colors[i][2]);
		glBegin(GL_POLYGON);
		for (int j = 0; j < 4; ++j)     // 每个面有四个顶点,循环四次      
			glVertex3fv(vertex_list[index_list[i][j]]);
		glEnd();
	}

	glColor3f(1, 0, 0);
	for (int i = 0; i < 6; ++i)      // 有六个面,循环六次      
	{
		glBegin(GL_LINE_LOOP);
		for (int j = 0; j < 4; ++j)     // 每个面有四个顶点,循环四次      
			glVertex3fv(vertex_list[index_list[i][j]]);
		glEnd();
	}

	
	glFlush();
	glutSwapBuffers();
}
void Mouse(int button, int state, int x, int y) //处理鼠标点击
{
	if (state == GLUT_DOWN) //第一次鼠标按下时,记录鼠标在窗口中的初始坐标
		oldmx = x, oldmy = y;
}
void onMouseMove(int x, int y) //处理鼠标拖动
{
	//printf("%d\n",du);
	du += x - oldmx; //鼠标在窗口x轴方向上的增量加到视点绕y轴的角度上,这样就左右转了
	h += 0.03f*(y - oldmy); //鼠标在窗口y轴方向上的改变加到视点的y坐标上,就上下转了
	//if (h>1.0f) h = 1.0f; //视点y坐标作一些限制,不会使视点太奇怪
	//else if (h<-1.0f) h = -1.0f;
	oldmx = x, oldmy = y; //把此时的鼠标坐标作为旧值,为下一次计算增量做准备
}

int main(int argc, char *argv[])
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
	glutInitWindowPosition(100, 100);
	glutInitWindowSize(400, 400);
	glutCreateWindow("OpenGL");
	glutDisplayFunc(display);
	glutIdleFunc(display);  //设置不断调用显示函数
	glutMouseFunc(Mouse);
	glutMotionFunc(onMouseMove);
	glutMainLoop();
	return 0;
}

其中比较重要的是这么几个地方

首先前面的

        glLoadIdentity();
	gluLookAt(r*cos(c*du), h, r*sin(c*du), 0, 0, 0, 0, 1, 0); //从视点看远点,y轴方向(0,1,0)是上方向

static float c = M_PI/180.0f; //弧度和角度转换参数
static int du = 90, oldmy = -1, oldmx = -1; //du是视点绕y轴的角度,opengl里默认y轴是上方向

static float r = 1.75f, h = 0.0f; //r是视点绕y轴的半径,h是视点高度即在y轴上的坐标
gluLookAt函数我们在之前就介绍过了,在绕着y轴旋转的的方向可以保持物体的大小不变,这是因为对y轴的半径没变




第二种方法是对物体进行旋转

#include<GL/GLUT.H>      
#include <windows.h>          
#include <math.h>          
#include <gl/GL.h>          
  
static const GLfloat vertex_list[][3] = {  
    -0.5f, -0.5f, -0.5f,  
    0.5f, -0.5f, -0.5f,  
    0.5f, 0.5f, -0.5f,  
    -0.5f, 0.5f, -0.5f,  
    -0.5f, -0.5f, 0.5f,  
    0.5f, -0.5f, 0.5f,  
    0.5f, 0.5f, 0.5f,  
    -0.5f, 0.5f, 0.5f,  
};  
  
GLfloat colors[][3] = {  
    { 1.0, 0.0, 0.0 },  
    { 1.0, 1.0, 0.0 },  
    { 0.0, 1.0, 0.0 },  
    { 0.0, 1.0, 1.0 },  
    { 1.0, 0.0, 1.0 },  
    { 0.0, 0.0, 1.0 },  
    { 0.0, 0.5, 0.0 },  
    { 0.0, 0.5, 0.5 },  
};  
  
static const GLint index_list[][4] = {  
    0, 1, 2, 3,//bottem        
    0, 3, 7, 4,//left        
    2, 3, 7, 6,//front        
    1, 2, 6, 5,//right        
    0, 1, 5, 4,//back        
    4, 5, 6, 7//top        
};  
  
float M_PI=3.14159265f;  
  
  
static float c = M_PI/180.0f; //弧度和角度转换参数  
static int du = 90, oldmy = -1, oldmx = -1; //du是视点绕y轴的角度,opengl里默认y轴是上方向  
static float r = 1.75f, h = 0.0f; //r是视点绕y轴的半径,h是视点高度即在y轴上的坐标  
  
void display(void)  
{  
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);  
    glEnable(GL_DEPTH_TEST);  
    glMatrixMode(GL_PROJECTION);  
    glLoadIdentity();  
    gluPerspective(80.0f,1.0f, 1.0f, 1000.0f);  
    glMatrixMode(GL_MODELVIEW);  
  
  
    //printf("At:%.2f %.2f %.2f\n",r*cos(c*du),h,r*sin(c*du)); //这就是视点的坐标  
    glLoadIdentity();  
    gluLookAt(r, 0.2, r, 0, 0, 0, 0, 1, 0); //从视点看远点,y轴方向(0,1,0)是上方向  
  
    glRotatef(30*c*du, 0, 1, 0);  
	glRotatef(-h, -1, 0, 0);  

    for (int i = 0; i < 6; ++i)      // 有六个面,循环六次        
    {  
        glColor3f(colors[i][0], colors[i][1], colors[i][2]);  
        glBegin(GL_POLYGON);  
        for (int j = 0; j < 4; ++j)     // 每个面有四个顶点,循环四次        
            glVertex3fv(vertex_list[index_list[i][j]]);  
        glEnd();  
    }  
  
    glColor3f(1, 0, 0);  
    for (int i = 0; i < 6; ++i)      // 有六个面,循环六次        
    {  
        glBegin(GL_LINE_LOOP);  
        for (int j = 0; j < 4; ++j)     // 每个面有四个顶点,循环四次        
            glVertex3fv(vertex_list[index_list[i][j]]);  
        glEnd();  
    }  
  
      
    glFlush();  
    glutSwapBuffers();  
}  
void Mouse(int button, int state, int x, int y) //处理鼠标点击  
{  
    if (state == GLUT_DOWN) //第一次鼠标按下时,记录鼠标在窗口中的初始坐标  
        oldmx = x, oldmy = y;  
}  
void onMouseMove(int x, int y) //处理鼠标拖动  
{  
    //printf("%d\n",du);  
    du += x - oldmx; //鼠标在窗口x轴方向上的增量加到视点绕y轴的角度上,这样就左右转了  
    h += (y - oldmy); //鼠标在窗口y轴方向上的改变加到视点的y坐标上,就上下转了  
    //if (h>1.0f) h = 1.0f; //视点y坐标作一些限制,不会使视点太奇怪  
    //else if (h<-1.0f) h = -1.0f;  
    oldmx = x, oldmy = y; //把此时的鼠标坐标作为旧值,为下一次计算增量做准备  
}  
  
int main(int argc, char *argv[])  
{  
    glutInit(&argc, argv);  
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);  
    glutInitWindowPosition(100, 100);  
    glutInitWindowSize(400, 400);  
    glutCreateWindow("OpenGL");  
    glutDisplayFunc(display);  
    glutIdleFunc(display);  //设置不断调用显示函数  
    glutMouseFunc(Mouse);  
    glutMotionFunc(onMouseMove);  
    glutMainLoop();  
    return 0;  
}  

http://www.bubuko.com/infodetail-435954.html

http://zhidao.baidu.com/question/4401444.html?qbl=relate_question_0&word=%CF%C8%C8%C6%D7%C5x%D6%E1%2C%D4%D9%C8%C6%D7%C5y%D6%E1%D0%FD%D7%AA


你可能感兴趣的:(图形,OpenGL,CAGD)