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.
windSpeedBounds[1]=0d;
}
//Calculate VMG for both bounds.
for(inti=0;i<windSpeedBounds.length;i++){
doublepolarWindSpeed=windSpeedBounds[i];
//We don't calculate anything for wind speeds of 0, as boats will not move.
//This is the delta angle between the boat's true bearing and the destination.
@ -210,14 +223,130 @@ public class Polars {
}
}
//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.
//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());
}
//Get the interpolation scalar for the current wind speed.