我正在使用kinect和ofxopeni。我在实际坐标中有一个点云,但我需要旋转这些点以抵消相机的倾斜。地板平面应该能够提供我需要的所有信息,但我无法确定如何计算轴和旋转角度。
我最初的想法是......
ofVec3f target_normal(0,1,0);
ofVec3f vNormal; //set this from Xn3DPlane floorPlane (not shown here)
ofVec3f ptPoint; //as above
float rot_angle = target_normal.angle(vNormal);
for(int i = 0; i < numPoints; i++){
cloudPoints[i].rotate(rot_angle, vNormal, ptPoint); //align my points to normal is (0 1 0)
}
到目前为止,这似乎过于简单了。我一直在钓鱼各种文章,可以看到它很可能涉及四分之一或旋转矩阵,但我无法找到从哪里开始。我真的很感激任何相关文章的指示或获得轴和旋转角度的最佳技巧是什么?我想象使用ofQuarterion或openni函数可以很容易地完成它,但我无法弄清楚如何实现。
最好
西蒙
答案 0 :(得分:1)
我从未使用过xopeni,但这是我能给出的最好的数学解释。
您可以使用TBN矩阵(切线,比特,正常)将任何一组数据集从一个轴设置旋转到另一个轴,其中T B和N是您的新轴组。因此,您已经拥有正常数据,但您需要找到切线。我不确定你的Xn3DPlane是否提供切线,但如果确实如此,请使用它。
比特正是由法线和切线的交叉积给出的:
B = T x N
TBN看起来像这样:
TBN = { Tx ,Ty ,Tz,
Bx, By, Bz,
Nx, Ny, Nz }
这将在一组新的轴上旋转您的数据,但您的平面也有一个原点,所以我们通过翻译:
A = {1 , 0 , 0, 0, { Tx , Ty , Tz , 0,
0, 1, 0, 0, Bx , By , Bz , 0,
0, 0, 1, 0, x Nx , Ny , Nz , 0,
-Px,-Py,-Pz,1} 0 , 0 , 0 , 1}
// The multiply the vertex, v, to change it's coordinate system.
v = v * A
如果你可以把事情发展到这个阶段,你可以将你的所有点转换为新的坐标系。有一点需要注意,正常现在与z轴对齐,如果你想让它与y对齐,在TBN矩阵中交换N和B.
编辑:最终矩阵计算略有错误。固定的。