三維空間中的幾何變換-平移旋轉縮放
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