首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >四元数乘法的几何意义是什么?

四元数乘法的几何意义是什么?
EN

Stack Overflow用户
提问于 2013-04-01 12:11:50
回答 1查看 157关注 0票数 1

我目前正在编写一个Arcball (用于模型视图相机),我正在研究MS DXUT代码,它们有一个Arcball实现,如下所示

代码语言:javascript
复制
#include "ArcBall.h"

ArcBall::ArcBall(void)
{
        Reset() ;
        m_vDownPt = D3DXVECTOR3( 0, 0, 0 ) ;
        m_vCurrentPt = D3DXVECTOR3( 0, 0, 0 ) ;
        m_Offset.x = 0 ;
        m_Offset.y = 0 ;
}

ArcBall::~ArcBall(void)
{
}

void ArcBall::Reset()
{
        D3DXQuaternionIdentity( &m_qDown );
        D3DXQuaternionIdentity( &m_qNow );
        D3DXMatrixIdentity( &m_mRotation );
        m_bDrag = FALSE;
        m_fRadius = 1.0f;

        RECT rc ;
        GetClientRect(GetForegroundWindow(), &rc) ;
        SetWindow(rc.right, rc.bottom) ;
}

void ArcBall::OnBegin(int nX, int nY)
{
        // enter drag state only if user click the window's client area
        if( nX >= m_Offset.x && 
                nX <= m_Offset.x + m_nWidth &&
                nY >= m_Offset.y &&
                nY < m_Offset.y + m_nHeight )
        {
                m_bDrag = true ; // begin drag state
                m_qDown = m_qNow ;
                m_vDownPt = ScreenToVector((float)nX, (float)nY) ;
        }
}

void ArcBall::OnMove(int nX, int nY)
{
        if(m_bDrag)
        {
                m_vCurrentPt = ScreenToVector((float)nX, (float)nY) ;
                m_qNow = m_qDown * QuatFromBallPoints( m_vDownPt, m_vCurrentPt ) ;
        }
}

void ArcBall::OnEnd()
{
        m_bDrag = false ;
}

void ArcBall::SetOffset( INT nX, INT nY )
{
        m_Offset.x = nX ; 
        m_Offset.y = nY ;
}

void ArcBall::SetWindow( int nWidth, int nHeight, float fRadius)
{
         m_nWidth = nWidth; 
         m_nHeight = nHeight; 
         m_fRadius = fRadius; 
         m_vCenter = D3DXVECTOR2(m_nWidth / 2.0f, m_nHeight / 2.0f);
}

const D3DXMATRIX* ArcBall::GetRotationMatrix()
{
        return D3DXMatrixRotationQuaternion(&m_mRotation, &m_qNow) ;
}

D3DXQUATERNION ArcBall::QuatFromBallPoints(const D3DXVECTOR3 &vFrom, const D3DXVECTOR3 &vTo)
{
        D3DXVECTOR3 vPart;
        float fDot = D3DXVec3Dot( &vFrom, &vTo );       // rotation angle
        D3DXVec3Cross( &vPart, &vFrom, &vTo );          // rotation axis

        return D3DXQUATERNION( vPart.x, vPart.y, vPart.z, fDot );
}

D3DXVECTOR3 ArcBall::ScreenToVector(float fScreenPtX, float fScreenPtY)
{
        // Scale to screen
        // xֵΪ¸º£¬ÊÇÒòΪDirectXʹÓÃ×óÊÖϵ
        FLOAT x = -( fScreenPtX - m_Offset.x - m_nWidth / 2 ) / ( m_fRadius * m_nWidth / 2 );
        FLOAT y = ( fScreenPtY - m_Offset.y - m_nHeight / 2 ) / ( m_fRadius * m_nHeight / 2 );

        FLOAT z = 0.0f;
        FLOAT mag = x * x + y * y;

        if( mag > 1.0f )
        {
                FLOAT scale = 1.0f / sqrtf( mag );
                x *= scale;
                y *= scale;
        }
        else
                z = sqrtf( 1.0f - mag );

        // Return vector
        return D3DXVECTOR3( x, y, z );
}

在函数移动中,我们可以看到两个四元数的乘法

代码语言:javascript
复制
m_qNow = m_qDown * QuatFromBallPoints( m_vDownPt, m_vCurrentPt ) ; 

function QuatFromBallPoints根据两个点计算四元数的底数。我想知道这个产品是什么意思?

代码说明:当用户拖动鼠标时,当鼠标按键按下(假设是左键)时,OnBegin函数被调用。当鼠标按键打开时,调用OnEnd函数;当用户拖动鼠标时,调用OnMove函数。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-04-03 23:10:15

乘法是指旋转的组合。QuatFromBallPoints返回将m_vDownPt映射到m_vCurrentPt的旋转。此新旋转必须与arcball的当前旋转(开始拖动时的旋转)组合在一起。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15737519

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档