the calculation of the βhardβ method can be simplified for the case r1 = r2 =: r. First, we need to transform the district centers P1, P2 from (lat, lng) into Cartesian coordinates (x, y, z).
var DEG2RAD = Math.PI/180; function LatLng2Cartesian(lat_deg,lng_deg) { var lat_rad = lat_deg*DEG2RAD; var lng_rad = lng_deg*DEG2RAD; var cos_lat = Math.cos(lat_rad); return {x: Math.cos(lng_rad)*cos_lat, y: Math.sin(lng_rad)*cos_lat, z: Math.sin(lat_rad)}; } var P1 = LatLng2Cartesian(lat1, lng1); var P2 = LatLng2Cartesian(lat2, lng2);
But the line of intersection of the planes holding the circles can be easily calculated. Let d be the distance to the actual center of the circle (in the plane) to the corresponding point P1 or P2 on the surface. A simple conclusion shows (with R the radius of the Earth):
var R = 6371;
Now let S1 and S2 be the intersection points, and S their midpoint. With s = |OS| and t = |SS1| = |SS2| t = |SS1| = |SS2| (where O = (0,0,0) is the center of the earth), we get from simple differentiations:
var a = Math.acos(P1.x*P2.x + P1.y*P2.y + P1.z*P2.z);
Now, since r1 = r2 points S, S1, S2 are in the middle plane between P1 and P2. For v_s = OS we get:
function vecLen(v) { return Math.sqrt(vx*vx + vy*vy + vz*vz); } function vecScale(scale,v) { return {x: scale*vx, y: scale*vy, z: scale*vz}; } var v = {x: P1.x+P2.x, y: P1.y+P2.y, z:P1.z+P2.z}; // P1+P2 is in the middle of OP1 and OP2 var S = vecScale(s/vecLen(v), v); function crossProd(v1,v2) { return {x: v1.y*v2.z - v1.z*v2.y, y: v1.z*v2.x - v1.x*v2.z, z: v1.x*v2.y - v1.y*v2.x}; } var n = crossProd(P1,P2); // normal vector to plane OP1P2 = vector along S1S2 var SS1 = vecScale(t/vecLen(n),n); var S1 = {x: S.x+SS1.x, y: S.y+SS1.y, z: S.z+SS1.z}; // S + SS1 var S2 = {x: Sx-SS1.x, y: Sy-SS2.y, z: Sz-SS1.z}; // S - SS1
Finally, we need to convert back (lat, lng):
function Cartesian2LatLng(P) { var P_xy = {x: Px, y:Py, z:0} return {lat: Math.atan2(Py,Px)/DEG2RAD, lng: Math.atan2(Pz,vecLen(P_xy))/DEG2RAD}; } var S1_latlng = Cartesian2LatLng(S1); var S2_latlng = Cartesian2LatLng(S2);