1. 程式人生 > >三維空間中的幾何變換-平移旋轉縮放

三維空間中的幾何變換-平移旋轉縮放

https://blog.csdn.net/swety_gxy/article/details/73087848

前言

前段時間由於專案需要,深入學習了下圖形幾何變換,主要是繞任意軸旋轉部分(其他的已有一定基礎),現記錄學習筆記。

文章內容部分引用並參考了下面的部落格:


http://netclass.csu.edu.cn/NCourse/hep089/Chapter6/CG_Txt_6_012.htm

http://www.cnblogs.com/graphics/archive/2012/08/10/2627458.html

原理

由於用齊次座標表示,三維幾何變換的矩陣是一個4階方陣,其形式如下:

其中,產生按軸縮放、旋轉、錯切等變換。產生平移變換,產生投影變換,產生整體的縮放變換。

(1)平移

三維平移變換的計算,通常是左乘一個平移矩陣,表示方式可以如下:

(2)縮放

對於空間任意參考點的縮放變換,縮放矩陣的形成過程如下:

<1>將參考點平移到原點處;

<2>進行縮放變換;

<3>平移回原位置;

則最終變換矩陣結果如下:

其中,等號左邊中間的矩陣的由縮放向量(分別對應x軸、y軸,z軸方向的縮放)構成的縮放矩陣。

(3)繞座標軸旋轉

考慮右手座標系下相對座標原點繞座標軸旋轉q 角的變換:

<1>繞X軸轉

<2>繞Y軸轉

<3>繞Z軸轉

三維空間的平移旋轉及縮放的示意圖可如下表示:

(4)繞任意軸旋轉

設旋轉軸AB由任意一點A(xa,ya,za)及其方向數(a,b,c)定義,

可以通過下列步驟來實現P點的旋轉:

     A. 將A點移到座標原點。

     B. 使AB分別繞X軸、Y軸旋轉適當角度與Z軸重合。

     

     D.作上述變換的逆操作,使AB回到原來位置。

是AB在YOZ平面與XOZ平面的投影與Z軸的夾角。

我們可以得到如下的矩陣:

設旋轉軸A(a,b,c)過原點,旋轉角度為θ,

則旋轉矩陣為:

設旋轉軸A(u,v,w)不過原點,P(a,b,c)是旋轉軸的起點,旋轉角度為θ,

則旋轉矩陣為:

對一個三維頂點作任意軸的旋轉變換,只需左乘旋轉矩陣即可。

示例程式碼

<1>空間點繞任意旋轉軸旋轉,函式輸入引數是單位化後的軸方向、軸上任一點、旋轉角度、要旋轉的點


void RotateVecPoint(float& angle, osg::Vec3& N, osg::Vec3 center, osg::Vec3& Pt)
    {
        //輸入引數是旋轉軸上的任意一點P(a,b,c),單位化後的旋轉軸方向向量N(u,v,w),旋轉角度θ,要旋轉的點
        float mcos = cos(angle), msin = sin(angle);
        /*若旋轉軸過原點*/
        /*osg::Matrixf mat = osg::Matrixf(
        pow(N.x(), 2)*(1 - mcos) + mcos, N.x()*N.y()*(1 - mcos) + N.z()*msin, N.x()*N.z()*(1 - mcos) - N.y()*msin, 0.0,
        N.x()*N.y()*(1 - mcos) - N.z()*msin, pow(N.y(), 2)*(1 - mcos) + mcos, N.y()*N.z()*(1 - mcos) + N.x()*msin, 0.0,
        N.x()*N.z()*(1 - mcos) + N.y()*msin, N.y()*N.z()*(1 - mcos) - N.x()*msin, pow(N.z(), 2)*(1 - mcos) + mcos, 0.0,
        0.0, 0.0, 0.0, 1.0);*/
        /*若旋轉軸不過原點:涵蓋了上面的情況*/
        float a = center.x(), b = center.y(), c = center.z();//軸所在直線起點
        float u = N.x(), v = N.y(), w = N.z();
        //轉置
        osg::Matrixf mat = osg::Matrixf(
            u*u + (v*v + w*w)*mcos, v*u*(1 - mcos) + w*msin, w*u*(1 - mcos) - v*msin, 0.0,
            u*v*(1 - mcos) - w*msin, v*v + (u*u + w*w)*mcos, v*w*(1 - mcos) + u*msin, 0.0,
            u*w*(1 - mcos) + v*msin, v*w*(1 - mcos) - u*msin, w*w + (u*u + v*v)*mcos, 0.0,
            (a*(v*v + w*w) - u*(b*v + c*w))*(1 - mcos) + (b*w - c*v)*msin, (b*(u*u + w*w) - v*(a*u + c*w))*(1 - mcos) + (c*u - a*w)*msin, (c*(u*u + v*v) - w*(a*u + b*v))*(1 - mcos) + (a*v - b*u)*msin, 1.0
            );
        mat.preMult(Pt);
    }

效果圖
<1>空間圓繞著任意軸旋轉一定的角度

關於幾何變換更詳細的描述請參考:

http://netclass.csu.edu.cn/NCourse/hep089/Chapter6/CG_Txt_6_012.htm

http://www.cnblogs.com/graphics/archive/2012/08/10/2627458.html