在 LatLng 坐标系中旋转对象

Cur*_*s99 3 latitude-longitude coordinates coordinate-transformation dart flutter

嘿,我正在尝试在经纬度系统中绕其自己的中心旋转一条线。

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

 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);

  }
Run Code Online (Sandbox Code Playgroud)

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

LatLng newA = rotate(A.latitude,A.longitude);
LatLng newB = rotate(B.latitude,B.longitude);
Run Code Online (Sandbox Code Playgroud)

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

正如 @Abion47 在他的回答中澄清的那样,我需要 3 维旋转,但如何做到这一点?如果线非常小,二维是否可能?

Abi*_*n47 7

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

真正的问题是您想要围绕中点旋转这些点,但您的数学只是执行直线旋转,这将围绕原点旋转它们(即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);
}
Run Code Online (Sandbox Code Playgroud)

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

Google 地图上的公式结果

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

(请注意,蓝点之间的距离似乎比红点之间的距离更远。这是因为我在使用墨卡托投影的 Google 地图中可视化了结果,并且结果是与点出现的位置拧在一起。彼此之间是相对的。如果您要在地球上想象这一点,则这些点之间的距离应该是正确的。)