【问题标题】:Using Rotation Matrix to rotate points in space使用旋转矩阵旋转空间中的点
【发布时间】:2014-11-30 13:30:47
【问题描述】:

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

工作至今

我首先从SensorManager.getRotationMatrix 函数中读取矩阵。接下来,我使用this link 中给出的解释将旋转矩阵转换为四元数。我这样做是因为我读到欧拉角会导致万向节锁定问题,并且使用 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 和 原始的 3 × 1 列矩阵表示 v→。这需要 3 × (3 乘法 + 2 次加法)= 9 次乘法和 6 次加法, 旋转矢量的最有效方法。

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

【问题讨论】:

    标签: android matrix rotation quaternions


    【解决方案1】:

    由于没有人回答,所以我在这里回答自己。

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

    • 旋转矩阵 - 9 次乘法和 6 次加法
    • 四元数 - 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;
      }
    

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

    【讨论】:

    • 它有更好的解决方案。您还在寻找解决方案吗?
    • 不,我已经离开了这个项目 :) 我最终选择了不同的方法
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-09-30
    • 1970-01-01
    • 2012-08-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多