Source: VelocityField.js

/**
 *
 * @param {number} width - the width of the field
 * @param {number} height - the height of the field
 * @param {number} numSeedPoints - number of seed points
 * @constructor
 */
var VelocityField = function (width, height, numSeedPoints) {

    var parent = this;

    this.widthOfField = width;
    this.heightOfField = height;
    //this.seedPositions = [];
    this.numSeedPoints = numSeedPoints;

    this.wheaterStations = [
        {
            name: "Linz/Hörsching",
            xPos: 790,
            yPos: 210,
            direction: 71,
            kmh: 270
        },
        {
            name: "Wien/Schwechat",
            xPos: 1100,
            yPos: 250,
            direction: 5,
            kmh: 80
        },
        {
            name: "Bregenz",
            xPos: 60,
            yPos: 450,
            direction: 1,
            kmh: 62
        },
        {
            name: "Innsbruck",
            xPos: 330,
            yPos: 400,
            direction: 47,
            kmh: 259
        }
    ];

    //create 2 dimensional array for easier accessing.
    var fieldData = new Array(height);
    for (var i = 0; i < width; i++) {
        fieldData[i] = new Array(height);
    }

    this.initAustriaField = function() {
        //TODO
    }

    /**
     * inits a custom velocity field
     */
    this.initCustomField = function () {
        for (var i = 0; i < parent.heightOfField; i++){
            for (var j = 0; j < parent.widthOfField; j++){

                var xDir = 10;
                var yDir = 0;

                var velocity = Math.sqrt(xDir*xDir + yDir*yDir);
                fieldData[j][i] = new VelocityFieldPoint(j, i, xDir, yDir, velocity);
                fieldData[j][i].distance = 0;
            }
        }


        for (var i = 200; i < 500; i++){
            for (var j = 200; j < 400; j++){

                var xDir = 10;
                var yDir = 20;

                var velocity = Math.sqrt(xDir*xDir + yDir*yDir);
                fieldData[j][i] = new VelocityFieldPoint(j, i, xDir, yDir, velocity);
                fieldData[j][i].distance = 0;
            }
        }

        for (var i = 200; i < 500; i++){
            for (var j = 600; j < 800; j++){

                var xDir = 1;
                var yDir = -2;

                var velocity = Math.sqrt(xDir*xDir + yDir*yDir);
                fieldData[j][i] = new VelocityFieldPoint(j, i, xDir, yDir, velocity);
                fieldData[j][i].distance = 0;
            }
        }
    }

    this.initWheaterField = function () {
        //TODO fetch real weather data and init the Velocity Field
        console.error("NOT IMPLEMENTED.");
    }

    /**
     * get average field data for a given point
     * @param {number} x - x coordinate
     * @param {number} y - y coordinate
     * @returns {VelocityFieldPoint}
     */
    this.getAverageFieldData = function(x, y)
    {
        try {
            if(x+1 < 0 || y+1 < 0 || x+1 > parent.widthOfField-1 || y+1 > parent.heightOfField-1 || x < 0 || y < 0 || x > parent.widthOfField-1 || y > parent.heightOfField-1)
            {
                return new VelocityFieldPoint(0, 0, 0, 0, 0);
            } 
            else {

                //console.log("x: " + x + ",y: " + y);
                var fieldPoint = fieldData[x][y];
                var fieldPointRight = fieldData[x+1][y];
                var fieldPointTop = fieldData[x][y+1];
                var fieldPointRightTop = fieldData[x+1][y+1];

                var avgX = (fieldPoint.dirX + fieldPointRight.dirX + fieldPointTop.dirX + fieldPointRightTop.dirX) / 4;
                var avgY = (fieldPoint.dirY + fieldPointRight.dirY + fieldPointTop.dirY + fieldPointRightTop.dirY) / 4;
                var avgV = Math.sqrt(avgX*avgX+avgY*avgY);

                return new VelocityFieldPoint(x, y, avgX, avgY, avgV);
            }
        }catch(e){
                console.log("WARNING: VelocityField: Weird property error with fieldData. x: " + x + "y: " + y + " fieldData: " + fieldData[x][y]);

                return new VelocityFieldPoint(0, 0, 0, 0, 0);
        }
    }

    /**
     *
     * @param {number} x - x coordinate
     * @param {number} y - y coordinate
     * @returns {VelocityFieldPoint}
     */
    this.getVelocityFieldPoint = function (x, y) {
       try{
            if(x+1 < 0 || y+1 < 0 || x+1 > parent.widthOfField-1 || y+1 > parent.heightOfField-1 || x < 0 || y < 0 || x > parent.widthOfField-1 || y > parent.heightOfField-1)
                {
                    return new VelocityFieldPoint(-1, -1, 0, 0, 0);
                } 
            else {
                return fieldData[x][y];
            }
        } catch (e){
            console.log("WARNING: getVelocityFieldPoint: Weird property error with fieldData. x: " + x + "y: " + y + " fieldData: " + fieldData[x][y]);
            return new VelocityFieldPoint(-1, -1, 0, 0, 0);
        }
    }
    
}