将鼠标事件的设备坐标转换到世界坐标
一、首先,对设备坐标、视口坐标、世界坐标进行说明。
设备坐标:单位是像素,坐标系如图,屏幕左上角为原点,X轴水平向右增大,Y轴垂直向下增大。
世界坐标和视口坐标的对应关系,如下
GLfloat left,right,bottom,top;//世界坐标系中被投影的范围
float A,B,C,D;//世界坐标和视口坐标的缩放和平移参数
SetWindowAndViewport(width,height);//设置世界坐标和视口坐标的对应关系,自定义函数
//width,height,分别代表客户区的大小
SetWindowAndViewport(GLint width, GLint height)
{
left=bottom=-10000;
right=top=10000;
//建立一个最简单的坐标系
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//设置 世界坐标系 的投影范围大小
gluOrtho2D(left,right,bottom,top);
//设置 视口 中的投影范围大小 也为windows窗口的宽和高
glViewport(0,0,width,height);
//计算缩放和平移参数
A=(width-0)/(right-left);
B=(height-0)/(top-bottom);
C=0-A*left;
D=0-B*bottom;
TRACE("A=%f,B=%f,C=%f,D=%f/n",A,B,C,D);
}
经过上述设置,视口的坐标系统如下,窗口的左下角为原点,X轴水平向右增大,Y轴垂直向上增大
经实践,这一过程经历如下两个过程。
1. 从设备坐标到视口坐标.
2. 从视口坐标到世界坐标
OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
TRACE("Device Point x=%d,y=%d/n",point.x,point.y);
CRect clientRect;
GetClientRect(clientRect);
CPoint windowPoint;//保存世界坐标系中的点
windowPoint.x=point.x;//从设备坐标转换成视口坐标
windowPoint.y=clientRect.Height()-point.y;
TRACE("View Point x=%d,y=%d/n",windowPoint.x,windowPoint.y);
windowPoint=GetWindowPoint(windowPoint);//从视口坐标到世界坐标,使用自定义函数
TRACE("world Point x=%d,y=%d/n",windowPoint.x,windowPoint.y);
//在世界坐标系中绘图
glBegin(GL_POINTS);
glVertex2i(windowPoint.x,windowPoint.y);
glEnd();
glFlush();
CView::OnLButtonDown(nFlags, point);
}
CPoint GetWindowPoint(CPoint viewportPoint)
{
CPoint windowPoint;
windowPoint.x=(viewportPoint.x-C)/A;
windowPoint.y=(viewportPoint.y-D)/B;
return windowPoint;
}