使用旋转矩阵旋转空间中的点

时间:2014-10-06 09:47:06

标签: android matrix rotation quaternions

我正在使用android的旋转矩阵来旋转空间中的多个点。

到目前为止工作

我首先从SensorManager.getRotationMatrix函数中读取矩阵。接下来,我使用this link中给出的解释将旋转矩阵转换为四元数。我这样做是因为我读到Euler角度会导致Gimbal锁定问题,并且使用3x3矩阵的操作可能是详尽无遗的。 source

问题

现在我想要做的是:想象一下手机是参考的起源并给出一组点(投影的lat / lng坐标到xyz坐标系见方法下面)我想要的旋转它们,以便我可以检查哪些是我的视线。为此,我使用this SO question返回X和Y(分别为左和上)来显示屏幕上的点。它工作正常,但只有在面向北方时才有效(因为它没有考虑方向,我的投影向量使用北/南为X,东/西为Z)。所以我的想法是旋转所有对象。即使初始高度(Y)为0,我也希望能够根据手机的方向上/下定位点。

我认为部分解决方案可能在this post。但由于这使用欧拉角,我不认为这是最好的方法。

结论

那么,如果旋转每个点的位置真的更好,我怎样才能使用旋转四元数来存档?否则哪种方式更好?

如果我在这篇文章中说错了,我很抱歉。我不擅长物理学。

代码

//this functions returns a 3d vector (0 for Y since I'm discarding altitude) using 2 coordinates
public static float[] convLocToVec(LatLng source, LatLng destination)
{
    float[] z = new float[1];
    z[0] = 0;
    Location.distanceBetween(source.latitude, source.longitude, destination
            .latitude, source.longitude, z);
    float[] x = new float[1];
    Location.distanceBetween(source.latitude, source.longitude, source
            .latitude, destination.longitude, x);
    if (source.latitude < destination.latitude)
        z[0] *= -1;
    if (source.longitude > destination.longitude)
        x[0] *= -1;

    return new float[]{x[0], (float) 0, z[0]};
}

感谢您的帮助,祝您度过愉快的一天。


更新1

根据Wikipedia

  

计算3×3旋转矩阵R和矩阵乘积的矩阵乘积   表示v→的原始3×1列矩阵。这需要3×(3   乘法+ 2次加法)= 9次乘法和6次加法,   旋转矢量的最有效方法。

我真的应该使用旋转矩阵来旋转矢量吗?

1 个答案:

答案 0 :(得分:0)

因为没有人回答我在这里回答自己。

经过一些研究(实际上很多)我得出结论是的,可以使用四元数旋转矢量,但最好将它转换为旋转矩阵。< / p>

  • 旋转矩阵 - 9次乘法和6次加法
  • Quartenion - 15次乘法和15次加法

来源:Performance comparisons

最好使用Android提供的旋转矩阵。此外,如果您打算以某种方式使用四元数(例如Sensor.TYPE_ROTATION_VECTOR + SensorManager.getQuaternionFromVector),您可以(并且应该)将其转换为旋转矩阵。您可以使用方法SensorManager.getRotationMatrixFromVector将旋转矢量转换为矩阵。获得旋转矩阵后,您只需将其乘以所需的投影向量即可。您可以使用此功能:

 public float[] multiplyByVector(float[][] A, float[] x) {
        int m = A.length;
        int n = A[0].length;
        if (x.length != n) throw new RuntimeException("Illegal matrix dimensions.");
        float[] y = new float[m];
        for (int i = 0; i < m; i++)
            for (int j = 0; j < n; j++)
                y[i] += (A[i][j] * x[j]);
        return y;
  }

虽然我仍然无法正常运行,但我会将其标记为答案。