// quarter turn
double Q4 = PI/2;
// some random airport orientation
double randomAngle = random(0, TAU);
// distance from approach point to offset point
double R = 50;
// distance from offset point to secondary offset
// (to force the plane to fly towards the offset)
double R2 = R + 10;
Point end, start, M = new Point(0,0), anchor, o1, o2;
void determineCriticalPoints(int x, int y) {
Point cursor = new Point(x, y);
double ca = cos(randomAngle);
double sa = sin(randomAngle);
// even though M is (0,0), it won't be in the game.
double mx = M.x;
double my = M.y;
start = new Point(mx - 150 * ca, my - 150 * sa);
end = new Point(mx - 200 * ca, my - 200 * sa);
anchor = new Point(mx + 150 * ca, my + 150 * sa);
o1 = null;
o2 = null;
double ax = anchor.x;
double ay = anchor.y;
double v1 = M.x - ax;
double v2 = M.y - ay;
double w1 = cursor.x - ax;
double w2 = cursor.y - ay;
double r = randomAngle;
double a = atan2(w2*v1 - w1*v2, w1*v1 + w2*v2);
Point p = cursor.project(M, anchor);
double d = dist(p, cursor);
if (a > Q4 || a < -Q4) {
o1 = new Point(ax + R * cos(r), ay + R * sin(r));
} else {
if (a > 0) {
r -= Q4;
double cr = cos(r);
double sr = sin(r);
o1 = new Point(ax + R * cr, ay + R * sr);
if (d < 50) o2 = new Point(ax + R2 * cr, ay + R2 * sr);
} else {
r += Q4;
double cr = cos(r);
double sr = sin(r);
o1 = new Point(ax + R * cr, ay + R * sr);
if (d < 50) o2 = new Point(ax + R2 * cr, ay + R2 * sr);
}
}
}