三维重建:点绕特定轴旋转公式
???? 一些特定的三維平面運算可以直接在三維空間中進行,也可以在二維平面中運行,通過坐標變化轉換到三維空間。旋轉方式有中心旋轉、軸旋轉。
1. 羅德里格旋轉公式?
?? 在三維旋轉理論體系中,羅德里格旋轉公式(根據歐林·羅德里格命名)是在給定轉軸和旋轉角度后,旋轉一個向量的有效算法。如果v是在中的向量,k是轉軸的單位向量,θ是旋轉角度(根據叉乘的方向確定正負號),那羅德里格旋轉公式表達為:
輸入:
V = (vx, vy, vz) = (u, v, w),這是待旋轉的一個向量。
K = (kx, ky, kz) = (x, y, z),這是單位化后的轉軸。
輸出:Vrot
計算過程及公式:
Vrot = V cosT + (K * V) sinT + K ( K . V) (1- cosT) 
??????? = (u, v, w) cosT + (yw - zv, zu - xw, xv - yu) sinT + (x, y, z)(xu + yv + zw)(1 - cosT)
計算公式:
?Vrot.x = u cosT + (yw - zv) sinT + x (xu + yv + zw) ( 1- cosT)
?Vrot.y = v cosT + (zu - xw) sinT + y (xu + yv + zw) ( 1- cosT)
?Vrot.z = w cosT + (xv - yu) sinT + z (xu + yv + zw) ( 1- cosT)
代碼(java版本):
public static Point3d rtRoundLine( Point3d line, Point3d p, double Aplha ){double u = p.m_x;double v = p.m_y;double w = p.m_z;double T = Aplha;Point3d axisU = unit( line );double x= axisU.m_x;double y= axisU.m_y;double z= axisU.m_z;//長度double l= Math.sqrt(dot(line,line) );Point3d Vrot = new Point3d();Vrot.m_x = u *Math.cos(T) + (y * w - z * v) *Math.sin(T) + x *(x * u + y * v + z * w)*( 1- Math.cos(T));Vrot.m_y = v *Math.cos(T) + (z * u - x * w) *Math.sin(T) + y *(x * u + y * v + z * w)*( 1- Math.cos(T));Vrot.m_z = w *Math.cos(T) + (x * v - y * u) *Math.sin(T) + z *(x * u + y * v + z * w)*( 1- Math.cos(T));return Vrot;}但是羅德里格旋轉公式不適用于任意旋轉軸旋轉,得到的結果是錯誤的。
二、任意點繞特定軸旋轉
?? 參考文章:點繞任意軸旋轉....
?? 使用通用的把軸轉換到Z軸上的方法,經過兩次變換和兩次逆變換得到旋轉矩陣。
如下方法處理:
假設用v1(a1, b2, c2)和v2(a2, b2, c2)來表示旋轉軸,θ表示旋轉角度。為了方便推導,暫時使用右手系并使用列向量,待得出矩陣后轉置一下即可,上面步驟對應的流程圖如下。
.................................
即
對應的函數代碼如下(Java版本):
public static double[][] GetRotMatByLine( Point3d v1, Point3d v2, double theta ){int col = 4;int row = 4;double[][] pOut= new double[row][col];//一次性完成???double a = v1.m_x;double b = v1.m_y;double c = v1.m_z;//D3DXVECTOR3 p = *v2 - *v1;Point3d p = new Point3d(v2.m_x-v1.m_x,v2.m_y-v1.m_y,v2.m_z-v1.m_z);//D3DXVec3Normalize(&p, &p);p = unit( p );double u = p.m_x;double v = p.m_y;double w = p.m_z;double uu = u * u;double uv = u * v;double uw = u * w;double vv = v * v;double vw = v * w;double ww = w * w;double au = a * u;double av = a * v;double aw = a * w;double bu = b * u;double bv = b * v;double bw = b * w;double cu = c * u;double cv = c * v;double cw = c * w;double costheta = Math.cos(theta);double sintheta = Math.sin(theta);pOut[0][0] = uu + (vv + ww) * costheta;pOut[0][1] = uv * (1 - costheta) + w * sintheta;pOut[0][2] = uw * (1 - costheta) - v * sintheta;pOut[0][3] = 0;pOut[1][0] = uv * (1 - costheta) - w * sintheta;pOut[1][1] = vv + (uu + ww) * costheta;pOut[1][2] = vw * (1 - costheta) + u * sintheta;pOut[1][3] = 0;pOut[2][0] = uw * (1 - costheta) + v * sintheta;pOut[2][1] = vw * (1 - costheta) - u * sintheta;pOut[2][2] = ww + (uu + vv) * costheta;pOut[2][3] = 0;pOut[3][0] = (a * (vv + ww) - u * (bv + cw)) * (1 - costheta) + (bw - cv) * sintheta;pOut[3][1] = (b * (uu + ww) - v * (au + cw)) * (1 - costheta) + (cu - aw) * sintheta;pOut[3][2] = (c * (uu + vv) - w * (au + bv)) * (1 - costheta) + (av - bu) * sintheta;pOut[3][3] = 1;return pOut;}//GetRotMatByLine使用函數的代碼:
public static Point3d rtRoundLine( Point3d ps, Point3d pe, Point3d p, double Aplha,double[][] transM ){//計算旋轉點Point3d Vrot = new Point3d();//點乘矩陣if( true ){Vrot.m_x = p.m_x* transM[0][0] +p.m_y* transM[1][0] +p.m_z* transM[2][0]+ transM[3][0];Vrot.m_y = p.m_x* transM[0][1] +p.m_y* transM[1][1] +p.m_z* transM[2][1]+ transM[3][1];Vrot.m_z = p.m_x* transM[0][2] +p.m_y* transM[1][2] +p.m_z* transM[2][2]+ transM[3][2];}Vrot.m_z =-Vrot.m_z;return Vrot;}示例結果:
??
點云圖與平面圖對比
參考:各種旋轉方式總結.....
????? ? ?? 羅德里格旋轉公式....
總結
以上是生活随笔為你收集整理的三维重建:点绕特定轴旋转公式的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: Learning Face Age Pr
- 下一篇: 知乎怎么看提问人是谁
