1

我正在尝试确定一个 3d 矢量来Vector3表示我的手机方向而没有角度。我正在寻找的是像射线一样从手机背面发出的向量,基本上是手机的法线向量。

我知道四元数给了我一个转变,但是到什么?

此外,我发现Quaternion.ToAxisAngle()将四元数转换为轴及其各自的滚动角。我想,太好了,这就是我需要的,我可以忽略角度。

当手机放在桌子上时,我得到以下轴:

axis = [0,0,-1]

而角度基本上代表了指南针的角度。在那种特殊情况下,这就是我所期望的。但是当手机具有不同的任意空间位置时,轴似乎不再是手机的法线向量。

如何计算手机平面的法线向量?

4

1 回答 1

5

“一切都是相对的”

因此,您需要做的是保存一个四元数并将其用作原点(也称为 call centre),然后您可以定位任何新的四元数以确定发生了哪些方向变化。

校准

可以通过告诉用户保持手机稳定然后对四元数流进行采样和去抖动并在一段时间内对它们进行平均来执行校准。但是对于这个例子。只需将设备放在桌子上,屏幕向上,然后再启动应用程序,然后获取第一个示例(不是很好,但它可以快速运行)。

注意: System.Reactive observable 非常适合采样和去抖动

注意:将此四元数存储为其倒数 ( Quaternion.Inverse),因为您必须对每个样本执行更少的计算。

计算每个样本的差异:

您想将当前采样的四元数乘以原点/中心(以逆形式)。

注意:请记住,乘法与四元数不可交换,因此顺序很重要(!)

var currentQ = e.Reading.Orientation;
var q = Quaternion.Multiply(originQ, currentQ);

转换本地化的四元数

所以现在你有一个本地化的四元数,你可以将它转换为 Vector3(通过基本向量(向上、向前、向下,...)转换它或获得一些欧拉角或......

例子:

因此,使用 Xamarin Essentials 示例,这就是我将如何更改OrientationSensor_ReadingChanged事件作​​为一个非常简单的示例。

注意:采样事件被称为 A LOT 取决于设备,并且SensorSpeed对于控制输出速率实际上没有用。如果您直接尝试使用这些示例更新屏幕(以一对一的方式),您可能会遇到严重的问题(Mono 垃圾收集器几乎无法跟上更新 UI 时创建的字符串的 GC (观察应用程序输出,GC 循环不断发生,即使SensorSpeed.UI设置了。)我使用 Reactive Observables 来平滑样本并将传感器输出限制在合理的更新周期(16ms 或更多)之前更新 UI。

void OrientationSensor_ReadingChanged(object sender, OrientationSensorChangedEventArgs e)
{
    if (originQ == Quaternion.Identity) // auto-origin on first sample or when requested
    {
        originQ = Quaternion.Inverse(e.Reading.Orientation);
    }

    var q = Quaternion.Multiply(originQ, e.Reading.Orientation);

    GetEulerAngles(q, out yaw, out pitch, out roll); // assuming "right-hand" orientation

    SmoothAndThrottle(yaw, pitch, roll, () =>
    {
        Device.BeginInvokeOnMainThread(() =>
        {
            pitchLabel.Text = pitch.ToString();
            rollLabel.Text = roll.ToString();
            yawLabel.Text = yaw.ToString();

            // This will appear to keep the image aligned to the origin/centre.
            direction.RotateTo(90 * yaw, 1);
            direction.RotationX = 90 * pitch;
            direction.RotationY = -90 * roll;
        });
    });
}

注意:只需将您最喜欢的四元数转换为欧拉角例程(如果需要,还可以编写一个平滑和节流例程)。

输出:

在此处输入图像描述

于 2019-02-06T04:09:04.977 回答