Haversine Formula in Max - Troublesome.

conorb's icon

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:

Max Patch
Copy patch and select New From Clipboard in Max.

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);

}

Ben Bracken's icon

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

conorb's icon

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);
}