D3D鼠标旋转物体算法(总结)

首先我们需要定义一些变量来储存所需信息

D3DXQUATERNION g_qNow, g_qDown; //分别是 现在的旋转用四元数 按下鼠标时的旋转用四元数

D3DXVECTOR3 g_vDownPt, g_vCurrentPt; //分别是 按下鼠标时的球面上的位置向量 当前的位置向量

bool g_bDrag = false; //是否按下鼠标左键 用来判断按键拖拽

然后初始化这些变量

D3DXQuaternionIdentity(&g_qNow);

D3DXQuaternionIdentity(&g_qDown);

g_bDrag = false;

好了,初始化工作做完了,然后具体讲下算法。

在鼠标按下处理过程

case WM_LBUTTONDOWN:

{

int iMouseX = ( short )LOWORD( lParam );

int iMouseY = ( short )HIWORD( lParam );    //得到屏幕坐标

g_bDrag = true;

g_qDown = g_qNow;

g_vDownPt = ScreenToVector( ( float )iMouseX, ( float )iMouseY );   //得到投影窗口下的坐标

}

在鼠标移动处理过程

case WM_MOUSEMOVE:

{

if( g_bDrag )

{

int iMouseX = ( short )LOWORD( lParam );

int iMouseY = ( short )HIWORD( lParam );  //得到屏幕坐标

g_vCurrentPt = ScreenToVector( ( float )iMouseX, ( float )iMouseY );//得到投影窗口下的坐标

g_qNow = g_qDown * QuatFromBallPoints( g_vDownPt, g_vCurrentPt );

}

}

//看看QuatFromBallPoints函数

D3DXQUATERNION QuatFromBallPoints( const D3DXVECTOR3& vFrom, const D3DXVECTOR3& vTo )

{

D3DXVECTOR3 vPart;

float fDot = D3DXVec3Dot( &vFrom, &vTo ); //取得两向量的点乘,因为两个都是单位向量,所以fDot等于cos theta

D3DXVec3Cross( &vPart, &vFrom, &vTo );//叉乘,获得的是垂直于两个向量的一个向量,即旋转轴。其模等于|a||b|sin theta等于sin theta

return D3DXQUATERNION( vPart.x, vPart.y, vPart.z, fDot );//正好构成一个旋转2*theta角度的四元数

}

首先说一下旋转四元数,一个(x*sin theta, y*sin theta, z*sin theta, cos theta)的四元数被用来旋转2*theta角度。在上面的代码中通过两个单位向量得到了一个旋转四元数。从效果上来说就是鼠标在球体上做过theta角度,物体就旋转2*theta角度。这是一个很方便的解决方法,不仅省却了换算,也使得物体能够在一次拖拽中旋转360度。现在大部分事情都清楚了,接下来只要在绘制之前把世界矩阵按所得的旋转四元数旋转之后绘制物体就可以了。

我们使用D3DXMatrixRotationQuaternion这个函数从四元数得到一个旋转矩阵作为世界矩阵。

D3DXMATRIXA16 matWorld;

D3DXMatrixRotationQuaternion( &matWorld, &g_qNow );

g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );

至此完成,我们只需要在每一次绘制的时候按当前的旋转四元数即g_qNow来设置世界矩阵即可。

首先我们需要定义一些变量来储存所需信息

D3DXQUATERNION g_qNow, g_qDown; //分别是 现在的旋转用四元数 按下鼠标时的旋转用四元数

D3DXVECTOR3 g_vDownPt, g_vCurrentPt; //分别是 按下鼠标时的球面上的位置向量 当前的位置向量

bool g_bDrag = false; //是否按下鼠标左键 用来判断按键拖拽

然后初始化这些变量

D3DXQuaternionIdentity(&g_qNow);

D3DXQuaternionIdentity(&g_qDown);

g_bDrag = false;

好了,初始化工作做完了,然后具体讲下算法。

在鼠标按下处理过程

case WM_LBUTTONDOWN:

{

int iMouseX = ( short )LOWORD( lParam );

int iMouseY = ( short )HIWORD( lParam );    //得到屏幕坐标

g_bDrag = true;

g_qDown = g_qNow;

g_vDownPt = ScreenToVector( ( float )iMouseX, ( float )iMouseY );   //得到投影窗口下的坐标

}

在鼠标移动处理过程

case WM_MOUSEMOVE:

{

if( g_bDrag )

{

int iMouseX = ( short )LOWORD( lParam );

int iMouseY = ( short )HIWORD( lParam );  //得到屏幕坐标

g_vCurrentPt = ScreenToVector( ( float )iMouseX, ( float )iMouseY );//得到投影窗口下的坐标

g_qNow = g_qDown * QuatFromBallPoints( g_vDownPt, g_vCurrentPt );

}

}

//看看QuatFromBallPoints函数

