三维重建:点绕特定轴旋转公式
???? 一些特定的三維平面運(yùn)算可以直接在三維空間中進(jìn)行,也可以在二維平面中運(yùn)行,通過坐標(biāo)變化轉(zhuǎn)換到三維空間。旋轉(zhuǎn)方式有中心旋轉(zhuǎn)、軸旋轉(zhuǎn)。
1. 羅德里格旋轉(zhuǎn)公式?
?? 在三維旋轉(zhuǎn)理論體系中,羅德里格旋轉(zhuǎn)公式(根據(jù)歐林·羅德里格命名)是在給定轉(zhuǎn)軸和旋轉(zhuǎn)角度后,旋轉(zhuǎn)一個(gè)向量的有效算法。如果v是在中的向量,k是轉(zhuǎn)軸的單位向量,θ是旋轉(zhuǎn)角度(根據(jù)叉乘的方向確定正負(fù)號),那羅德里格旋轉(zhuǎn)公式表達(dá)為:
輸入:
V = (vx, vy, vz) = (u, v, w),這是待旋轉(zhuǎn)的一個(gè)向量。
K = (kx, ky, kz) = (x, y, z),這是單位化后的轉(zhuǎn)軸。
輸出:Vrot
計(jì)算過程及公式:
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)
計(jì)算公式:
?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;}但是羅德里格旋轉(zhuǎn)公式不適用于任意旋轉(zhuǎn)軸旋轉(zhuǎn),得到的結(jié)果是錯(cuò)誤的。
二、任意點(diǎn)繞特定軸旋轉(zhuǎn)
?? 參考文章:點(diǎn)繞任意軸旋轉(zhuǎn)....
?? 使用通用的把軸轉(zhuǎn)換到Z軸上的方法,經(jīng)過兩次變換和兩次逆變換得到旋轉(zhuǎn)矩陣。
如下方法處理:
假設(shè)用v1(a1, b2, c2)和v2(a2, b2, c2)來表示旋轉(zhuǎn)軸,θ表示旋轉(zhuǎn)角度。為了方便推導(dǎo),暫時(shí)使用右手系并使用列向量,待得出矩陣后轉(zhuǎn)置一下即可,上面步驟對應(yīng)的流程圖如下。
.................................
即
對應(yīng)的函數(shù)代碼如下(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使用函數(shù)的代碼:
public static Point3d rtRoundLine( Point3d ps, Point3d pe, Point3d p, double Aplha,double[][] transM ){//計(jì)算旋轉(zhuǎn)點(diǎn)Point3d Vrot = new Point3d();//點(diǎn)乘矩陣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;}示例結(jié)果:
??
點(diǎn)云圖與平面圖對比
參考:各種旋轉(zhuǎn)方式總結(jié).....
????? ? ?? 羅德里格旋轉(zhuǎn)公式....
總結(jié)
以上是生活随笔為你收集整理的三维重建:点绕特定轴旋转公式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Learning Face Age Pr
- 下一篇: 知乎怎么看提问人是谁