2009-06-21 102 views
7

我在3D空间中有一组数据点,这些数据点显然都落在特定的平面上。我使用PCA来计算平面参数。 PCA的第三个分量给出了平面的法向矢量(最弱的分量)。将法向量旋转到轴平面上

接下来我想要做的是将所有点转换到所述平面上并在2D中查看它。

我的想法是做到以下几点:

  • 在飞机上
  • 。减去它找到一个中心点(平均分)从所有数据点来安排他们围绕原点
  • 旋转正常使之成为(0,0,-1)
  • 应用此旋转到所有数据点
  • 使用正交投影(基本上,跳过Z轴)

现在我被困在找到正确的旋转操作。我尝试过使用acos或atan并设置两个旋转矩阵。似乎这两种方法(使用acos,使用atan)给我错误的结果。也许你可以帮助我在这里!

Matlab代码如下:

b = atan(n(1)/n(2)); 
rotb = [cos(b) -sin(b) 0; sin(b) cos(b) 0; 0 0 1]; 
n2 = n * rotb; 
a = atan(n(1)/n(3)); 
rota = [cos(a) 0 sin(a); 0 1 0; -sin(a) 0 cos(a)]; 
n3 = n2 * rotaows: 

我希望n2具有零y分量。但是,该向量(-0.6367,0.7697,0.0467)已经失败。

+0

为什么不简单地在飞机上投影所有的点,然后旋转所有的东西,这样你就可以用他们的xz(或xy)坐标绘制点? – 2009-06-21 14:30:01

+0

或者直接将相机安装在飞机上,直接看相机。 – 2009-06-21 14:31:18

+0

相机的想法是一个很好的想法。将摄像机从原点平面移出距离法线一段距离。然后你将相机指向原点。当然,这假定你有相机投影代码,可以用旋转或矢量来完成。 – Nosredna 2009-06-21 20:34:56

回答

10

如果你有一架飞机,你有一个法向量和一个原点。我根本不会做任何“旋转”。你只是一些远离你的答案的矢量操作。

  • 让我们把你的平面的法向量称为新的z轴。
  • 您可以通过将旧的x轴与新的z轴(您的平面的法线)相交来生成新的y轴。
  • 通过将新z与新y相交来生成新的x轴。
  • 将所有新的轴矢量转换为单位矢量(长度为1)。
  • 对于你所有的点,创建一个从你的新原点到点的矢量(矢量减去点 - plane_origin)。只需点新的x和新的y单位向量,你就可以绘制一对(x,y)!

如果您已经有交叉和点积的产品功能,这只是几行代码。我知道它是有效的,因为我写的大多数3D电子游戏都是这样工作的。

技巧:

  • 注意哪些你的矢量指向方向。如果它们指向错误的方向,则取消合成矢量或更改交叉积的顺序。
  • 如果您的飞机的法线与您的原始x轴完全相同,则会出现问题。
1

如何:

分解法向量成在XY平面上的向量以及Z向量。然后围绕Z轴施加一个旋转,将XY向量与其中一个轴对齐。然后找到法线与Z轴的点积,并旋转沿着哪个X,Y排列。

想法是将法线向量与Z向上对齐,并且通过这样做,您的平面现在是XY平面。

0

尽管当时有一些有趣的反应,这是我们想通了,在等待答案的解决方案:

function roti = magic_cosini(n) 
    b = acos(n(2)/sqrt(n(1)*n(1) + n(2)*n(2))); 
    bwinkel = b * 360/2/pi; 
    if (n(1) >= 0) 
     rotb = [cos(-b) -sin(-b) 0; sin(-b) cos(-b) 0; 0 0 1]; 
    else 
     rotb = [cos(-b) sin(-b) 0; -sin(-b) cos(-b) 0; 0 0 1]; 
    end 
    n2 = n * rotb; 
    a = acos(n2(3)/sqrt(n2(2)*n2(2) + n2(3)*n2(3))); 
    awinkel = a * 360/2/pi; 
    rota = [1 0 0; 0 cos(-a) -sin(-a); 0 sin(-a) cos(-a)]; 
    roti = rotb * rota; 

(它返回一个希望正确双旋转矩阵)

我们有瑕疵之前和固定在这里是尤其。处理X分量的符号,这在余弦计算中没有涉及。这使我们在错误的方向上旋转了一次(以180°角旋转)。

我希望我也会抽出时间来尝试Nosredna的解决方案!避免三角法总是很好的。