您的位置:首页 > 大数据 > 人工智能

3D- rotaion and zoom in/out pan function in opengl

2018-01-31 00:28 399 查看
More seriously, you can find an example about one regular cube rotation where you can select the axis of rotation
with the mouse's buttons at http://www.macs.hw.ac.uk/~mjc/wp-mjc...xample_7_2.cpp
(you can immediatly destroy the stdafx.h include because it's seem me very too platform dependant and I don't see
why is it here ...) 

You can easily add variables for to handling the rotation and scaling speeds using rotation/scaling variables coupled
with a detection of mouse movements 
(for example, left/right for the rotation and bottom/top for scaling)
=> this is typically an excellent exercice for to begin with the OpenGL development 


Here an working example :

// Example_7_2.cpp : Using Rotation with Vertex Arrays
//
// Author  : E. Angel, Interactive Computer Graphics
//           A Top-Down Approach with OpenGL, Third Edition
//           Addison-Wesley Longman, 2003
// Version : 1.1 - Commenting changed to match other examples style
//
// Using Vertex Arrays
//
// Program behaviour:
// Left Mouse Button (LMB) spins the cube on its X-Axis
// Right Mouse Button (RMB) spins the cube on its Y-Axis
// Middle Mouse Button (MMB) spins the cube on its Z-Axis
//
// Callback commentary sent to normal command window.
//
// Last tested in Visual C++ 2010 Express

// YLP 01/05/2013 : add a dynamic rotation and scaling (+ comment the stdafx.h include for to be more cross-platform compliant)
// mouse left/right movments during mouse button down :  handle the rotation speed
// mouse top/bottom movments durinf mouse button down :  handle the general scaling of the cube
// tested on Linux

// #include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <GL/glut.h>

//======================================================
// GLOBAL VARIABLES
//======================================================

GLfloat vertices[] =
{-1.0,-1.0,-1.0,
1.0,-1.0,-1.0,
1.0,1.0,-1.0,
-1.0,1.0,-1.0,
-1.0,-1.0,1.0,
1.0,-1.0,1.0,
1.0,1.0,1.0,
-1.0,1.0,1.0};

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

// define cube faces
// each set of 4 indices indicates a different face
GLubyte cubeIndices[]=
{0,3,2,1,
2,3,7,6,
0,4,7,3,
1,2,6,5,
4,5,6,7,
0,1,5,4};

static GLfloat theta[] = {0.0, 0.0, 0.0}; // Rotation (X,Y,Z)
static GLint axis = 2; // Changed by the Mouse Callback Routine

// YLP 01/05/2013 : add scaling and dynamics rotations speed
static int lastx = 0, lasty = 0;
static GLfloat rotate_speed = 0.5f;
static GLfloat  scaling = 1.0f;

//======================================================
// MOUSE CALLBACK ROUTINE
//======================================================
void mouseCallBack(int btn, int state, int x, int y)
{

// Changes the rotation axis depending on the mouse button pressed.
if ( state == GLUT_DOWN )
{
if( btn == GLUT_LEFT_BUTTON ) axis = 0;
if( btn == GLUT_MIDDLE_BUTTON ) axis = 1;
if( btn == GLUT_RIGHT_BUTTON) axis = 2;
}
}

// YLP 01/05/2013 : add dynamics rotation and scaling speed
void motionCallBack(int x, int y)
{
int movx, movy;

movx = lastx - x;
movy = lasty - y;

if ( abs(movx) < 10 ){ rotate_speed += (float)(movx) / 50.0f; }
if ( abs(movy) < 10 ){ scaling  += (float)(movy) / 100.0f;  }

if ( scaling < 00.1f) scaling = 0.1f;
if ( scaling > 10.0f) scaling = 10.0f;

lastx = x;
lasty = y;
}

//======================================================
// IDLE CALLBACK ROUTINE
//======================================================
// YLP 01/05/2013 : add dynamic rotation speed + scaling speed/limits
void idleCallBack()
{
// Spins the cube around the set axis.
theta[axis] += rotate_speed;

while( theta[axis] > 360.0 ) theta[axis] -= 360.0;
while( theta[axis] < 360.0 ) theta[axis] += 360.0;

glutPostRedisplay();
}

