import java.util.ArrayList;
import java.util.List;
public class ParabolicTrajectoryGenerator {
private static final double EARTH_RADIUS = 6371000; // 地球半径(米)
public static void main(String[] args) {
// 示例数据
double lonA = 116.4074; // 北京经度
double latA = 39.9042; // 北京纬度
double lonB = 121.4737; // 上海经度
double latB = 31.2304; // 上海纬度
double maxHeight = 10000; // 最高点高度(米)
int numPoints = 50; // 生成的轨迹点数
List<GeoPoint> trajectory = generateParabolicTrajectory(
lonA, latA, lonB, latB, maxHeight, numPoints
);
// 输出结果(实际应用中可用于可视化或进一步处理)
for (GeoPoint point : trajectory) {
System.out.printf("经度: %.6f, 纬度: %.6f, 高度: %.2f米%n",
point.longitude, point.latitude, point.elevation);
}
}
/**
* 生成抛物线轨迹
* @param lonA 起点经度
* @param latA 起点纬度
* @param lonB 终点经度
* @param latB 终点纬度
* @param maxHeight 最高点高度(米)
* @param numPoints 生成的点数
* @return 轨迹点列表(包含经纬度和高度)
*/
public static List<GeoPoint> generateParabolicTrajectory(
double lonA, double latA, double lonB, double latB,
double maxHeight, int numPoints) {
// 1. 计算两点间的大圆距离
double distance = haversineDistance(lonA, latA, lonB, latB);
// 2. 生成轨迹点
List<GeoPoint> points = new ArrayList<>();
for (int i = 0; i < numPoints; i++) {
// 计算当前点在路径中的比例(0-1)
double t = (double) i / (numPoints - 1);
// 计算当前点经纬度
double[] position = interpolatePoint(lonA, latA, lonB, latB, t);
double currentLon = position[0];
double currentLat = position[1];
// 计算当前点高度(抛物线公式)
double currentHeight = calculateHeight(distance, maxHeight, t);
points.add(new GeoPoint(currentLon, currentLat, currentHeight));
}
return points;
}
/**
* 计算两点间的大圆距离(Haversine公式)
*/
private static double haversineDistance(double lon1, double lat1, double lon2, double lat2) {
double dLat = Math.toRadians(lat2 - lat1);
double dLon = Math.toRadians(lon2 - lon1);
double a = Math.sin(dLat / 2) * Math.sin(dLat / 2)
+ Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(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;
}
/**
* 在两点间插值计算中间点(球面线性插值)
* @param t 插值比例(0=起点,1=终点)
*/
private static double[] interpolatePoint(
double lon1, double lat1, double lon2, double lat2, double t) {
// 转换为弧度
double lat1Rad = Math.toRadians(lat1);
double lon1Rad = Math.toRadians(lon1);
double lat2Rad = Math.toRadians(lat2);
double lon2Rad = Math.toRadians(lon2);
// 计算插值参数
double delta = haversineDistance(lon1, lat1, lon2, lat2) / EARTH_RADIUS;
double A = Math.sin((1 - t) * delta) / Math.sin(delta);
double B = Math.sin(t * delta) / Math.sin(delta);
// 计算笛卡尔坐标分量
double x = A * Math.cos(lat1Rad) * Math.cos(lon1Rad) + B * Math.cos(lat2Rad) * Math.cos(lon2Rad);
double y = A * Math.cos(lat1Rad) * Math.sin(lon1Rad) + B * Math.cos(lat2Rad) * Math.sin(lon2Rad);
double z = A * Math.sin(lat1Rad) + B * Math.sin(lat2Rad);
// 转换为经纬度
double newLat = Math.atan2(z, Math.sqrt(x * x + y * y));
double newLon = Math.atan2(y, x);
return new double[]{
Math.toDegrees(newLon),
Math.toDegrees(newLat)
};
}
/**
* 计算抛物线高度
* @param distance 两点间总距离
* @param maxHeight 最高点高度
* @param t 当前位置比例(0-1)
*/
private static double calculateHeight(double distance, double maxHeight, double t) {
// 抛物线方程:h = a(x - d/2)² + H_max
// 当x=0时h=0,推导出 a = -4*H_max/d²
double a = -4 * maxHeight / (distance * distance);
// 当前位置距离起点的距离
double x = t * distance;
// 计算高度(确保起点和终点高度为0)
return a * (x - distance / 2) * (x - distance / 2) + maxHeight;
}
/**
* 地理坐标点类
*/
static class GeoPoint {
double longitude;
double latitude;
double elevation; // 高度(米)
public GeoPoint(double longitude, double latitude, double elevation) {
this.longitude = longitude;
this.latitude = latitude;
this.elevation = elevation;
}
}
}
java根据经纬度以及高度生成抛物线
Java开发语言相关
最新推荐文章于 2025-11-26 15:59:01 发布
1826

被折叠的 条评论
为什么被折叠?



