在 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 地图中可视化了结果,并且具有点之间相互关联的结果。如果你想在地球上看到这一点,这些点之间的距离应该是正确的。)
嘿,我正在尝试在 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 地图中可视化了结果,并且具有点之间相互关联的结果。如果你想在地球上看到这一点,这些点之间的距离应该是正确的。)