made speed and bearing members private - had accidentally forget the visibility specifier.
Mock.Polars:
Added linear interpolation between speed values (e.g., if the wind speed is 15.9kn, it will interpolate between the 12kn and 16kn data). This allows for wind speeds less than 4kn (the lowest wind speed in the data file). It does not extrapolate anything for wind speeds larger than 30kn (the largest wind speed in the data file).
Also refactored some of the code into some interpolation functions.
#story[873]
//Currently a fairly simple implementation where we find the wind speed that is less than or equal to the current wind speed (the lower bound), and then find the specific angle (with no interpolation) that gives the best VMG.
//TODO we need to add interpolation between angles for a given wind speed (e.g., we have 0 deg, 30 deg, but the optimal bearing may be 17.3 degrees).
//TODO we should also interpolate between wind speeds (e.g., we have 12kn and 16kn, but if the wind speed is actually 15.999kn, then we should interpolate to get a more accurate final value).
//-1 indicates that we haven't found any smaller wind speeds in our map.
doublepolarWindSpeed=-1;
//Find the lower bound wind speed from the polar table.
//We need to find the upper and lower wind speeds from the Polars table, for a given current wind speed (e.g., current wind speed is 11kn, therefore lower = 8kn, upper = 12kn).
doublepolarWindSpeedLowerBound=0;
doublepolarWindSpeedUpperBound=9999999;//Start this off with a value larger than any in the Polars table so that it actually works.
//This indicates whether or not we've managed to find a wind speed larger than the current wind speed (the upper bound) in the Polars table (in cases where the current wind speed is larger than any in the file we will never find an upper bound).
//If we never found a smaller speed value (e.g., smallest speed in table is 4kn, user provided 2kn), then for now we give a vector with 0 speed towards destination. Later, this should interpolate between adjacent wind speeds.
if(polarWindSpeed==-1){
returnnewVMG(0,destinationAngle);
}
//TODO for wind speeds larger than any in the Polars table, we will simply not find an upper bound, and therefore never calculate an upper VMG, or interpolate between them.
//Find the angle with the best VMG.
//We need to find the VMGs for both lower and upper bound wind speeds, and interpolate betweent them.
ArrayList<VMG>vmgs=newArrayList<>();
//Put wind speed bounds we found above into an array.
double[]windSpeedBounds=newdouble[2];
windSpeedBounds[0]=polarWindSpeedLowerBound;
if(foundUpperBoundSpeed){
windSpeedBounds[1]=polarWindSpeedUpperBound;
}
else{
//If we never found an upper bound, give it a wind speed of 0, so that we don't bother calculating a VMG for it.
//Calculate how far between those points the angle is.
if(!foundInterval){
//If we never found the interval, then it must be the "last" interval, between the i'th and 0'th values.
lowerBound=polarAngles.get(polarAngles.size()-1);
upperBound=polarAngles.get(0);
}
//Angle iteration loop is finished.
//Create the VMG, and add to list.
VMGvmg=newVMG(bestVMGVelocity,bestVMGAngle);
vmgs.add(vmg);
}
//If we never found an upper bound for the wind speed, we will only have one VMG (for the lower bound), so we can't interpolate/extrapolate anything.
if(!foundUpperBoundSpeed){
returnvmgs.get(0);
}
else{
//We may have more than one VMG. If we found an upper and lower bound we will have two, if we only found an upper bound (e.g., wind speed = 2kn, upper = 4kn, lower = n/a) we will only have one VMG, but must interpolate between that and a new VMG with 0kn speed.
//This is the "distance" between the angle and its lower bound.
//I.e., L----A-----------U
// <----> is lowerDelta.
doublelowerDelta=angle-lowerBound;
//This is the "distance" between the upper and lower bound.
//I.e., L----A-----------U
// <----------------> is intervalDelta.
//This can potentially be negative if we have, e.g., lower = 340deg, upper = 0deg, delta = -340deg.
doubleintervalDelta=upperBound-lowerBound;
//If it _is_ negative, modulo it to make it positive.
//E.g., -340deg = +20deg.
if(intervalDelta<0){
intervalDelta+=360d;
//We do a simple linear interpolation.
VMGvmg1=vmgs.get(0);
VMGvmg2;
if(vmgs.size()>1){
//If we have a second VMG use it.
vmg2=vmgs.get(1);
}
else{
//Otherwise create a VMG with zero speed, but the same angle.
vmg2=newVMG(0,vmg1.getBearing());
}
//This is how far between the lower and upper bounds the angle is, as a proportion (e.g., 0.5 = half-way, 0.9 = close to upper).