java根据经纬度以及高度生成抛物线

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;
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值