动画方向箭头“围绕我”样式使用ngCordova

Animated directional arrows "aroundMe" style using ngCordova

本文关键字:围绕我 样式 ngCordova 方向 动画      更新时间:2023-09-26

我希望创建与我们在AroundMe移动应用程序中看到的指南针/箭头完全相同的指南针/箭头,该指南针/箭头与我的移动位置相应地精确指向地图上的图钉,并在移动手机时更新箭头。

我越来越想确切地了解如何做到这一点,但我找不到任何指南或教程来解释它。

在网上找到的是一个轴承函数,我围绕它创建了一个指令:

app.directive('arrow', function () {
    function bearing(lat1, lng1, lat2, lng2) {
      var dLon = (lng2 - lng1);
      var y = Math.sin(dLon) * Math.cos(lat2);
      var x = Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(dLon);
      var rad = Math.atan2(y, x);
      var brng = toDeg(rad);
      return (brng + 360) % 360;
    }
    function toRad(deg) {
      return deg * Math.PI / 180;
    }
    function toDeg(rad) {
      return rad * 180 / Math.PI;
    }
    return {
    restrict: 'E',
    link: function (scope, element, attrs) {
      var arrowAngle = bearing(scope.user.position.lat, scope.user.position.lng, attrs.lat, attrs.lng);
      element.parent().css('transform', 'rotate(' + arrowAngle + 'deg)');
    }
  };
});

它似乎在某个方向上更新箭头,但不幸的是它不是正确的方向,因为它不是使用移动magneticHeading位置计算的。

所以我为设备定向添加了ngCordova插件来获取magneticHeading,现在我不知道如何使用它以及在bearing函数中的位置。

  $cordovaDeviceOrientation.getCurrentHeading().then(function(result) {
    var magneticHeading = result.magneticHeading;
    var arrowAngle = bearing(scope.user.position.lat, scope.user.position.lng, attrs.lat, attrs.lng, magneticHeading);
    element.parent().css('transform', 'rotate(' + arrowAngle + 'deg)');
  });

我试图在返回语句中添加它:

return (brng - heading) % 360;

或:

return (heading - ((brng + 360) % 360));

使用观察程序实现此代码,我看到箭头在移动,但不在确切的位置......例如,从我的位置和图钉来看,箭头应该指向 N,它指向 E

总是在网上寻找,我找不到任何教程/问题来找到lat/lng pointmagnetingHeading之间的方位。

也许我已经接近解决方案,但我不能独自前进。

我也试图搜索数学公式,但即使理解和实施它也是一个巨大的痛苦。

希望你能帮上忙。

这个问题很难给出一个简单的答案,因为很大程度上取决于实际的图形表示。例如,您指向哪个方向rotate(0deg)

我可以解释您找到的公式,这可能有助于您自己解决问题。困难的部分如下:

  var dLon = (lng2 - lng1);
  var y = Math.sin(dLon) * Math.cos(lat2);
  var x = Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(dLon);
  var rad = Math.atan2(y, x);

你在这里看到的是哈弗西斯公式(https://en.wikipedia.org/wiki/Haversine_formula(。通常,两组坐标就足够了,并计算它们之间的角度。当使用纬度和经度时,这将不起作用,因为地球不是一个平坦的表面。前三条线是哈弗正,结果(xy(是unit circle上的坐标(https://en.wikipedia.org/wiki/Unit_circle(

下一步是计算从这个单位圆上的点到中心的角度。我们可以为此使用arctangant。Javascript有一个帮助程序函数atan2它简化了这个过程。结果很简单,即您的点朝向圆心的角度。换句话说,您对兴趣点的立场。结果以弧度为单位,需要转换为度数。(https://en.wikipedia.org/wiki/Atan2(

具有平面坐标系的简化版本如下所示:

var deltaX = poi.x - you.x;
var deltaY = you.y - poi.y;
var rotation = toDeg(Math.atan2(deltaX, deltaY));
bearingElement.css('transform', 'rotate(' + rotation + 'deg)');

poi是兴趣点,you是您的位置。

为了补偿自己的旋转,您需要减去自己的旋转。在上面的示例中,结果将变为:

var deltaX = poi.x - you.x;
var deltaY = you.y - poi.y;
var rotation = toDeg(Math.atan2(deltaX, deltaY));
rotation -= you.rotation;
bearingElement.css('transform', 'rotate(' + rotation + 'deg)');

我做了一个Plunckr,你可以在其中看到一个简单的平面坐标系。您可以移动和旋转youpoint of interest。"你"里面的箭头总是指向poi,即使你旋转"你"。这是因为我们补偿了自己的轮换。

https://plnkr.co/edit/OJBGWsdcWp3nAkPk4lpC?p=preview

请注意,在 Plunckr 中,"零"位置始终在北方。检查您的应用以查看您的"零"位置。相应地调整它,您的脚本将起作用。

希望这有帮助:-(