D3DXQUATERNION QuatFromBallPoints( const D3DXVECTOR3& vFrom, const D3DXVECTOR3& vTo )

{

D3DXVECTOR3 vPart;

float fDot = D3DXVec3Dot( &vFrom, &vTo ); //取得两向量的点乘,因为两个都是单位向量,所以fDot等于cos theta

D3DXVec3Cross( &vPart, &vFrom, &vTo );//叉乘,获得的是垂直于两个向量的一个向量,即旋转轴。其模等于|a||b|sin theta等于sin theta

return D3DXQUATERNION( vPart.x, vPart.y, vPart.z, fDot );//正好构成一个旋转2*theta角度的四元数

}

首先说一下旋转四元数,一个(x*sin theta, y*sin theta, z*sin theta, cos theta)的四元数被用来旋转2*theta角度。在上面的代码中通过两个单位向量得到了一个旋转四元数。从效果上来说就是鼠标在球体上做过theta角度,物体就旋转2*theta角度。这是一个很方便的解决方法,不仅省却了换算,也使得物体能够在一次拖拽中旋转360度。现在大部分事情都清楚了,接下来只要在绘制之前把世界矩阵按所得的旋转四元数旋转之后绘制物体就可以了。

我们使用D3DXMatrixRotationQuaternion这个函数从四元数得到一个旋转矩阵作为世界矩阵。

D3DXMATRIXA16 matWorld;

D3DXMatrixRotationQuaternion( &matWorld, &g_qNow );

g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );

至此完成,我们只需要在每一次绘制的时候按当前的旋转四元数即g_qNow来设置世界矩阵即可。


相关文章

  • 实现太阳自传,地球公转的程序
  • 3D游戏从入门到精通 作者:佚名 来源:不详 发布时间:2007-4-5 18:46:17 减小字体 增大字体 有了上面绕着坐标轴旋转的矩阵,就可以轻松地构造我们的太阳系了.在我们太阳系中,太阳是自转的,在这个例子里要就要让太阳绕着Y轴自转 ...查看


  • 计算机图形学究极题库 - 副本
  • 名词解释: 1.图形:能够在人们视觉系统中形成视觉印象的对象称为图形,包括自然景物和人工绘图. 2.像素图:点阵法列举图形中的所有点.用点阵法描述的图形称为像素图. 3.参数图:参数法描述图形的形状参数和属性参数.用参数法描述的图形称为参数 ...查看


  • 最全面的犀牛快捷键命令
  • (1).按功能分类的快捷键 Sift+Page Up 英文:Adjust the lens length of the camera in a perspective view 中文:调整透视图中相机的焦距 Shift+Page Down ...查看


  • 接触ZBrush第一步-画布控制栏
  • ZBrush画布控制栏中的每一个命令在整个软件中有着举足轻重的作用,本文将对画布控制栏做详细介绍,以便新手能快速入门. 对画布控制栏各按钮的说明如下: : 渲染工具.渲染编辑工具,最好的预览渲染 . : 亚像素抗锯齿渲染质量. : 画布实际 ...查看


  • 点云数据的配准方法研究
  • ·计算技术与自动化· 点云数据的配准方法研究 陈三清 摘 (攀枝花学院计算机学院,四川攀枝花617000) 要:利用三维扫描技术获取的点云数据在三维物体的恢复与重建中有重要的应用.本文首先论述了点云数据配准算法的研 最后对ICP 算法未来的 ...查看


  • 用连除解决实际问题
  • 用连除解决实际问题 教学内容:P11-12 教学目标: 1.初步了解用连除解决的实际问题的基本结构和数量关系,能列式解决这类的实际问题. 2.在解决实际问题的过程中体验解决问题方法的多样化,进一步培养分析和推理能力. 教学重点:了解应用题的 ...查看


  • 淘宝店铺装修代码大全
  • <淘宝店铺装修代码大全> 如何提高店铺的访问量呢? 这个问题大家一定都很想知道,有好的产品,有好的宣传,更吸引顾客眼球的是你有特别的装修,让你的店铺与众不同! 好了,现在简单为大家总结了所有的 html设计代码大全 1)贴图:本 ...查看


  • 线结构光的3维目标测量与多分辨率建模
  • 第!" 卷第#期*++,年)) 月 测绘学报 -. /-0123-1/4.-56.-7/207-894.-:4(4.- $%&'!" ,(%')) (%;',*++,文献标识码:- ! ! ! ! ! ! ! ! ...查看


  • 轴类零件尺寸测量专用影像系统的研究
  • 砌n蝴ond嘲工艺与检测 轴类零件尺寸测量专用影像系统的研究' 叶晓平 (丽水学院机电与建工学院,浙江丽水323000) 摘要:介绍了高精度尺寸测量影像系统研究的意义,以及系统的原理.组成和各部分的功能,并阐述了影像 测量中的基本算法原理. ...查看


热门内容