I am trying to find the intersection of circles with their center given in Lat/Lng and their radius in meter.
I find this really good code here https://gis.stackexchange.com/questions/156371/finding-intersection-of-two-circle-given-lat-lon-and-radius that I modified, and it works with the given value, but when I try with mine, it return NaN as Lat/Lng.
//My value - radius in meter
{
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));
}
{
//Value that works - radius in 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);
//This is where the problem occur
//It should return a number but instead i get 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){
// converts NM right now
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)){
// process as parallel arrays
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)){
// process as key-value object
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;
}
I think it may be because the circles are too close to each other, but I'm not sure.