编程(www.cppentry.com)实现自由旋转的方法和经验
1、首先建立一个虚拟球类
用面向对象的方法来解决问题,能使解决方案有很好的可移植性和可维护性。而VC++(www.cppentry.com)是功能强大的面向对象编程(www.cppentry.com)的工具,所以我们使用VC++面向对象程序设计的方案来实现自由旋转功能。虚拟球类的声明如下:
class VirtualBall { protected: void _mapToSphere(const Point2fT* NewPt, Vector3fT* NewVec) const; public: //构造和析构函数 VirtualBall(GLfloat NewWidth, GLfloat NewHeight); ~VirtualBall() { /* 不做任何事*/ }; //设置边界, 当窗口大小改变时,使虚拟球与窗口大小相适应 void setBounds(GLfloat NewWidth, GLfloat NewHeight) void click(const Point2fT* NewPt);// 鼠标按下,映射起始点到虚拟球 //鼠标拖动,第二个鼠标坐标在这里得到更新,并映射到虚拟球上,计算旋转 //轴的向量和夹角的信息,将它们保存到一个四元数NewRot中(前3个元素为 //坐标信息,最后一个元素为关于夹角的信息,其实就是两个向量的点乘) void drag(const Point2fT* NewPt, Quat4fT* NewRot); protected: Vector3fT StVec; //保存鼠标点击时的向量(起始点) Vector3fT EnVec; //保存拖动时的向量(终点) GLfloat AdjustWidth; //setBounds函数用其来调整窗口 GLfloat AdjustHeight; } |
2、把鼠标坐标映射为虚拟球上的坐标
通过虚拟球的旋转来达到旋转模型的目的,关键在于把视图中鼠标点击和拖动的坐标映射为虚拟球上的坐标。
为此,我们首先简单的把鼠标点击和拖动的范围[0~width),[0~height)映射到 [-1~1],[1~ -1](在映射中我们颠倒了y坐标的符号,不然OpenGL中得不到正确的结果)。这样做可以使数学计算变得简单些,其映射如下:
MousePt.X = ((MousePt.X / ((Width – 1) / 2)) – 1); MousePt.Y = -((MousePt.Y / ((Height – 1) / 2)) – 1); |
其次,计算鼠标矢量,将鼠标坐标映射到虚拟球上,可以根据式1的定义完成这一步工作。
|