public Point2D.Double getDirectionFor(Task task) { Point2D.Double loc = task.ownerLoc; Point2D.Double tLoc = task.targetLoc; Point2D.Double tVel = task.target.getVelocity(); double tSpeed = tVel == null ? 0 : tVel.distance(0, 0); Point2D.Double diff = new Point2D.Double(tLoc.x - loc.x, tLoc.y - loc.y); if (tSpeed == 0 || task.owner.par.topSpeed < tSpeed * 1.0001) return PlanarMathUtils.normalize(diff); // In this algorithm, the capture point is assumed to be where the pursuer would first be able // to overtake the evader if the evader kept heading // in its current direction... this is where the ratio of speeds is equal to the ratio of // distances to this hypothetical point. // The evader's distance to this point is dE, and the pursuer heads toward the evader's // position plus its heading times dE*leadFactor. double mu = task.owner.par.topSpeed / tSpeed; // ratio of speeds is used several times in the formula double dcosth = (tVel.x * diff.x + tVel.y * diff.y) / tSpeed; // basic dot product formula for cosine... provides ||diff|| * cos of angle // between diff and tVel double dE = (Math.abs(dcosth) - Math.sqrt(dcosth * dcosth - (1 - mu * mu) * diff.distanceSq(0, 0))) / (1 - mu * mu); return unitVectorTo( loc, new Point2D.Double( tLoc.x + tVel.x * leadFactor * dE / tSpeed, tLoc.y + tVel.y * leadFactor * dE / tSpeed), task.type.multiplier); }
public int compare(Point2D.Double a, Point2D.Double b) { return Double.compare(a.distanceSq(center), b.distanceSq(center)); }