You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

经纬度圆心、米级半径的圆求交返回NaN问题求助

问题:经纬度圆心、米级半径的两圆交点计算返回NaN

我正在计算两个以经纬度为圆心、米为单位半径的圆的交点,修改了一段代码后,使用示例参数时可正常运行,但用自己的参数时返回NaN格式的经纬度。

// 自定义参数 - 半径单位为米
{
  const circle1 = {lat:-4.504471833333334, lon:48.37154066666667, r:meterToNautMiles(2887.5)};
  const circle2 = {lat:-4.504421, lon:48.37154066666667, r:meterToNautMiles(2898.5)};
  console.log(findInterscetionOfTwoCircles(circle1,circle2));
}


{
  // 可正常运行的示例参数 - 半径单位为海里(NM)
  const circle1 = {lat:37.673442, lon:-90.234036, r:107.5};
  const circle2 = {lat:36.109997, lon:-90.953669, r:145};
   console.log(findInterscetionOfTwoCircles(circle1,circle2));
}

function meterToNautMiles(meter){
    var NM = meter * 0.00053996;
    return NM;
}

function findInterscetionOfTwoCircles(circle1, circle2){
    var c1 = latLonToGeocentricCoords(circle1);
    var c2 = latLonToGeocentricCoords(circle2);
    var r1 = convertRadius(circle1.r);
    var r2 = convertRadius(circle2.r);
    var c1dotc2 = calculateDotProduct(c1, c2);

    var a = (Math.cos(r1) - (Math.cos(r2) * c1dotc2)) / (1 - (c1dotc2 * c1dotc2));
    var b = (Math.cos(r2) - (Math.cos(r1) * c1dotc2)) / (1 - (c1dotc2 * c1dotc2)); 
    var n = calculateCrossProduct(c1, c2); 

    var x0 = calculateLinearCombination(a, b, c1, c2);

    ndot = calculateDotProduct(n,n);
    xdot = calculateDotProduct(x0,x0);

    // 问题出在这里
    // 应该返回数值,但实际得到NaN
    var t = Math.sqrt((1 - xdot)/ndot);

    var point_1 = vectorPlusVector(x0,numberTimesVector(t, n));
    var point_2 = x0 + (numberTimesVector(-t, n));

    point1 = {
        lat: radToDeg(Math.asin(point_1[2])), 
        lon:radToDeg(Math.atan2(point_1[1], point_1[0]))
    }
    return point1;

}

function latLonToGeocentricCoords(circle){
    var x = Math.cos(degToRad(circle.lon)) * Math.cos(degToRad(circle.lat));
    var y = Math.sin(degToRad(circle.lon)) * Math.cos(degToRad(circle.lat));
    var z = Math.sin(degToRad(circle.lat));

    return {x:x, y:y, z:z};
}

function geocentricCoordsToLatLon(x, y, z){
    var lon = Math.atan2(x,y)
    var lat = Math.atan2(Math.sqrt((x*x)+(y*y)), z)

    return { lat: lat, lon: lon};
}

function convertRadius(radius){
    // 当前转换海里单位
    return degToRad(radius) / 60;
}

function numberTimesVector(number, vector){
    for(let i=0; i < vector.length; i++){
        vector[i] = vector[i] * number;
    }
    return vector;
}

function vectorPlusVector(v1, v2){
    var vector = [];
    if(v1.length !== v2.length){
        throw new Error('Input lengths must be the same.');
    }
    for(let i=0; i < v1.length; i++){
        vector.push(v1[i]+v2[i]);
    }
    return vector;
}

function calculateDotProduct(input1, input2){
    if(arguments.length !== 2){
        throw new Error('You must supply two arguments to this method.');
    }

    if(Array.isArray(input1) !== Array.isArray(input2) || typeof input1 !== typeof input2){
        throw new Error('Inputs must be the same types.');
    }

    var dotProduct = 0;
    if(Array.isArray(input1)){
        // 处理数组类型
        if(input1.length !== input2.length){
            throw new Error('Input lengths must be the same.');
        }
        for(var i = 0, len = input1.length; i < len; i++){
            dotProduct += input1[i] * input2[i];
        }
    } else if(typeof input1 === 'object' && !Array.isArray(input1)){
        // 处理键值对对象类型
        for(var key in input1){
            if (input1.hasOwnProperty(key)) {
                if(!input2[key]){
                    throw new Error('Both inputs must have the same properties to be processed.');
                }
                dotProduct += input1[key] * input2[key];
            }

        }
    }

    return dotProduct; 
}

function calculateCrossProduct(circle1, circle2){
    var x = (circle1.y * circle2.z) - (circle1.z * circle2.y);
    var y = (circle1.z * circle2.x) - (circle1.x * circle2.z);
    var z = (circle1.x * circle2.y) - (circle1.y * circle2.x);

    return [x, y, z];
}

function calculateLinearCombination(a, b, c1, c2){
    var x = {x: a * c1.x, y: a * c1.y, z: a * c1.z};
    var y = {x: b * c2.x, y: b * c2.y, z: b * c2.z};

    return [x.x+y.x, x.y+y.y,x.z+y.z];
} 

function degToRad(degree){
    return degree * Math.PI / 180;
}

function radToDeg(radian){
    return radian / Math.PI * 180;
}

我猜测可能是两个圆过于接近导致的,但不确定具体原因。


内容的提问来源于stack exchange,提问作者Antonin L

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 18:24:56