simulation-backend/src/main/java/com/hivekion/common/GeoPosition.java
2025-09-14 16:18:12 +08:00

101 lines
3.1 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.hivekion.common;
/**
* [类的简要说明]
* <p>
* [详细描述,可选]
* <p>
*
* @author LiDongYU
* @since 2025/7/22
*/
public class GeoPosition {
// 地球半径(单位:米)
private static final double EARTH_RADIUS = 6371000.0;
// 角度转弧度
public static double toRadians(double degree) {
return degree * Math.PI / 180.0;
}
// 弧度转角度
public static double toDegrees(double radian) {
return radian * 180.0 / Math.PI;
}
// 球面距离haversine公式
public static double haversine(double lat1, double lon1, double lat2, double lon2) {
double dLat = toRadians(lat2 - lat1);
double dLon = toRadians(lon2 - lon1);
lat1 = toRadians(lat1);
lat2 = toRadians(lat2);
double a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(lat1) * Math.cos(lat2) *
Math.sin(dLon/2) * Math.sin(dLon/2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
return EARTH_RADIUS * c;
}
// 球面线性插值Slerp大圆航线插值
public static double[] interpolate(double lat1, double lon1, double lat2, double lon2, double f) {
// 转为弧度
lat1 = toRadians(lat1);
lon1 = toRadians(lon1);
lat2 = toRadians(lat2);
lon2 = toRadians(lon2);
double sinLat1 = Math.sin(lat1), cosLat1 = Math.cos(lat1);
double sinLat2 = Math.sin(lat2), cosLat2 = Math.cos(lat2);
double deltaLon = lon2 - lon1;
double a = Math.sin((1-f) * haversineAngle(lat1, lon1, lat2, lon2)) / Math.sin(haversineAngle(lat1, lon1, lat2, lon2));
double b = Math.sin(f * haversineAngle(lat1, lon1, lat2, lon2)) / Math.sin(haversineAngle(lat1, lon1, lat2, lon2));
// 球面坐标
double x = a * cosLat1 * Math.cos(lon1) + b * cosLat2 * Math.cos(lon2);
double y = a * cosLat1 * Math.sin(lon1) + b * cosLat2 * Math.sin(lon2);
double z = a * sinLat1 + b * sinLat2;
double lat = Math.atan2(z, Math.sqrt(x*x + y*y));
double lon = Math.atan2(y, x);
return new double[] { toDegrees(lat), toDegrees(lon) };
}
// 计算球面距离的角度(弧度)
public static double haversineAngle(double lat1, double lon1, double lat2, double lon2) {
double dLat = lat2 - lat1;
double dLon = lon2 - lon1;
double a = Math.sin(dLat/2) * Math.sin(dLat/2)
+ Math.cos(lat1) * Math.cos(lat2)
* Math.sin(dLon/2) * Math.sin(dLon/2);
return 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
}
public static void main(String[] args) {
// 起点
double lon1 = 121.148362;
double lat1 = 25.007064;
// 终点
double lon2 = 121.147192;
double lat2 = 25.007612;
// 速度(米/秒)
double speed = 5.0;
// 已行驶时间(秒)
double seconds = 30.0;
// 计算总距离
double totalDist = haversine(lat1, lon1, lat2, lon2);
// 已行驶距离
double movedDist = speed * seconds;
// 占比
double f = Math.min(movedDist / totalDist, 1.0);
// 球面插值
double[] pos = interpolate(lat1, lon1, lat2, lon2, f);
System.out.printf("当前位置:经度 %.6f, 纬度 %.6f\n", pos[1], pos[0]);
}
}