Haversine Formula in Max - Troublesome.
Hello, I'm fairly fresh faced to the way javascript works in Max, perhaps y'all can enlighten me!
I'm trying to implement within js the Haversine formula which takes in two sets of longitudes and latitudes and roughly calculates the geographic distance between those two points.
Its currently returning nan and I don't have a clue why. There was a troublesome .toRad function that I've replaced with the equation itself.
Heres the Max side of things:
And heres my javascript:
inlets = 1;
outlets = 1;
autowatch = 1;
function lat1(val){
var lat1 = val
}
function lon1(val){
var lon1 = val
}
function lat2(val){
var lat2 = val
}
function lon2(val){
var lon2 = val
}
function bang(){
var R = 6371; // km
//has a problem with the .toRad() method below.
var x1 = lat2-lat1;
var dLat = x1* Math.PI / 180;
var x2 = lon2-lon1;
var dLon = x2* Math.PI / 180;
var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(lat1* Math.PI / 180) * Math.cos(lat2* Math.PI / 180) *
Math.sin(dLon/2) * Math.sin(dLon/2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
var d = R * c;
post(d);
outlet(0,d);
}
Your lat1/lat2/lon1/lon2 variables are local to their functions, so other functions don't know about them. You could declare them at the top of your code and then set them in your bang function, or you could get rid of these functions altogether and use declareattribute(). You can read more about declareattribute() here:
-Ben
Perfect! Working away now. Thanks for your help Ben.
Working code for anyone that wants to get their haversine / earth distance calculations on;
var lat1;
var lon1;
var lat2;
var lon2;
inlets = 4;
outlets = 1;
autowatch = 1;
function msg_float(val){
if (inlet==3){
lon2 = val; // convert appropriate inlet to value. lat1, lon1, lat2, lon2.
}
if (inlet==2){
lat2 = val;
}
if (inlet==1){
lon1 = val;
}
if (inlet==0){
lat1 = val;
}
var R = 6371; // km
//has a problem with the .toRad() method below.
var x1 = lat2-lat1;
var dLat = x1* Math.PI / 180;
var x2 = lon2-lon1;
var dLon = x2* Math.PI / 180;
var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(lat1* Math.PI / 180) * Math.cos(lat2* Math.PI / 180) *
Math.sin(dLon/2) * Math.sin(dLon/2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
var d = R * c;
post(d);
outlet(0,d);
}