MODULE Spiral; IMPORT Geometry, PS, Math, R2; VAR rot := 10; (* number of rotations *) PRIVATE CONST resolution = 0.5; /* the degree of resolution -- the greater the value, the larger the number of segments used to construct the spiral, so the smoother the overall result */ PRIVATE CONST MaxPathSize = 500; /* maximum number of segments in path allowed before stroking; this is to avoid a PostScript "limitcheck" error when printing to a PostScript device */ PROC Archimedes(a, b) IS PS.MoveTo(a); VAR i, r, theta, n, p, pathSz IN i := 1; pathSz := MaxPathSize; n := CEILING(resolution * rot * Geometry.Dist(a, b)); DO i <= n -> r := i / n; theta := 2 * rot * Math.Pi * r; p := (r * COS(theta), r * SIN(theta)) REL (a, b); PS.LineTo(p); i := i + 1; IF pathSz = 0 -> PS.Stroke(); PS.MoveTo(p); pathSz := MaxPathSize | pathSz := pathSz - 1 FI OD END; PS.Stroke() END; UI PointTool(Archimedes); (* Draw an Archimedian spiral with center "a" and endpoint "b". The spiral contains a total of "rot" rotations. *) PROC Cmd0() IS IF VAR a = R2.Origin, b ~ (138.22218, 0) IN a HOR b -> Archimedes(a, b) END FI END;