作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我希望能够更改设备运动管理器引用系(对于陀螺仪),以便我的重力矢量位于 Y 轴上。
通常,当您启动设备运动管理器更新时,您只会使手机的 z 轴与重力对齐。
您可以更改此设置以使用磁力计使 x 轴与磁北极或真北极对齐。这样我的 X 轴就指向北,Z 轴就指向下。
我想要做的是让我的 Y 轴(负)指向下(以便它与重力对齐),并且让我的 X 轴指向真正的磁极。
我想要的结果是,当我的手机以垂直(纵向)方向静止时,手机的右侧将与北极对齐,并且我的所有读数(滚动、俯仰、偏航)将读取为 0 。然后,如果我在 X 轴上旋转手机,俯仰角就会改变,如果我绕 Y 轴旋转,偏航就会改变。
到目前为止,我知道如果我乘以先前存储的态度的倒数,我可以设置自己的引用系(就像我可以手动将手机设置在这个方向,保存该态度并简单地继续乘以新态度)通过与此存储的相反,我的所有读数将与我想要的完全一样)。
但是手动设置它不是一个选项,那么我如何以编程方式进行此设置?
我不认为有一个函数可以创建我自己的姿态引用系,或者如果至少有一个函数可以将姿态乘以旋转矩阵,那么我可能可以解决这个问题。 (因为我只是将所有姿态乘以 90 度的音高变化)。
我希望我能清楚地解释自己,
我将不胜感激任何建议。谢谢
PD:这些是 iPhone 方向坐标:
最佳答案
伪代码:
这是代码:
- (void) initMotionCapture
{
firstGravityReading = NO;
referenceAttitude = nil;
if (motionManager == nil)
{
self.motionManager = [CMMotionManager new];
}
motionManager.deviceMotionUpdateInterval = 0.01;
self.gravityTimer = [NSTimer scheduledTimerWithTimeInterval:1/60.0
target:self
selector:@selector(getFirstGravityReading)
userInfo:nil repeats:YES];
}
- (void) getFirstGravityReading
{
CMAcceleration currentGravity;
CMDeviceMotion *dm = motionManager.deviceMotion;
referenceAttitude = dm.attitude;
currentGravity = dm.gravity;
[motionManager startDeviceMotionUpdates];
if (currentGravity.x !=0 &&
currentGravity.y !=0 && currentGravity.z !=0)
{
NSLog(@"Gravity = (%f,%f,%f)",
currentGravity.x, currentGravity.y, currentGravity.z);
firstGravityReading = YES;
[gravityTimer invalidate];
self.gravityTimer = nil;
[self setupCompass];
}
}
- (void) setupCompass
{
//Draw your cube... I am using a quartz 3D perspective hack!
CATransform3D initialTransform = perspectiveTransformedLayer.sublayerTransform;
initialTransform.m34 = 1.0/-10000;
//HERE IS WHAT YOU GUYS NEED... the vector equations!
NSLog(@"Gravity = (%f,%f,%f)",
currentGravity.x, currentGravity.y, currentGravity.z);
//we have current gravity vector and our device gravity vector of (0, 0, -1)
// get the dot product
float dotProduct = currentGravity.x*0 +
currentGravity.y*0 +
currentGravity.z*-1;
float innerMagnitudeProduct = currentGravity.x*currentGravity.x +
currentGravity.y + currentGravity.y +
currentGravity.z*currentGravity.z;
float magnitudeCurrentGravity = sqrt(innerMagnitudeProduct);
float magnitudeDeviceVector = 1; //since (0,0,-1) computes to: 0*0 + 0*0 + -1*-1 = 1
thetaOffset = acos(dotProduct/(magnitudeCurrentGravity*magnitudeDeviceVector));
NSLog(@"theta(degrees) = %f", thetaOffset*180.0/M_PI);
//Now we have the device angle to the gravity vector (0,0,-1)
//We must transform these coordinates to match our
//device's attitude by transforming to theta prime
float theta_deg = thetaOffset*180.0/M_PI;
float thetaPrime_deg = -theta_deg + 90; // ThetaPrime = -Theta + 90 <==> y=mx+b
NSLog(@"thetaPrime(degrees) = %f", thetaOffset*180.0/M_PI);
deviceOffsetRotation =
CATransform3DMakeRotation((thetaPrime_deg) * M_PI / 180.0, 1, 0, 0);
initialTransform = CATransform3DConcat(deviceOffsetRotation, initialTransform);
perspectiveTransformedLayer.sublayerTransform = initialTransform;
self.animationTimer = [NSTimer scheduledTimerWithTimeInterval:1/60.0
target:self
selector:@selector(tick)
userInfo:nil
repeats:YES];
}
- (void) tick
{
CMRotationMatrix rotation;
CMDeviceMotion *deviceMotion = motionManager.deviceMotion;
CMAttitude *attitude = deviceMotion.attitude;
if (referenceAttitude != nil)
{
[attitude multiplyByInverseOfAttitude:referenceAttitude];
}
rotation = attitude.rotationMatrix;
CATransform3D rotationalTransform = perspectiveTransformedLayer.sublayerTransform;
//inverse (or called the transpose) of the attitude.rotationalMatrix
rotationalTransform.m11 = rotation.m11;
rotationalTransform.m12 = rotation.m21;
rotationalTransform.m13 = rotation.m31;
rotationalTransform.m21 = rotation.m12;
rotationalTransform.m22 = rotation.m22;
rotationalTransform.m23 = rotation.m32;
rotationalTransform.m31 = rotation.m13;
rotationalTransform.m32 = rotation.m23;
rotationalTransform.m33 = rotation.m33;
rotationalTransform =
CATransform3DConcat(deviceOffsetRotation, rotationalTransform);
rotationalTransform =
CATransform3DConcat(rotationalTransform,
CATransform3DMakeScale(1.0, -1.0, 1.0));
perspectiveTransformedLayer.sublayerTransform = rotationalTransform;
}
关于iphone - 如何创建新的CMAttitude引用系以使重力位于Y轴上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8663507/
我是一名优秀的程序员,十分优秀!