我如何在 iOS 5 中使用 CMDeviceMotion 获取设备的标题

2023-11-26

我正在使用陀螺仪开发 AR 应用程序。我使用了苹果代码示例公园。它使用旋转矩阵来计算坐标的位置,而且效果非常好,但现在我正在尝试实现一个“雷达”,我需要根据设备航向来旋转它。我正在使用 CLLocationManager 标题,但它不正确。

问题是,如何使用 CMAttitude 获取设备的方向以准确反映我在屏幕上看到的内容?

我对旋转矩阵之类的东西很陌生。

这是用于计算 AR 坐标的代码的一部分。用态度更新cameraTransform:

CMDeviceMotion *d = motionManager.deviceMotion;
if (d != nil) {
    CMRotationMatrix r = d.attitude.rotationMatrix;
    transformFromCMRotationMatrix(cameraTransform, &r);
[self setNeedsDisplay];
}

然后在drawRect代码中:

mat4f_t projectionCameraTransform;
multiplyMatrixAndMatrix(projectionCameraTransform, projectionTransform, cameraTransform);

int i = 0;
for (PlaceOfInterest *poi in [placesOfInterest objectEnumerator]) {
    vec4f_t v;
    multiplyMatrixAndVector(v, projectionCameraTransform, placesOfInterestCoordinates[i]);

    float x = (v[0] / v[3] + 1.0f) * 0.5f;
    float y = (v[1] / v[3] + 1.0f) * 0.5f;

我还用俯仰角旋转视图。 运动更新从北向开始:

[motionManager startDeviceMotionUpdatesUsingReferenceFrame:CMAttitudeReferenceFrameXTrueNorthZVertical];

所以我认为必须有可能使设备在任何位置(任何俯仰和偏航......)“滚动”/航向,但我不知道如何。


有几种方法可以根据 CMDeviceMotion 返回的旋转矩阵计算航向。假设您使用与 Apple 指南针相同的定义,其中 +y 方向(iPhone 顶部)指向正北返回航向 0,向右旋转 iPhone 会增加航向,因此东为 90,南为 180 ,等等。

首先,当您开始更新时,请务必检查以确保标题可用:

if (([CMMotionManager availableAttitudeReferenceFrames] & CMAttitudeReferenceFrameXTrueNorthZVertical) != 0) {
   ...
}

接下来,当您启动运动管理器时,请求姿态作为从 X 指向真北的旋转(或磁北,如果您出于某种原因需要):

[motionManager startDeviceMotionUpdatesUsingReferenceFrame: CMAttitudeReferenceFrameXTrueNorthZVertical
                                                   toQueue: self.motionQueue
                                               withHandler: dmHandler];

当运动管理器报告运动更新时,您想要了解设备在 X-Y 平面上旋转了多少。由于我们对 iPhone 的顶部感兴趣,因此我们将在该方向上选取一个点,并使用返回的旋转矩阵对其进行旋转,以获得旋转后的点:

   [m11 m12 m13] [0]   [m12]
   [m21 m22 m23] [1] = [m22]
   [m31 m32 m33] [0]   [m32]

时髦的括号是矩阵;这是我能用 ASCII 做的最好的事情了。 :)

航向是旋转点与真北之间的角度。我们可以使用旋转点的 X 和 Y 坐标来提取反正切,从而给出该点与 X 轴之间的角度。这实际上与我们想要的有180度的偏差,因此我们必须进行相应的调整。结果代码如下所示:

CMDeviceMotionHandler dmHandler = ^(CMDeviceMotion *aMotion, NSError *error) {
    // Check for an error.
    if (error) {
        // Add error handling here.
    } else {
        // Get the rotation matrix.
        CMAttitude *attitude = self.motionManager.deviceMotion.attitude;
        CMRotationMatrix rm = attitude.rotationMatrix;

        // Get the heading.
        double heading = PI + atan2(rm.m22, rm.m12);
        heading = heading*180/PI;
        printf("Heading: %5.0f\n", heading);
    }
};

有一个问题:如果 iPhone 的顶部笔直向上或笔直向下,则方向是不确定的。结果是 m21 和 m22 为零或非常接近零。您需要确定这对您的应用意味着什么,并相应地处理这种情况。例如,当 m12*m12 + m22*m22 接近于零时,您可以切换到基于 -Z 轴(iPhone 后面)的航向。


