我正在使用 iPhone ARToolkit,我想知道它是如何工作的。
我想知道如何使用目的地位置、用户位置和指南针,这个工具包可以知道用户正在寻找那个目的地。
我怎么知道这个计算背后的数学?
我正在使用 iPhone ARToolkit,我想知道它是如何工作的。
我想知道如何使用目的地位置、用户位置和指南针,这个工具包可以知道用户正在寻找那个目的地。
我怎么知道这个计算背后的数学?
AR ToolKit 使用的数学是基本的三角函数。它没有使用 Thomas 所描述的技术,我认为这是一种更好的方法(除了第 5 步。见下文)
iPhone 的 GPS 提供设备的位置,您已经有了想要查看的位置的坐标。
首先,它计算两点的纬度和经度值之间的差异。这两个差异测量意味着您可以构建一个直角三角形并计算另一个给定位置与当前位置的角度。这是相关代码:
- (float)angleFromCoordinate:(CLLocationCoordinate2D)first toCoordinate:(CLLocationCoordinate2D)second {
float longitudinalDifference = second.longitude - first.longitude;
float latitudinalDifference = second.latitude - first.latitude;
float possibleAzimuth = (M_PI * .5f) - atan(latitudinalDifference / longitudinalDifference);
if (longitudinalDifference > 0) return possibleAzimuth;
else if (longitudinalDifference < 0) return possibleAzimuth + M_PI;
else if (latitudinalDifference < 0) return M_PI;
return 0.0f;
}
此时,您可以从手机中读取罗盘值并确定您的设备指向的特定罗盘角度(方位角)。指南针的读数将是直接位于相机视野中心的角度。然后,当 iPhone 的视野已知时,AR ToolKit 会计算屏幕上当前显示的完整角度范围。
特别是它通过计算视图最左边部分的角度来实现这一点:
double leftAzimuth = centerAzimuth - VIEWPORT_WIDTH_RADIANS / 2.0;
if (leftAzimuth < 0.0) {
leftAzimuth = 2 * M_PI + leftAzimuth;
}
然后计算最右边:
double rightAzimuth = centerAzimuth + VIEWPORT_WIDTH_RADIANS / 2.0;
if (rightAzimuth > 2 * M_PI) {
rightAzimuth = rightAzimuth - 2 * M_PI;
}
我们现在有:
这足以在屏幕上的正确位置绘制一个标记(有点……见下面的问题部分)
它还进行与设备倾斜度相关的类似计算,因此如果您仰望天空,您希望不会在上面看到城市标记,如果您将其指向您的脚下,理论上您应该会看到地球另一侧的城市。但是,此工具包中的这些计算存在问题。
设备定位不完美
我刚刚解释的计算值假设您将设备保持在相对于地球的精确位置。即完美的风景或肖像。您的用户可能不会一直这样做。如果您稍微倾斜设备,您的水平线在屏幕上将不再是水平的。
地球实际上是3D的!
地球是三维的。工具包中的计算很少考虑到这一点。只有当您将设备指向地平线时,它执行的计算才会真正准确。
例如,如果您尝试在地球的另一侧(就在您的脚下)绘制一个点,则此工具包的行为非常奇怪。用于计算屏幕方位角范围的方法仅在查看地平线时有效。如果您将相机对准地板,您实际上可以看到每个指南针点。但是,该工具包认为您仍然只查看compass reading ± (width of view / 2)
. 如果您在原地旋转,您会看到标记移动到屏幕边缘,消失然后重新出现在另一侧。您希望看到的是标记在您旋转时停留在屏幕上。
我最近用 AR 实现了一个应用程序,我最初希望 AR Toolkit 能为我完成繁重的工作。我遇到了刚刚描述的问题,这些问题对于我的应用程序来说是不可接受的,所以我不得不自己动手。
Thomas 的方法在第 5 点之前是一个很好的方法,正如我上面解释的那样,它仅在指向地平线时才有效。如果您需要绘制除此之外的任何内容,它就会崩溃。在我的情况下,我必须绘制开销的对象,所以它完全不合适。
我通过使用 OpenGL ES 在 3D 空间中绘制我的标记来解决这个问题,并根据陀螺仪的读数移动 OpenGL 视口,同时不断地重新校准指南针。3D 引擎处理所有确定屏幕内容的繁重工作。
希望这足以让你开始。我希望我能提供比这更多的细节,但没有发布很多我不能发布的 hacky 代码。然而,这种方法确实解决了上述两个问题。我希望在某个时候开源我的那部分代码,但它非常粗糙并且目前与我的问题域耦合。
编辑:计算:(这只是一个想法:可能存在没有很多坐标变换的更好的解决方案)
atan2(deast, dnorth)
dest_angle - 10° <= compass_angle <= dest_angle + 10°
10°
只是一个猜测值。您应该尝试一些值以找出有用的值,或者您必须分析 iPhone 相机的某些属性。如果假设地球是球体而不是椭球体,坐标变换方程会变得简单得多。如果有 postet 的大多数链接都假设 wgs-84 椭球,因为 gps 也可以做 afaik)。