在 LatLng 坐标系中旋转对象

Rotate a object in LatLng coordinate system

嘿,我正在尝试在 latlng 系统中围绕它自己的中心旋转一条线。

我得到了角度和两个点。所以我尝试像这样附加旋转矩阵(以下方法采用点的纬度和经度以及角度):

 LatLng rotate(double lat, double long, double angle){
   double rad = angle*pi/180;
   double newLong = long*cos(rad)-lat*sin(rad);
   double newLat = long* sin(rad) + lat*cos(rad);

  return LatLng(newLat,newLong);

  }

例如我得到了点A(纬度:x,经度:y)和点B(纬度:x,经度:y)。连接这两点导致一条线。现在我想用上面的方法围绕它自己的中心旋转两个线,通过调用:

LatLng newA = rotate(A.latitude,A.longitude);
LatLng newB = rotate(B.latitude,B.longitude);

但是当我连接newA和NewB这两个点时,并没有达到预期的效果。

正如@Abion47 在他的回答中阐明的那样,我需要在 3 维空间中进行旋转,但该怎么做呢?如果它是一条非常小的线,是否可以使用二维?

这就是问题所在。我之前提到的问题是,经纬度对是一对角度,而不是图形上一个点的二维向量,因此尝试使用它们在 3D space 的表面上旋转一个点sphere 将 运行 变成它自己的问题。然而,事实证明,只要您不选择穿过国际日期变更线或两极的点,您仍然可以通过假装角度对是二维向量来使用这个技巧。

真正的问题是您想要围绕中点旋转这些点,但您的数学只是执行直线旋转,这将使它们围绕原点旋转(即 0,0)。您需要用您用作参考的点来抵消您的“点数”。

import 'dart:math';

LatLng rotate(LatLng coord, LatLng midpoint, double angle) {
  // Make this constant so it doesn't have to be repeatedly recalculated
  const piDiv180 = pi / 180;

  // Convert the input angle to radians
  final r = angle * piDiv180;

  // Create local variables using appropriate nomenclature
  final x = coord.longitude;
  final y = coord.latitude;
  final mx = midpoint.longitude;
  final my = midpoint.latitude;
  
  // Offset input point by the midpoint so the midpoint becomes the origin
  final ox = x - mx;
  final oy = y - my;

  // Cache trig results because trig is expensive
  final cosr = cos(r);
  final sinr = sin(r);

  // Perform rotation
  final dx = ox * cosr - oy * sinr;
  final dy = ox * sinr + oy * cosr;

  // Undo the offset
  return LatLng(dy + my, dx + mx);
}

使用这种方法,我得到了以下结果:

蓝色点是输入,绿色点是计算出的中点,红色点是经过90度旋转的每个蓝色点。

(请注意,蓝色点之间的距离似乎比红色点之间的距离更远。这是因为我在使用墨卡托投影的 Google 地图中可视化了结果,并且具有点之间相互关联的结果。如果你想在地球上看到这一点,这些点之间的距离应该是正确的。)