Escape Circle
Escape Circle is the circumference of Escape Envelope assuming the motion of the target is linear and uniform, and ignoring any collision with walls or other robots.
Prove & calculation
Assuming uniform linear motion, consider a situation where a bullet fired from the firer A hits the target C at some future position B. A is the angle opposite to a, B is opposite to b, and C is opposite to c.
Let the target C be the origin, the distance and orientation from the target to the firer be the unit length and positive x-axis respectively.
Let θ be the angle between b and a, we have c / a = Vb / Vr, b = 1, where Vb and Vr is the velocity of the bullet and the target respectively. Now consider cosine formula:
a2 + 12 - 2 a cosθ = (Vb / Vr a)2
Let x = a cosθ, y = a sinθ, k = 1 / ((Vb / Vr)2 - 1), we have:
(x + k)2 + y2 = k2 + k
The points defined by (x, y) satisfying above formula is a circle e with center P(-k, 0), and radius sqrt(k2 + k).
Example code
import java.awt.geom.Point2D;
public final class EscapeCircle {
public Point2D.Double center;
public double radius;
public EscapeCircle(Point2D.Double center, double radius) {
this.center = center;
this.radius = radius;
}
public static EscapeCircle calc(Point2D.Double fireLocation, Point2D.Double targetLocation, double waveSpeed) {
double distance = fireLocation.distance(targetLocation);
double k = 1. / (sq(waveSpeed / 8.) - 1.);
double radius = distance * Math.sqrt(k * k + k);
return new EscapeCircle(scale(fireLocation, targetLocation, 1 + k), radius);
}
private static Point2D.Double scale(Point2D.Double origin, Point2D.Double point, double ratio) {
return new Point2D.Double(
origin.x + ratio * (point.x - origin.x),
origin.y + ratio * (point.y - origin.y)
);
}
private static double sq(double x) {
return x * x;
}
}