CONST NodeSize = 25, NodeEcc = 1, BoxH = 10, BoxW = 25, ArrowSize = 10, Border = 5; PRED BoxSize(a, b) IS b = R2.Plus(a, (-BoxW, BoxH)) END; UI PointTool(BoxSize); PROC NodeLabel(c, txt) IS VAR a IN a := R2.Plus(c, (NodeSize, -NodeSize * NodeEcc)); PS.Type(a, txt) END END; UI TextTool(NodeLabel); PRED OnNode(a, b) IS (E c = R2.Plus(b, (NodeSize, 0)) :: Ellipse.OnEcc(a, b, c, NodeEcc)) END; UI PointTool(OnNode); PRIVATE FUNC ecc = Ecc(wh) IS (E w, h :: wh = (w, h) AND ecc = h / w) END; PRIVATE FUNC p = RectOnHint(a, c, b) IS (E wh = R2.Minus(b, c), maj :: maj = R2.Plus(c, (CAR(wh), 0)) AND p ~ (0.5, 0) REL (a, c) AND Geometry.Colinear(a, p, c) AND Ellipse.OnEcc(p, c, maj, Ecc(wh))) END; PROC NodeToRect(a, c, b, text) IS IF VAR d ~ RectOnHint(a, c, b), e ~ (0.1428, 0) REL (a, c), f = Geometry.Mid(d, e) IN Geometry.Colinear(a, d, c) AND Geometry.Colinear(a, c, e) AND OnNode(e, a) AND Rect.OnC(d, c, b) -> Arrow.Straight(e, d); TypeLinesC.South(f, text) END FI END; UI TextTool(NodeToRect); PROC FigN(a, b, h, N) IS IF VAR c ~ (2, 0) REL (a, b), d ~ (3, 0) REL (a, b), e ~ (4, 0) REL (a, b), f ~ (5, 0) REL (a, b), g ~ (0.7215, 0.2047) REL (a, h), i ~ (0.7533, 0.09867) REL (g, h), j ~ (1.02, -0.7497) REL (a, h), k ~ (0.7533, 0.09867) REL (f, j), l = R2.Minus(a, (NodeSize + Border, NodeSize + Border)), m = (CAR(j) + BoxW + Border, CDR(h) + NodeSize + Border) IN a HOR b AND a HOR c AND a HOR d AND a HOR e AND a HOR f AND (a, b) CONG (b, c) AND (b, c) CONG (c, d) AND (c, d) CONG (d, e) AND (d, e) CONG (e, f) AND (a, g) CONG (g, f) AND BoxSize(h, i) AND g HOR h AND f HOR j AND BoxSize(j, k) AND Geometry.CongX(g, i, f, k) -> PS.SetBBox(l, m); PS.SetWidth(1.5); Arrow.SetSize(ArrowSize); DiGraph.SetNodeWE((NodeSize, NodeEcc)); PS.SetFontFace("Helvetica-Bold"); PS.SetFontSize(PS.Small); DiGraph.Node(d); DiGraph.Node(e); DiGraph.Node(f); DiGraph.Node(g); DiGraph.Label(d, "sphere"); DiGraph.Label(e, "sphere"); DiGraph.Label(f, "sphere"); DiGraph.Label(g, "root"); NodeLabel(g, "\"root\""); NodeLabel(f, "\"ball\""); DiGraph.Straight0(g, d); DiGraph.Straight0(g, e); DiGraph.Straight0(g, f); IF N >= 2 -> DiGraph.Node(a); DiGraph.Node(b); DiGraph.Node(c); DiGraph.Label(a, "camera"); DiGraph.Label(b, "ambient\nlight"); DiGraph.Label(c, "vector\nlight"); DiGraph.Straight0(g, a); DiGraph.Straight0(g, b); DiGraph.Straight0(g, c) | SKIP FI; IF N >= 3 -> Rect.DrawC(j, k); PS.Stroke(); TypeLinesC.Center(j, "\"red\""); NodeToRect(f, j, k, "Surface\nColor") | SKIP FI; IF N >= 4 -> Rect.DrawC(h, i); PS.Stroke(); TypeLinesC.Center(h, "\"yellow\""); NodeToRect(g, h, i, "Surface\nColor") | SKIP FI END FI END; PROC Cmd0() IS IF VAR a = (-196.9, -26.07), b = R2.Plus(a, (58.7, 0)), c = R2.Plus(a, (252.8, 151)), i IN a HOR b -> i := 1; DO i <= 4 -> IF i > 1 -> PS.ShowPage(); PS.Reset() | SKIP FI; FigN(a, b, c, i); i := i + 1 OD END FI END;