对于一个智能手机的增强现实网络应用程序,当用户将设备握在手中,屏幕处于垂直平面,屏幕顶部向上时,我试图计算指南针的方向。
我已经从http://dev.w3.org/geo/api/spec-source-orientation(参见样例)中获取了建议的公式,并实现了以下函数:
function compassHeading(alpha, beta, gamma) {
var a1, a2, b1, b2;
if ( beta !== 0 || gamma !== 0 ) {
a1 = -Math.cos(alpha) * Math.sin(gamma);
a2 = Math.sin(alpha) * Math.sin(beta) * Math.cos(gamma);
b1 = -Math.sin(alpha) * Math.sin(gamma);
b2 = Math.cos(alpha) * Math.sin(beta) * Math.cos(gamma);
return Math.atan((a1 - a2) / (b1 + b2)).toDeg();
}
else {
return 0;
}
}
而.toDeg()是一个数字对象扩展名http://www.movable-type.co.uk/scripts/latlong.html
/** Converts radians to numeric (signed) degrees */
if (typeof Number.prototype.toDeg == 'undefined') {
Number.prototype.toDeg = function() {
return this * 180 / Math.PI;
};
}
然而,问题是,即使设备(谷歌Galaxy Nexus)被安装为保持静止位置,计算的罗盘航向值也会从-75跳到80。这似乎发生在谷歌Chrome BETA和FF BETA 23中。
有人看到我的方法有错误吗?或者有更可靠的方法来计算罗盘的航向?
4条答案
按热度按时间j2datikz1#
根据规范**中提供的示例,确定罗经航向 * 所需的步骤如下:
alpha
、beta
和gamma
值从度转换为弧度,即alphaRad
、betaRad
和gammaRad
。alphaRad
、betaRad
和gammaRad
(如以下示例代码所示),按照规范中的工作示例计算旋转A(rA
)和旋转B(rB
)分量。compassHeading = Math.atan(rA / rB)
。compassHeading
从弧度转换回度(可选)。下面是用JavaScript实现的规范的工作示例:
您也可以使用view a demo of the code provided above。
截至编写本文件时(2014年2月17日),该文件目前适用于:
其他浏览器尚未符合DeviceOrientation事件规范中描述的DeviceOrientation校准和/或未提供
absolute
DeviceOrientation数据值,因此无法使用不完整的数据确定compassHeading
。nzk0hqpo2#
我也玩过一些DeviceOrientationEvent(可能会采用你的公式...),不时会看到类似的问题。你可能想试试像这个video这样的校准。你可以在YouTube上搜索更多的例子。
7hiiyaii3#
从设备方向事件中获取指南针方向似乎已被弃用,可能是出于隐私原因。您应该查看Geolocation API,它需要权限。事件具有Coordinates.heading。
wlzqhblo4#
2023年答案
由绝对α、β和γ计算罗经航向的公式如下:
上述公式对于零beta和gamma(例如,电话躺在table上)表现良好,并且对于beta=90(例如,保持直立)也有效。
现在是2023年,iOS仍然不支持绝对DeviceOrientationEvent,Android仍然不直接支持指南针,下面的TypeScript代码展示了如何获取两种类型设备的指南针值,你可以通过移除冒号后面的类型说明符将其转换为JavaScript。
测试时,我发现我的Android的绝对(α,β,γ)是非常不准确的(约60度误差α).然而,通过滚动设备周围校准自己,并得到了约5度误差.