这一切都假设您想要绕 X-Y 平面旋转,就像苹果公司通常对其指南针所做的那样。它之所以有效,是因为您使用运动管理器返回的旋转矩阵来旋转沿 Y 轴指向的向量,即以下矩阵:

[0]
[1]
[0]

要旋转不同的向量(例如,沿着 -Z 的一个向量),请使用不同的矩阵,例如

[0]
[0]
[-1]

当然,你还必须在不同的平面上取反正切,所以而不是

double heading = PI + atan2(rm.m22, rm.m12);

你会用

double heading = PI + atan2(-rm.m33, -rm.m13);

获得 X-Z 平面上的旋转。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

我如何在 iOS 5 中使用 CMDeviceMotion 获取设备的标题 的相关文章

  • 在 Swift 中使用 commitEditingStyle 动态删除 UITable 部分

    我正在处理一个无法解决的问题 我有一个来自客户数据库数组的名称表 每个客户在其他数据成员中都有一个名称属性 我可以成功删除某个部分中的行 但我不能删除该部分 当该部分中的最后一行被删除时 该部分必须消失 I got NSInternalIn
  • 显示器连接或断开连接时的通知

    我正在开发一个 OS X 应用程序 该应用程序在所有连接的显示器的所有可用空间上显示自定义窗口 我可以通过调用 NSScreen Screens 获取可用显示对象的数组 我目前缺少的是一种判断用户是否将显示器连接到系统或从系统断开屏幕的方法
  • 如何在 SQLite 中替换字符串?

    如何更新具有以下内容的表列 var mobile 233KKFSDK3234 Documents Page jpg 并将其替换为 Documents Page jpg 在 SQLite 中 注意 所有文字 除了 Documents 是动态的
  • 以编程方式向 UIButton 标签添加阴影

    我试图向按钮标签添加 1px 黑色阴影 但没有成功 我试过这个 self setTitleShadowOffset CGSizeMake 0 1 但我得到 请求非结构或联合中的成员 setTitleShadowOffset 任何建议都会很棒
  • 检查系统时间是自动还是用户设置

    我需要在当前的项目中设置用户证明时间 我围绕这个问题发现了很多不同的问题 但似乎没有一个问题有我正在寻找的答案 这些是我到目前为止看过的问题 XCODE 如何从设备获取 验证准确的时间戳 https stackoverflow com qu
  • AppDelegate 的变量用作全局变量不起作用

    我想使用我的 AppDelegate 来存储任何其他类都可以访问的对象 我已经像这样声明了这个 AppDelegate interface MyAppDelegate UIResponder
  • CGContextSelectFont 等效项

    在 iOS 7 CGContext SelectFont 中已弃用 已弃用的消息说我必须使用 Core Text 但我不知道哪一个与这段代码完全相同 CGContextSelectFont context Helvetica kBarLab
  • 如何更改便携式 xamarin ios 项目中的启动屏幕?

    我正在使用便携式 xamarin 形式 其中项目是 IOS 项目 在 IOS 项目中 我想创建闪屏 我在 ios 项目属性中添加了 Iphone 启动图像和 iPad 启动图像 当我运行该应用程序时 它显示默认的启动屏幕 我还尝试从 inf
  • iOS 解析如何通过 URL 下载文件

    我正在将 parse 用于我的聊天应用程序 当我上传文件时 我保留该 url 并将该 url 发送给其他用户 然后其他用户可以通过该 URL 下载文件 这是我上传文件的代码 void uploadBlob NSData blob fileN
  • 核心数据:为什么必须调用重新加载数据才能使我的应用程序运行?

    我花了整个晚上调试一个简单的应用程序 该应用程序从网络检索一张图像 是的 是的 旨在让我的生活更轻松 并将其显示在表格视图中 我这样做是为了练习学习核心数据 在我修复它之前 错误消息显示如下 2012 09 30 06 16 12 854
  • ShareKit + Facebook 身份验证不起作用

    我正在使用 ShareKit 从我正在开发的 PhoneGap 应用程序发布到 Facebook 我在 Facebook 中创建了该应用程序 并在我的项目中安装了该插件 Twitter 工作正常 但当我尝试在 Facebook 上分享时出现
  • 将语音添加到自定义 UIMenuController

    我创建了一个自定义UIMenuController in a UIWebView但它似乎摆脱了 说出选择 选项UIMenuController在那之后 所有测试设备上的 偏好设置 中都打开了发言选择选项 并且它出现在其他应用程序中 包括非
  • 如何获取 UITableView 中的所有单元格

    假设我有一个包含多行的 UITableView 我想在某个时间点将所有 UITableViewCells 作为 NSArray 获取 我努力了 tableView visibleCells 但这种方法有一个问题 我无法拥有当前不在当前屏幕中
  • 为每行 NSTableView 文本着色

    我有一个 NSTableView 它显示我拥有的对象数组 对于每个对象 行 我想根据在每个对象上运行的函数的结果来更改显示的文本的颜色 因此 例如表中存在于另一个列表 或其他一些要求 中的所有对象 我想以绿色文本显示它们 不存在的对象以红色
  • 如何从 Firebase 同步检索数据?

    我有两个集合 即用户和问题 根据使用 userId 登录的用户 我检索currQuestion价值来自users收藏 基于currQuestion值 我需要检索question来自 Firebase 的文档Questions收藏 我使用下面
  • 如何将unix时间戳转换为iphone中的nsdate [重复]

    这个问题在这里已经有答案了 可能的重复 从 Unix 时间戳创建 NSDate https stackoverflow com questions 5827240 create nsdate from unix timestamp 我有一个
  • 由于 2.23 导致 iOS 应用程序被拒绝 - iOS 数据存储指南

    以下是 Apple 关于拒绝的消息 2 23 应用程序必须遵循 iOS 数据存储指南 否则将被拒绝 2 23 详情 在启动和内容下载时 您的应用程序会存储 6 5 MB 这并不意味着 遵守 iOS 数据存储指南 下一步 请验证只有用户使用您
  • AVPlayer 不播放音频 - iOS 9,目标 - C

    我正在尝试从我的应用程序中的 URL 播放音频 iOS 8 中一切都按预期发生 模拟器和物理设备 对于 iOS 9 它可以在模拟器中运行 但在设备上 音频根本无法播放 出现流媒体 如果我单击播放 进度条还显示音频正在加载并播放 但没有声音
  • iOS 13 检查 CLLocationManager 的临时授权状态

    根据 WWDC 视频 https developer apple com videos play wwdc2019 705 https developer apple com videos play wwdc2019 705 当你要求 Al
  • 如果加载 dylib,垃圾收集工作队列会崩溃

    我们正在将应用程序从 10 6 移植到 10 8 我正在查看我们在应用程序中加载的 dylib 我面临着非常不寻常的崩溃垃圾收集工作队列并附有以下消息 malloc Thread suspend unable to suspend a th

