1.固定点绘制:
思路:为了在屏幕固定位置画点P,我们可以先在空间坐标上某个位置绘制一点(这一点在投影到屏幕中的位置好确定),然后再移动到相应的位置p’,使得p’投影到屏幕时位置正好为p。
当空间投影面如上定义时,我采用的方法是:先在投影面的坐标原点o(0,0)处定义点p,这时点p映射到屏幕坐标时应显示在屏幕上的o点处。但真实的点应该定义在p’处。可见需要对其平移到p’处.那么就要计算平移距离transx,transy.
投影面的平移距离是可以根据屏幕的平移距离计算出来的。屏幕坐标o移动到p(50,50)处时,X向左平移w/2-50,Y向下平移h/2-50。由于投影面与屏幕是成比例的,一个像素对应的空间坐标长度就是20/h(或者( 宽比宽)20.0/h*w/w,他们是相同的)。因此像素移动的距离为(w/2-50,h/2-50),则坐标移动的距离为((w/2-50)*20/h,(h/2-50)*20/h).
2.坐标轴绕固定点旋转:
思路:简单的旋转变化,但是由于opengl的旋转变化都是相对原点的,所以产生旋转时,要先在原点位置处进行旋转操作,后才能进行平移操作。
代码:
#include <iostream>
using namespace std;
#include<gl/glut.h>
GLfloat transx,transy;
GLfloat scale;
int primw=300;
int primh=300;
GLfloat rotatex=0,rotatey=0;
GLint mousepx,mousepy;
void rend(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glPointSize(8);
glLineWidth(2);
glColor3f(1,0,0);
glPushMatrix();
glTranslatef(transx,transy,0);
glRotatef(rotatex,1,0,0);
glRotatef(rotatey,0,1,0);
glBegin(GL_LINES);
glVertex3f(0,0,0);
glVertex3f(0,2,0);
glVertex3f(0,0,0);
glVertex3f(2,0,0);
glVertex3f(0,0,0);
glVertex3f(0,0,2);
glEnd();
glPopMatrix();
glFlush();
}
void reshape(int w, int h)
{
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if(w<=h)
gluOrtho2D(-10,10,-10.0/w*h,10.0/w*h);
else
gluOrtho2D(-10.0/h*w,10.0/h*w,-10,10);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
if(w<=h)
{
/* scale=(GLfloat)primw/w;*/
transx=(50-w/2.0)*20.0/w;
transy=(50-h/2.0)*20.0/w;
}
else
{
/* scale=(GLfloat)primh/h;*/
transx=(50-w/2.0)*20.0/h;
transy=(50-h/2.0)*20.0/h;
}
}
void motion(int x, int y)
{
int w,h;
w=glutGet(GLUT_WINDOW_WIDTH);
h=glutGet(GLUT_WINDOW_HEIGHT);
if(0<=x && x<=w && 0<=y && y<=h)
{
rotatex=(mousepy-y)/(GLfloat)h*360;
rotatey=(mousepx-x)/(GLfloat)w*360;
/* cout<<"rotatex:rotatey"<<rotatex<<" "<<rotatey<<endl;*/
glutPostRedisplay();
}
}
void mousedown(int mouse, int state , int x, int y)
{
if(state== GLUT_DOWN)
{
mousepx=x;
mousepy=y;
}
// cout<<"mousepx:mousepy"<<endl;
// cout<<mousepx<<" "<<mousepy<<endl;
}
int main(int argc,char** argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_RGB);
glutInitWindowSize(primw,primh);
glutCreateWindow("coordination");
glClearColor(1,1,1,0);
glutDisplayFunc(rend);
glutMotionFunc(motion);
glutMouseFunc(mousedown);
glutReshapeFunc(reshape);
glutMainLoop();
return 0;
}