2

我正在使用 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 函数来完成,但我不知道如何实现。

最好的

西蒙

4

1 回答 1

1

我从来没有用过ofxopeni,但这是我能给出的最好的数学解释。

您可以使用 TBN 矩阵(切线、双切线、法线)将任何一组数据从一个轴组旋转到另一个轴组,其中 TB 和 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。

编辑:最终矩阵计算略有错误。固定的。

TBN 计算。

于 2011-08-18T00:37:54.960 回答