//======================================================
// WINDOW RESHAPE ROUTINE
//======================================================
void displayReshape(int w, int h)
{
// If the display is re-sized in any way, the cube is redrawn
// so that it fits the display properly. Try it!

glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w <= h)
glOrtho(-4.0, 4.0, -3.0 * (GLfloat) h / (GLfloat) w,
5.0 * (GLfloat) h / (GLfloat) w, -10.0, 10.0);
else
glOrtho(-4.0 * (GLfloat) w / (GLfloat) h,
4.0 * (GLfloat) w / (GLfloat) h, -3.0, 5.0, -10.0, 10.0);
glMatrixMode(GL_MODELVIEW);
}

//======================================================
// DISPLAY CALL BACK ROUTINE
//======================================================
void displayCallBack()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glLoadIdentity();
gluLookAt(1.0,1.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0);
glTranslatef(0.0, 1.0, 0.0);
glRotatef(theta[0], 1.0, 0.0, 0.0);
glRotatef(theta[1], 0.0, 1.0, 0.0);
glRotatef(theta[2], 0.0, 0.0, 1.0);
glScalef(scaling, scaling, scaling);

// Now draw the cube
glColorPointer(3,GL_FLOAT, 0, colors);
glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, cubeIndices);

glutSwapBuffers();
}

//======================================================
// MAIN PROGRAM
//======================================================
int main(int argc, char** argv)
{
// Allow cmd line arguments to be passed to the glut
glutInit(&argc, argv);

// Create and name window
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); // Need both double buffering and z buffer
glutInitWindowSize(500, 500);
glutCreateWindow("Example 7.2 - Vertex Arrays");

// Add Display & Mouse CallBacks
glutReshapeFunc(displayReshape);
glutD
4000
isplayFunc(displayCallBack);
glutIdleFunc(idleCallBack);
glutMouseFunc(mouseCallBack);
glutMotionFunc(motionCallBack);

glShadeModel(GL_FLAT); //use one colour per face
glEnable(GL_DEPTH_TEST); /* Enable hidden--surface--removal */
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, vertices);
glColorPointer(3,GL_FLOAT, 0, colors);
glClearColor(0.0,0.0,0.0,1.0);
glColor3f(0.0,0.0,0.0);

// Print information about the application in the command console
printf("Cube Rotation & Vertex Array Example\nChange Axis of Rotation by pressing Left, Right or Middle Mouse Buttons\n\n");

//Enter infinite loop calling 'displayCallBack'
glutMainLoop();

return 0;
}


zoom-in、zoom-out与图形放大、图形缩小的差别

许多人不知道zoom-in、zoom-out的确切意义,以为zoom-in就是图形放大、zoom-out就是图形缩小。其实,它们是有差别的。下面我来解释一下其中差别。

 

     zoom的意思是改变视距。zoom-in是将视距缩小,相当于离开事物近一点距离去观察事物,故看到物体确实会变大;zoom-out是将视距放大,即离开事物远一点去观察事物,所以事物看到确实会缩小。从这个角度来看,说zoom-in就是图形放大、zoom-out就是图形缩小也没有错。如果你用百度或Google翻译一下zoom in 或zoom out的中文,结果也会得到这样的解释。

      但另一方面,图形放大不一定要改变人对物体观察距离才能形成,将摄影所得底片或者你以前保存的小照片拿到照相馆去,他们也能将底片或旧照片上的任何形像放大。

     计算机中讲的图形放大就包含两种意义下的放大,而且通常指的是后一种意义的放大。

     照片是一个平面的东西,图形放大或缩小都是对这平面图形本身尺寸的改变,和物体已没有关系。图形放大和缩小是靠计算机软件来实现的,没有计算机,图形是不会放大缩小的。在图形放大或缩小是,人与图形的距离不发生关系。从几何学观点来看,图形放大就是一个相似变换,放大前后的两个图形是完全相似的。而zoom
in 或zoom out则不同,这是一个透视变换:如果物体本身是一平面图,则zoomIn的效果也会和放大完全一样,但如果物体是三维的,或者有背景存在,情况就会不同:在改变同一视距的情况下,在被观察到的不同物体中,距离近的大小相对变化大,距离远的物体相对变化小。下面有几种现成的图片可以说明一些问题。这里用到zoom,也用到缩放。



1 一张C60分子图形,所有原子一样大,但距离远的原子画得要小一点,因人观察它们时所撑视角小了



2 zoom in同时适当输小 后,近的原子变大明显,远的变化也变大,但不明显,因变化的距离比例不大,且为了维持整个分子的尺寸不变,所有原子要输小,这样距离远原子反而的显得小了



再 zoom in和整个分子适当缩小 ,近的原子变更大,为了保持整个分子不变,远的原子反而输小更多,明显失真了






4 如果只有缩放,那么就如上所示,各部分图形都有相同大小的变化率
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: