萬丈高樓平地起;勿在浮沙築高台。
暫時放下其他的東西的學習,還不能稱之為學習。潛心研究pbrt,看到第二章繞任意軸的旋轉一部分,但是只是給了一個大體的推導,最終的推導並沒有給出,所以在此做一下簡單的推導。
給定一個規范化的方向向量a作為旋轉軸,然后使向量v繞着這個軸旋轉θ度,如圖1所示,首先我們計算一個平行於向量a的向量 ,此向量與向量a的起點相同,終點與向量v的終點(此時向量v與向量a起點相同)在以a為法線的平面上。假設向量v與a之間的夾角為 ,那么我們有
我們首先在這個平面上構造一組向量基 v1與 v2,其中 v1是v1=v - vc,
另外一個基向量可以通過兩個向量的叉乘得到:v2 = (v1 x a),因為向量a是規范化的,所以v1與v2具有相同的長度,這個長度與v與vc之間的向量長度相同。在旋轉平面(v1與v2所在的平面)來計算v繞向量vc旋轉θ得到:
再繼續下面推導之前先復習一下向量點乘與叉乘的基本規律:
向量點乘符合以下規律:
向量叉乘符合以下規律:
現在可以開始推導上面的公式了,推導過程如下:(手機效果太爛。。。將就着看吧)
最后附上源碼:
1: Transform Rotate(float angle, const Vector &axis) {2: Vector a = Normalize(axis);3: float s = sinf(Radians(angle));4: float c = cosf(Radians(angle));5: float m[4][4];6:7: m[0][0] = a.x * a.x + (1.f - a.x * a.x) * c;8: m[0][1] = a.x * a.y * (1.f - c) - a.z * s;9: m[0][2] = a.x * a.z * (1.f - c) + a.y * s;10: m[0][3] = 0;11:12: m[1][0] = a.x * a.y * (1.f - c) + a.z * s;13: m[1][1] = a.y * a.y + (1.f - a.y * a.y) * c;14: m[1][2] = a.y * a.z * (1.f - c) - a.x * s;15: m[1][3] = 0;16:17: m[2][0] = a.x * a.z * (1.f - c) - a.y * s;18: m[2][1] = a.y * a.z * (1.f - c) + a.x * s;19: m[2][2] = a.z * a.z + (1.f - a.z * a.z) * c;20: m[2][3] = 0;21:22: m[3][0] = 0;23: m[3][1] = 0;24: m[3][2] = 0;25: m[3][3] = 1;26:27: Matrix4x4 mat(m);28: return Transform(mat, Transpose(mat));29: }


![]TM145XK7I`FRL`D[$8N3TC ]TM145XK7I`FRL`D[$8N3TC](/image/aHR0cHM6Ly9pbWFnZXMuY25ibG9ncy5jb20vY25ibG9nc19jb20vY2dfZ2hvc3QvMjAxMjA0LzIwMTIwNDI3MTI1NDIzNzg1My5qcGc=.png)
![`9P5MH}21~V$U]83E1WL1{T `9P5MH}21~V$U]83E1WL1{T](/image/aHR0cHM6Ly9pbWFnZXMuY25ibG9ncy5jb20vY25ibG9nc19jb20vY2dfZ2hvc3QvMjAxMjA0LzIwMTIwNDI3MTI1NDI4Nzg1OC5qcGc=.png)

![_L2@P]1C9`@8HBKU$UR958M _L2@P]1C9`@8HBKU$UR958M](/image/aHR0cHM6Ly9pbWFnZXMuY25ibG9ncy5jb20vY25ibG9nc19jb20vY2dfZ2hvc3QvMjAxMjA0LzIwMTIwNDI3MTI1NDMxMTc3Ni5qcGc=.png)