Search code examples
javascriptmathinterpolationweighted-average

Weighted Interpolation using means of circular quantities


I am woking on a project of weighted interpolation. Each station has a coordinate point on the map as shown below.

var stationCoor = [[408,352],[525,348],[535,495],[420,400],[272,145],[175,195],[197,335]];

I am taking points that are located in the lake and I am using those to create weighted averages for inputs from those stations. Here is my function for determining the weighted numbers.

function findWeightSpeed(xPos, yPos){
   var totalHypt = 0;
   var arrHpyt = [];
   var arrWeight = [];
   for(var l=0;l<7;l++){
       var xDis = Math.abs(xPos-stationCoor[l][0]);
       var yDis = Math.abs(yPos-stationCoor[l][1]);
       var hptSq = Math.pow(xDis,2)+Math.pow(yDis,2);
       var hypt = Math.sqrt(hptSq);
       totalHypt = totalHypt+hypt;
       arrHpyt.push(hypt);
   }
   for(var j=0;j<7;j++){
       arrWeight.push(arrHpyt[j]/totalHypt)
   }
   return arrWeight;
}

This finds the hypotenuse between the point (xPos,yPos) and the stations. It then adds the data up and divides each station by the total yielding the weighted numbers.

I need to use these points to weight wind direction from these stations. I was using the funciotn below to calculate an average of points.

function averageAngles(){
    var x = 0;
    var y = 0;
    var pi = 22/7;
    var angle = [2.7925,2.8797,2.9670,3.0543, 0.0872]; // 310,320,330,340,10
    for(var i = 0; i < angle.length; i++) {
        x += Math.cos(angle[i]);
        y += Math.sin(angle[i]);
    }
    var average_angle = Math.atan2(y, x);
    console.log((average_angle/pi)*360);
}

This gave me accurate information for a weighted average of .20 for all points. However, the weighted average points for the 7 stations (as seen below on the map) is similar to [0.1076839005418769, 0.08051796093187284, 0.003987308213631277, 0.08458358029618485, 0.2463427297217639, 0.26463834002675196, 0.21224618026791833].

How would I go about making a function that takes the weighted average numbers from the findWeightSpeed() and using that to weight the circular quantities in averageAngles()?

I used this How do you calculate the average of a set of circular data? to make the function for averaging angles.

Many thanks for any suggestions given.

Image of Clear Lake Map


Solution

  • Here is a link I found online that explains the entire procedure.

    Computing Weighted Averages for Wind Speed and Direction

    The code is similar to this.

    function weightAllData(xPos,yPos,windData){
                    var uVecSum = 0;
                    var vVecSum = 0;
                    var arrayWeightSpeed = findWeightSpeed(xPos, yPos); //using weighted interpolation based on distance
                    var arrayWindSpeed = [WSData];
                    var arrayWindDirection = [WDData];
                    for(var m=0;m<7;m++){
                        uVecSum = uVecSum + (arrayWeightSpeed[m] * getUVector(arrayWindSpeed[m],(arrayWindDirection[m]/180)*Math.PI));
                        vVecSum = vVecSum + (arrayWeightSpeed[m] * getVVector(arrayWindSpeed[m],(arrayWindDirection[m]/180)*Math.PI));
                    }
    
                    var weightWS = Math.sqrt(Math.pow(uVecSum,2)+Math.pow(vVecSum,2));
                    if(vVecSum!=0){
                        weightWDRad = Math.atan(uVecSum/vVecSum);
                    }
                    if(vVecSum==0){
                        weightWDRad = Math.atan(uVecSum/(0.0001+vVecSum));
                    }
                    if(weightWDRad<0){
                        weightWDRad = weightWDRad + Math.PI
                    }
                    weightWD = (weightWDRad * (180/Math.PI));
    }
    

    Let me know if you want an explanation