查看: 1034|回复: 2

Trackball的实现

[复制链接]

该用户从未签到

发表于 2014-8-23 14:00:38 | 显示全部楼层 |阅读模式
本帖最后由 daiday 于 2014-8-23 15:59 编辑

最近在学习OGL,为了从基础的开始,使用了GLUT来搞.不过拖拖拽拽不方便,所以又把osg的数学的部分提出来,单独使用.然后向做个简单的相机控制,写一个trackball.这就是背景吧.

首先来说,osg的Trackball当然是很好使了,不过我是没看懂怎么个意思.
于是我按照自己的想法----当然是错误的想法----实现了一个简单的trackball
  1. void Camera::trackball(float pt0_x, float pt0_y, float pt1_x, float pt1_y)
  2. {
  3.         // pt0_x和pt0_y是单位化后[-1~1]的屏幕坐标,是上一次事件的坐标值,算是旋转开始点呗
  4.         // pt1_x和pt1_y当然也一样,是当前事件坐标值,算是旋转结束点
  5.         osg::Vec3 v0(pt0_x, pt0_y, std::sqrt( osg::maximum(1-pt0_x*pt0_x -pt0_y*pt0_y, 0.f) ));
  6.         osg::Vec3 v1(pt1_x, pt1_y, std::sqrt( osg::maximum(1-pt1_x*pt1_x -pt1_y*pt1_y, 0.f) ));
  7.         osg::Quat q;
  8.         q.makeRotate(v1, v0);

  9.         //mRotation = mRotation * q; // 本来以为应该这么搞,结果怎么都不对?
  10.         mRotation = q * mRotation ;  // 这样子就对?为啥?胡蒙都蒙对了?
  11. }
复制代码

代码就上面的那样子.问题就出在了最后面.本来我认为应该是mRotation * q这样子来做旋转的.但是很显然不正确啊.然后就在我来回折腾验算的时候,无意中把这个值改成了 q * mRotation.竟然神奇的挺好使.妹的.
从OSG的Trackball代码来看,最后_rotation的计算确实应该是
  1. _rotation = _rotation * new_quat ;
复制代码

从这里来看,我上面代码所求出来的q,用osg所求出来的new_quat来表示,为
  1. q = _rotaiton * new_quat * _rotation.inverse();
复制代码

我就日了.这个地方我的鸡冠头怎么也想不通了.现在还是想自己安安静静的学习学习,所以很在乎这种细节上的问题.究竟是为啥?为啥?愁.
我想既然代码里面表现的是一样的,最起码应该说明方法是对的.但是思路呢?说好的自己写的trackball,自己不知道为啥,这太不合适了吧.
求论坛坛友指点一二,让我的鸡冠头也能融会贯通.
以上.

该用户从未签到

发表于 2014-8-23 15:25:03 | 显示全部楼层
这个应该表达的是在原有基础上旋转。所以原有旋转在前

该用户从未签到

发表于 2014-8-23 18:52:09 | 显示全部楼层
本帖最后由 cenfer 于 2014-8-23 19:02 编辑

很明显,这涉及姿态矩阵的左乘右程是代表相对运动还是绝对运动。
虽然这里是四元数的形式,道理还是类似的。
我想你应该知道矩阵的乘法不支持交换律。
如果矩阵作为姿态矩阵,其乘法赋予物理意义就是相对运动还是绝对运动。
矩阵的左乘右程到底对应什么运动,还和姿态信息是按行存储,还是列存储有关。
因为根据矩阵的转置法则(A*B)T =BT*AT,T代表转置啊
您需要登录后才可以回帖 登录 | 注册

本版积分规则

OSG中国官方论坛-有您OSG在中国才更好

网站简介:osgChina是国内首个三维相关技术开源社区,旨在为国内更多的技术开发人员提供最前沿的技术资讯,为更多的三维从业者提供一个学习、交流的技术平台。

联系我们

  • 工作时间:09:00--18:00
  • 反馈邮箱:1315785073@qq.com
快速回复 返回顶部 返回列表