FUNC r = CircleDist(c, a, b) IS r = Geometry.Dist(a, c) - Geometry.Dist(a, b) END; UI PointTool(CircleDist); (* "r" is the shortest distance from the point "c" to the circle with center "a" and circumference point "b". *) PRED EqCircleDist(e, a, b, c, d) IS CircleDist(e, a, b) = CircleDist(e, c, d) END; UI PointTool(EqCircleDist); CONST Eps = 0.1; PRED Near(x, y) IS (E xy = x - y :: xy * xy < Eps) END; PROC DrawCircle(a, b, color) IS Circle.Draw(a, b); PS.Save(); PS.SetColor(color); PS.Fill(); PS.Restore(); PS.Stroke() END; UI PointTool(DrawCircle); PROC DrawTangCirc(a, b, c, d, e) IS IF VAR f ~ (0.5, 0) REL (b, a), g ~ (-0.5, 0) REL (b, a), h ~ (0.5, 0) REL (d, a), i ~ (-0.5, 0) REL (d, a), p IN (b, c) CONG (b, f) AND (b, c) CONG (b, g) AND (d, e) CONG (d, h) AND (d, e) CONG (d, i) AND Geometry.Colinear(b, f, a) AND Geometry.Colinear(b, g, a) AND Geometry.Colinear(d, h, a) AND Geometry.Colinear(d, i, a) -> VAR af, ag, ah, ai IN af := Geometry.Dist(a, f); ag := Geometry.Dist(a, g); ah := Geometry.Dist(a, h); ai := Geometry.Dist(a, i); IF Near(af, ah) OR Near(af, ai) -> p := f | Near(ag, ah) OR Near(ag, ai) -> p := g | p := a FI END; Circle.Draw(a, p); PS.Stroke() END FI END; UI PointTool(DrawTangCirc); PROC Cmd0() IS IF VAR a = (-49.84547, 98.4375), b = R2.Plus(a, (-46.20029, -35.648987)), c = (86.34154, 75.848915), d = R2.Plus(c, (16.281494, -18.192665)), e = (1.4660432, -91.40625), f = R2.Plus(e, (-35.91806, -31.640625)), p ~ (31.057737, 12.205275) IN EqCircleDist(p, a, b, e, f) AND EqCircleDist(p, a, b, c, d) -> PS.SetWidth(2); DrawCircle(a, b, Color.Red); DrawCircle(c, d, Color.Yellow); DrawCircle(e, f, Color.Blue); DrawTangCirc(p, a, b, e, f) END FI END;