JavaScript Google Maps API V3 円と円の交点を求める

もう二度とやらないと思うけど
大分時間をとられたのでメモっておきます。
StackOverflowを参考にさせて頂き、2円の半径が違う場合でも交点が求められるように変更をしました。
ほぼそのままなので詳細は↑から確認してください。
function getIntersection(lat1, lng1, radius1, lat2, lng2, radius2){

    var R = 6378000; // m

    var r1 = radius1  / R;
    var r2 = radius2 / R;

    var x1 = lat1 * Math.PI / 180;
    var x2 = lat2 * Math.PI / 180;

    var y1 = lng1 * Math.PI / 180;
    var y2 = lng2 * Math.PI / 180;

    var dx = ((lat2 - lat1) * Math.PI) / 180;
    var dy = ((lng2 - lng1) * Math.PI) / 180;

    var a = Math.sin(dx / 2) * Math.sin(dx / 2) +
    Math.sin(dy / 2) * Math.sin(dy / 2) * Math.cos(x1) * Math.cos(x2);
    var distance = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));

    if(distance > r1 + r2){return}
    if(distance < Math.abs(r1 - r2)){return}

    var cos = (Math.pow(distance, 2) + Math.pow(r1, 2) - Math.pow(r2, 2)) / (2 * r1 * distance);

    var angle = Math.acos(cos);

    var y = Math.sin(dy) * Math.cos(x2);
    var x = Math.cos(x1) * Math.sin(x2) - Math.sin(x1) * Math.cos(x2) * Math.cos(dy);
    var brng = Math.atan2(y, x);

    var B_bearing = brng - angle;
    var D_bearing = brng + angle;

    var X1 = Math.asin(Math.sin(x1) * Math.cos(r1) +
    Math.cos(x1) * Math.sin(r1) * Math.cos(B_bearing));
    var Y1 = y1 + Math.atan2(Math.sin(B_bearing) * Math.sin(r1) * Math.cos(x1),
   Math.cos(r1) - Math.sin(x1) * Math.sin(x2));

    var X2 = Math.asin(Math.sin(x1) * Math.cos(r1) +
    Math.cos(x1) * Math.sin(r1) * Math.cos(D_bearing));
    var Y2 = y1 + Math.atan2(Math.sin(D_bearing) * Math.sin(r1) * Math.cos(x1),
   Math.cos(r1) - Math.sin(x1) * Math.sin(x2));

    return [
        {
            lat: X1 * 180 / Math.PI,
            lng: Y1 * 180 / Math.PI
        },
        {
            lat: X2 * 180 / Math.PI,
            lng: Y2 * 180 / Math.PI
        }
    ];
}
緯度, 経度, 半径(m)x2を投げるとObject型で緯度経度を返します。
極端に大きい半径だとおかしくなったりしますが、まあ求めている動作は出来たので良しとします。
正直数学とかもう何時の話やらって感じだし未だにいまいち理解しきれてないです。
そもそも緯度経度半径で交点求めるだけなんでGoogleMapsあんま関係ないし
教養の無さが辛いです(´・ω・`)

シェアする

  • このエントリーをはてなブックマークに追加

フォローする