查找iOS设备的法线向量 [英] Finding normal vector to iOS device

查看:176
本文介绍了查找iOS设备的法线向量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用CMAttitude来了解垂直于iPad / iPhone屏幕玻璃的矢量(相对于地面)。因此,我会得到如下矢量:

I would like to use CMAttitude to know the vector normal to the glass of the iPad/iPhone's screen (relative to the ground). As such, I would get vectors like the following:

请注意,这与方向不同,因为我不关心设备如何围绕z轴旋转。因此,如果我把iPad放在我的头顶朝下,它会读取(0,-1,0),即使我将它旋转到我头顶上方(如直升机),它仍将继续读取(0, - 1,0):

Notice that this is different from orientation, in that I don't care how the device is rotated about the z axis. So if I was holding the iPad above my head facing down, it would read (0,-1,0), and even as I spun it around above my head (like a helicopter), it would continue to read (0,-1,0):

我觉得这可能很简单,但由于我是四元数的新手并且没有完全理解设备运动的参考框架选项,它一直在回避我一天。

I feel like this might be pretty easy, but as I am new to quaternions and don't fully understand the reference frame options for device motion, its been evading me all day.

推荐答案


  1. 在你的情况下,我们可以说设备的旋转等于旋转设备正常(正常情况下的旋转就像你指定的那样被忽略)

  2. CMAttitude ,您可以通过
    CMMotionManager.deviceMotion 提供相对于参考框架的旋转
    。它的属性四元数,旋转
    矩阵和欧拉角只是不同的表示。

  3. 当你使用CMMotionManager的 startDeviceMotionUpdatesUsingReferenceFrame 方法。在iOS 4之前,您必须使用 multiplyByInverseOfAttitude

  1. In your case we can say rotation of the device is equal to rotation of the device normal (rotation around the normal itself is just ignored like you specified it)
  2. CMAttitude which you can get via CMMotionManager.deviceMotion provides the rotation relative to a reference frame. Its properties quaternion, roation matrix and Euler angles are just different representations.
  3. The reference frame can be specified when you start device motion updates using CMMotionManager's startDeviceMotionUpdatesUsingReferenceFrame method. Until iOS 4 you had to use multiplyByInverseOfAttitude

将这些放在一起你只需要乘以<中的四元数当设备面朝上放在桌子上时,使用法线向量的em>正确方式。现在我们需要这个正确方法表示旋转的四元数乘法:根据旋转向量这可以通过以下方式完成:

Putting this together you just have to multiply the quaternion in the right way with the normal vector when the device lies face up on the table. Now we need this right way of quaternion multiplication that represents a rotation: According to Rotating vectors this is done by:

n = q * e * q'其中 q 是由CMAttitude [w,(x,y,z)]传递的四元数, q'是它的共轭[w,( - x,-y,-z)]和 e 是正面朝向[0,(0,0,1)]的四元数表示。不幸的是,Apple的CMQuaternion是struct,因此你需要一个小帮手类。

n = q * e * q' where q is the quaternion delivered by CMAttitude [w, (x, y, z)], q' is its conjugate [w, (-x, -y, -z)] and e is the quaternion representation of the face up normal [0, (0, 0, 1)]. Unfortunately Apple's CMQuaternion is struct and thus you need a small helper class.

Quaternion e = [[Quaternion alloc] initWithValues:0 y:0 z:1 w:0];
CMQuaternion cm = deviceMotion.attitude.quaternion;
Quaternion quat = [[Quaternion alloc] initWithValues:cm.x y:cm.y z:cm.z w: cm.w];
Quaternion quatConjugate = [[Quaternion alloc] initWithValues:-cm.x y:-cm.y z:-cm.z w: cm.w];
[quat multiplyWithRight:e];
[quat multiplyWithRight:quatConjugate];
// quat.x, .y, .z contain your normal

Quaternion.h :

Quaternion.h:

@interface Quaternion : NSObject {
    double w;
    double x;
    double y;
    double z;
}

@property(readwrite, assign)double w;
@property(readwrite, assign)double x;
@property(readwrite, assign)double y;
@property(readwrite, assign)double z;

Quaternion.m:

Quaternion.m:

- (Quaternion*) multiplyWithRight:(Quaternion*)q {
    double newW = w*q.w - x*q.x - y*q.y - z*q.z;
    double newX = w*q.x + x*q.w + y*q.z - z*q.y;
    double newY = w*q.y + y*q.w + z*q.x - x*q.z;
    double newZ = w*q.z + z*q.w + x*q.y - y*q.x;
    w = newW;
    x = newX;
    y = newY;
    z = newZ;
    // one multiplication won't denormalise but when multipling again and again 
    // we should assure that the result is normalised
    return self;
}

- (id) initWithValues:(double)w2 x:(double)x2 y:(double)y2 z:(double)z2 {
        if ((self = [super init])) {
            x = x2; y = y2; z = z2; w = w2;
        }
        return self;
}

我知道四元数在开始时有点奇怪但是一旦你有了他们真的很棒。它帮助我将四元数想象为围绕向量(x,y,z)的旋转,并且w是角度的(余弦)。

I know quaternions are a bit weird at the beginning but once you have got an idea they are really brilliant. It helped me to imagine a quaternion as a rotation around the vector (x, y, z) and w is (cosine of) the angle.

如果您需要对它们进行更多操作,请查看 cocoamath 开源项目。 Quaternion类及其扩展QuaternionOperations是一个很好的起点。

If you need to do more with them take a look at cocoamath open source project. The classes Quaternion and its extension QuaternionOperations are a good starting point.

为了完整起见,是的,您也可以使用矩阵乘法:

For the sake of completeness, yes you can do it with matrix multiplication as well:

n = M * e

但我更喜欢四元数方式它可以为您节省所有三角函数麻烦和表现更好。

But I would prefer the quaternion way it saves you all the trigonometric hassle and performs better.

这篇关于查找iOS设备的法线向量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