【问题标题】:iOS - Calculating distance, azimuth, elevation and relative position (Augmented Reality)iOS - 计算距离、方位角、仰角和相对位置(增强现实)
【发布时间】:2012-12-28 14:23:54
【问题描述】:

我开始构建一个增强现实应用程序,您可以在其中将图像放置在增强现实相机视图的屏幕上,并且它会保持在地球上的那个位置,这样其他拥有相机视图的人就可以过来看到它在增强现实相机视图上。为此,我知道我需要计算某种距离因子以及方位角和仰角。

所以,我已经想出了如何将对象的图形发送到服务器并取回它,但是我怎样才能将它放回其相对于地球的原始位置。我知道我需要计算它:

  • 海拔高度
  • 坐标
  • 方位角
  • 海拔
  • 距离

但是我将如何计算这些并解释它们/将它们拼凑在一起。我希望你明白我的意思。

为了加深您的理解,让我给您一个简短的应用演示:

一个人在他的房子里,他决定将一幅画的图像放在他的一面墙上。他打开默认为增强现实屏幕的应用程序,按下加号按钮并从他的照片库中添加一张图片。在幕后,它将位置和位置数据保存到服务器,使用该应用程序及其增强现实屏幕的人经过,它进入服务器并找到保存在附近的图像,然后下载图像并将其放置在墙,这样其他人在移动它时可以用手机看到它。

我应该采取什么方法来实现这一目标?任何大纲、链接、资源、教程、想法、经验等。谢谢!这是一个通常很难写下来的问题,我希望你能理解。如果没有请告诉我,我会改写。

罗汉

【问题讨论】:

  • 它实际上是根据您当前的位置和目标位置计算投影。您可能会在这里有所了解:github.com/abm-adnan/Radar/blob/master/Radar/Controllers/…
  • @MCKapur 您如何从服务器获取图像的位置数据并将其发送到服务器?就像我知道图像的初始位置一样,如果用户将图像拖动到 AR 屏幕视图中的新位置,现在如何识别图像的新纬度/经度?

标签: iphone objective-c ios xcode augmented-reality


【解决方案1】:

我正在开发两个 AR iOS 应用程序,它们执行以下操作:将方位角(罗盘、水平角)和仰角(陀螺仪、垂直角)转换为 3D 空间中的位置(例如球面到笛卡尔)。

您需要的框架是:

  • 核心位置
  • CoreMotion

获取地理位置(坐标)对于纬度、经度和高度非常简单。您可以在多个在线资源中轻松找到此信息,但这是您拨打startUpdatingLocation 后需要从CLLocationManagerDelegate 拨打的主要电话:

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
    latitude = (float) manager.location.coordinate.latitude;
    longitude = (float) manager.location.coordinate.longitude;
    altitude = (float) manager.location.altitude;
}

获取方位角也很简单,调用startUpdatingHeading后使用与位置相同的委托:

- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading
{
    azimuth  = (float) manager.heading.magneticHeading;
}

高度是从陀螺仪中提取的,它没有委托,但也很容易设置。调用看起来像这样(注意:这适用于我在横向模式下运行的应用,请检查你的):

elevation = fabsf(self.motionManager.deviceMotion.attitude.roll);

最后,您可以将方向坐标转换为 3D 点,如下所示:

- (GLKVector3)sphericalToCartesian:(float)radius azimuth:(float)theta elevation:(float)phi
{
    // Convert Coordinates: Spherical to Cartesian
    // Spherical: Radial Distance (r), Azimuth (θ), Elevation (φ)
    // Cartesian: x, y, z

    float x = radius * sinf(phi) * sinf(theta);
    float y = radius * cosf(phi);
    float z = radius * sinf(phi) * cosf(theta);
    return GLKVector3Make(x, y, z);
}

对于最后一部分,请注意角度和轴的命名约定,因为它们因源而异。在我的系统中,θ是水平面的角度,φ是垂直面的角度,x是左右,y是上下,z是前后。

至于距离,我不确定你是否真的需要使用它,但如果你这样做了,那么只需将它替换为“半径”。

希望有帮助

【讨论】:

  • 谢谢,非常有价值的答案。我会在这方面做更多的事情并回复你。我可能需要距离,所以当你离得更远时我可以缩小图像。但是你是什么意思用它代替“半径”?那会奏效吗?如果可能的话,您能否将我指向使用此/类似代码的资源,以便我可以看到它实际上正在使用中?
  • 我正在使用半径来驱动 3D 对象周围的定向光,因此鉴于您的新信息,我认为半径与您无关。据我了解,您正在寻找的距离将被计算为地球上两点之间的差异,是吗? (如果是这样,我帮不了你!)此外,AR 对应用程序来说相对较新,所以你很难找到很多有用的信息,但我为我的理学硕士论文和目前正在审查的后续应用程序实施了这项技术由苹果。两者都是在过去 6 个月内开发的,我一直在努力寻找相关的代码示例!
  • 定向光是什么意思?我知道它与我无关,但只是问(听起来很酷)......所以我在这里有我的 3d 点,我怎样才能得到我的 3d 点并在该区域/位置上绘制图像?我检索坐标、高度、方位角和仰角,然后如何将其绘制回来?另一件事是,图像可能是屏幕中心的小图像。那么如何将图像绘制回地球上的位置,但也可以绘制到相对于屏幕的位置?还有一个问题,这些计算会非常准确吗?如果我把它拉回来,它会给出准确的位置吗?
  • 另外,如何将 GLKVector3 转换为 NSData 对象?这可能吗?
  • 定向光是一种常见的 3D CG 对象,它非常模拟直射阳光 - 它无限远且仅发射平行光线。听起来你还有很多设计基础需要覆盖,所以除非我开始仔细阅读你的实现和最终目标的细节,否则很难给出更多建议。从个人经验来看,相对于屏幕的位置是最棘手的,并且很大程度上取决于您如何定义比例和距离(例如,用户何时“足够接近”?)。数学就是数学,任何不准确之处都在于传感器:)
【解决方案2】:

斯威夫特 3

陀螺仪代码更新:

import CoreMotion
...
        motionManager.deviceMotionUpdateInterval = 0.1
        motionManager.startDeviceMotionUpdates(to: OperationQueue.current!) { deviceManager, error in
            guard let dm = deviceManager else { return }
            let roll = dm.attitude.roll
            let pitch = dm.attitude.pitch
            let yaw = dm.attitude.yaw

            print("r: \(roll), p: \(pitch), y: \(yaw)")
        }

【讨论】:

  • 方位角呢?
猜你喜欢
  • 1970-01-01
  • 2020-01-17
  • 1970-01-01
  • 1970-01-01
  • 2013-03-07
  • 1970-01-01
  • 2012-12-22
  • 2013-11-05
  • 1970-01-01
相关资源
最近更新 更多