随机推荐

  • 如何在 Mono For Android 中将位图转换为字节数组

    我正在使用 Mono for Android 我想将位图保存到字节数组 所以我可以将它保存到数据库中 在这里搜索我发现了以下代码 ByteArrayOutputStream bos new ByteArrayOutputStream bit
  • Firebase 查询子级的子级是否包含值

    表的结构是 chats gt 随机ID gt gt 参与者 gt gt gt 0 名称1 gt gt gt 1 名称2 gt gt 聊天项目 etc 我想做的是查询聊天表 以查找通过传入的用户名字符串容纳参与者的所有聊天 这是我到目前为止所
  • Kafka高级消费者使用Java API从主题获取所有消息(相当于--from-beginning)

    我正在使用 Kafka 站点上的 ConsumerGroupExample 代码测试 Kafka High Level Consumer 我想检索 Kafka 服务器配置中有关 测试 主题的所有现有消息 查看其他博客 auto offset
  • 在多个 GridViewColumn 中使用通用 DataTemplate

    我有一个显示一些值的 GridView
  • 跨平台方式检测符号链接/连接点?

    在java中 可以通过比较文件的规范路径和绝对路径来检测Unix环境中的符号链接 然而 这个技巧在 Windows 上不起作用 如果我执行 mkdir c foo mklink j c bar 从命令行 然后在java中执行以下几行 Fil
  • 怪异模式与 2011 年相关吗?

    随着IE9 FF4 不断更新的chrome等所有最新的浏览器 我们还需要怪异模式吗 如果有的话有什么用处 在什么场景下 Quirks 模式旨在允许 很多 较旧的网站在 相对 较新的浏览器中运行 新的开发永远不应该在 Quirks 模式下进行
  • ListView 图像的 onClick 侦听器 - Android

    我有一个ListView右侧有图像 我想表演一个onClick通过单击图像上的侦听器事件ListView 请参阅图片以供参考 我知道基本的OnClick监听器实现 但这对我来说似乎有点棘手 P 忘了说了 点击实际ListView将启动一项新
  • 使用 DbContext.Database.SqlQuery 在 EntityFramework 中进行预加载

    在 EF 4 中 我可以通过编写 sql 来预先加载导航属性吗DbContext Database SqlQuery or DbContext Set
  • 在 Mac OS 10.11 (El Capitan) 上使用 pfctl 转发端口

    我目前正在测试我的开发环境是否可以在即将推出的新 Mac OS 10 11 上运行 以及是否可以在发布后立即升级 在我的测试机器上 我当前正在运行 Beta Preview 3 一切似乎都运行良好 我只能得到pfctl转发我的端口 我使用
  • Angular 模板中的 Javascript 广告

    我正在尝试在 Angular 模板中呈现 Javascript 广告 但它不会显示 当他们将 Javascript 附加到 head 标签时 我找到了一些解决方案 但我希望将广告放置在我的 Html 正文内 中 这是一个笨蛋 https p
  • TestNG 选项未显示在 Eclipse 的 RunAs 选项中

    我在 Eclipse IDE 中使用 Maven 项目 并添加了一个 testng 依赖项
  • 如何使用网络浏览器在链接列表中导航?

    我有一个网址列表 我需要导航它们 如何确保每个 url 都会调用 DocumentCompleted 事件 我已经尝试创建许多线程并尝试使用单个线程 但应用程序仍然没有为每个 url 触发事件 DocumentCompleted 有没有办法
  • 如何在 Release() 上释放 NET COM 互操作对象

    我有一个用托管代码 C CLI 编写的 COM 对象 我在标准 C 中使用该对象 当 COM 对象被释放时 如何强制立即调用 COM 对象的析构函数 如果不可能 请调用 I have Release 在我的 COM 对象上调用 MyDisp
  • 通过 HTTPS 投放广告

    我知道不存在愚蠢的问题 但这是 您可以通过 adsense 或其他完全支持 https 的网站上的其他方式提供基于上下文的广告吗 Update 我们更新了 AdSense 广告代码 现在支持通过安全超文本传输 协议 HTTPS 网页上的安全
  • 使用jquery获取keyup位置[重复]

    这个问题在这里已经有答案了 可能的重复 如何获取文本区域中的插入符位置 如果我在 html textarea 控件中的任何位置键入 我需要获取 keyup 事件的当前位置 例如 Welcome to jQuery 所以我在 欢迎 之后有 表
  • 将本体与 Protege-OWL API 合并

    我使用 protege 创建了两个本体 并保存为 A owl B owl 我知道protege 4 0可以合并很多本体 我想使用protege owl API将本体A owl和B owl合并到C owl 但我不知道该怎么做 你可以帮帮我吗
  • 以最少的配置使用 Unity

    在工作中 我们经常使用Unity 它的工作非常出色 但是您使用它的次数越多 您的配置文件就会增长得越多 运行时问题也会增加得越多 并且您必须为每个测试项目重新创建统一配置的次数就越多 因此 我们最终得到了一个巨大的统一配置部分 必须在多个项
  • 在 Posix 中如何使用 dev_t 类型?

    我追求的是这种类型的含义以及什么接口可以使用它 Posix 规范中解释说dev t用于设备 ID 但是 对于路径所描述的任何对象 可以是文件 目录 fifo 或物理设备 来说 设备 id 意味着什么 例如 调用stat 应为您提供一个包含此
  • 将类添加到单击的元素

    我正在尝试向单击的元素添加一个类 有多个具有唯一 ID 的元素 因此我 不知道 元素的 ID 是什么 我可以使用以下代码的修改版本来实现此目的吗 Jquery document ready function this on click fu
  • 我如何在 iOS 5 中使用 CMDeviceMotion 获取设备的标题

    我正在使用陀螺仪开发 AR 应用程序 我使用了苹果代码示例公园 它使用旋转矩阵来计算坐标的位置 而且效果非常好 但现在我正在尝试实现一个 雷达 我需要根据设备航向来旋转它 我正在使用 CLLocationManager 标题 但它不正确 问