if(velocity >= 0 && distanceRemaining >= decelDistance(velocity)) |
double maxTurn = Math.PI/180*(10 - 0.75*Math.abs(velocity)); theta = limit(0,theta - maxTurn, Math.PI/2); if(velocity >= 0 && distanceRemaining > decelDistance(velocity)) |
|
double maxTurn = Math.PI/180*(10 - 0.75*velocity); theta = limit(0,theta - maxTurn, Math.PI/2); |
else //rule of cosines |
else{ //rule of cosines double oldDistRem? = distanceRemaining; |
double acosVal = (velocity*velocity + distanceRemaining*distanceRemaining - oldDistRem?*oldDistRem?)/(2*velocity*distanceRemaining); if(Math.abs(acosVal) <= 1){ theta = Math.abs(Math.acos(acosVal)); if(theta > Math.PI/2) theta = Math.PI - theta; } } |
}while(time < timeAvailable && distanceRemaining >= 1); |
}while(time < timeAvailable && distanceRemaining > 0.000001); |
public static boolean reachable(Point2D.Double fromLocation, Point2D.Double toLocation, long timeAvailable, double initialVelocity, double initialHeading){ double wantedHeading = absoluteBearing(fromLocation,toLocation); double velocity = initialVelocity; double distanceRemaining = fromLocation.distance(toLocation);; long time = 0; double theta = Math.abs(Utils.normalRelativeAngle(wantedHeading - initialHeading)); if(theta > Math.PI/2){ theta = Math.PI - theta; velocity = -velocity; } do{ double maxTurn = Math.PI/180*(10 - 0.75*Math.abs(velocity)); theta = limit(0,theta - maxTurn, Math.PI/2); if(velocity >= 0 && distanceRemaining > decelDistance(velocity)) velocity = limit(0,velocity + 1, 8); else velocity = limit(-1, Math.abs(velocity) - Math.min(distanceRemaining,2), 6)*(velocity<0?-1:1); if(theta == 0) distanceRemaining -= velocity; else{ //rule of cosines double oldDistRem = distanceRemaining; distanceRemaining = Math.sqrt(velocity*velocity + distanceRemaining*distanceRemaining - 2*velocity*distanceRemaining*Math.cos(theta)); double acosVal = (velocity*velocity + distanceRemaining*distanceRemaining - oldDistRem*oldDistRem)/(2*velocity*distanceRemaining); if(Math.abs(acosVal) <= 1){ theta = Math.abs(Math.acos(acosVal)); if(theta > Math.PI/2) theta = Math.PI - theta; } } time++; }while(time < timeAvailable && distanceRemaining > 0.000001); return distanceRemaining < 1; } static double decelDistance(double vel){ int intVel = (int)Math.round(vel); switch(intVel){ case 8: return 6 + 4 + 2; case 7: return 5 + 3 + 1; case 6: return 4 + 2; case 5: return 3 + 1; case 4: return 2; case 3: return 1; case 2: case 1: case 0: return 0; default: return 6 + 4 + 2; } }