summaryrefslogtreecommitdiff
path: root/ipl/gprogs/subdemo.icn
diff options
context:
space:
mode:
Diffstat (limited to 'ipl/gprogs/subdemo.icn')
-rw-r--r--ipl/gprogs/subdemo.icn264
1 files changed, 264 insertions, 0 deletions
diff --git a/ipl/gprogs/subdemo.icn b/ipl/gprogs/subdemo.icn
new file mode 100644
index 0000000..881d888
--- /dev/null
+++ b/ipl/gprogs/subdemo.icn
@@ -0,0 +1,264 @@
+############################################################################
+#
+# File: subdemo.icn
+#
+# Subject: Program to show the turtle graphics subset
+#
+# Author: Gregg M. Townsend
+#
+# Date: May 31, 1994
+#
+############################################################################
+#
+# This file is in the public domain.
+#
+############################################################################
+#
+# subdemo displays various random designs in a window using the
+# turtle graphics subset library procedures. Click in the window,
+# or enter a character on the keyboard, to start a new design.
+#
+# The following keyboard characters have meaning:
+#
+# w or W: random walk
+# b or B: fractal bush (looks like "desert broom")
+# s or S: spiral design
+# p or P: polygon design
+# t or T: rectangular tiling
+# r or R: radial tiling
+#
+# \n, \r, \t, or SP: choose design randomly
+# q or Q: exit program
+#
+# 0: pause drawing
+# 1, ... 9: set speed of drawing (9 is fastest)
+#
+############################################################################
+#
+# Requires: Version 9 graphics
+#
+############################################################################
+#
+# Links: options, optwindw, subturtl, random, graphics
+#
+############################################################################
+
+link options
+link optwindw
+link subturtl
+link random
+link graphics
+
+global msec # delay between drawing actions
+global event # interrupting event, if any
+
+procedure main(args)
+ local opts, dlist, p, e
+
+ opts := options(args, winoptions())
+ /opts["W"] := /opts["H"] := 500
+ &window := optwindow(opts)
+
+ randomize()
+ dlist := [walk, bush, poly, spiral, tile, radial]
+ msec := 0
+ event := "\r"
+ repeat {
+ e := \event | Event()
+ event := &null
+ case e of {
+ QuitEvents(): break
+ "\n" | "\r" | "\t" | " ": run(?dlist)
+ &lrelease | &mrelease | &rrelease: run(?dlist)
+ "b" | "B": run(bush)
+ "w" | "W": run(walk)
+ "s" | "S": run(spiral)
+ "p" | "P": run(poly)
+ "t" | "T": run(tile)
+ "r" | "R": run(radial)
+ "0"|"1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9": setdelay(e)
+ }
+ }
+end
+
+# run(p) -- execute procedure p after resetting screen environment
+
+procedure run(p)
+ TReset()
+ return p()
+end
+
+# continue() -- delay and check for interrupts
+#
+# Every demo should call this periodically and should exit if it fails.
+# The global "event" is set to the interrupting event and can be checked
+# to exit from recursive calls.
+
+procedure continue()
+ local evlist
+
+ event := &null
+ delay(msec)
+ if *Pending() = 0 then
+ return
+ event := Event()
+ if setdelay(event) then {
+ event := &null
+ return
+ }
+ else
+ fail
+end
+
+# setdelay(e) -- handle delay-setting event, or fail
+
+procedure setdelay(e)
+ while e === "0" do # 0 is pause -- wait until anything else input
+ e := Event()
+ if type(e) == "string" & *e = 1 & (e ? any(&digits)) then {
+ if e === "9" then
+ msec := 0
+ else
+ msec := ishift(1, 12 - e)
+ return
+ }
+ else
+ fail
+end
+
+
+#################### drawing routines ####################
+
+
+procedure walk() # random walk
+ local stepsize, maxturn, bias
+
+ maxturn := 30
+ bias := 1
+ while continue() do
+ every 1 to 10 do {
+ TDraw(1)
+ TRight(?maxturn - maxturn/2.0 + bias)
+ }
+end
+
+
+procedure bush(n, len) # fractal bush
+ local maxturn
+
+ if /n then {
+ TSkip(-150)
+ n := 4 + ?4
+ len := 400 / n
+ }
+ maxturn := 60
+ TSave()
+ TRight(?maxturn - maxturn / 2.0)
+ TDraw(?len)
+ if n > 0 & /event then {
+ continue()
+ every 1 to ?4 do
+ bush(n - 1, len)
+ }
+ TRestore()
+end
+
+
+procedure poly() # regular nonconvex polygon
+ local angle, side, x0, y0
+ angle := 60 + ?119
+ side := 200 - 100 * cos(dtor(angle))
+ x0 := WAttrib("width") / 2 - side / 2
+ y0 := WAttrib("height") / 2 - side / 3
+ TGoto(x0, y0)
+ TLeft(THeading()) # set heading to zero (East)
+ while continue() do {
+ TDraw(side)
+ TRight(angle)
+ if abs(TX() - x0) + abs(TY() - y0) < 1 then break
+ }
+end
+
+
+procedure spiral() # polygon spiral
+ local angle, side, incr
+ angle := 30 + ?149
+ incr := sqrt(4 * ?0) + 0.3
+ side := 0
+ while side < 1000 & continue() do {
+ TDraw(side +:= incr)
+ TRight(angle)
+ }
+end
+
+
+procedure tile()
+ local i, j, n, x0, y0, x, y, dx, dy, f, m
+
+ n := 5
+ x0 := WAttrib("width") / 2
+ y0 := WAttrib("height") / 2
+ dx := x0 / n
+ dy := y0 / n
+ f := mkfig(?10)
+ x := dx / 2
+ m := dx + dy
+ every i := 1 to n do {
+ y := dy / 2
+ every j := 1 to n do {
+ THeading(45)
+ TGoto(x0 + x, y0 + y); every 1 to 4 do { putfig(f, m); TRight(90) }
+ TGoto(x0 + x, y0 - y); every 1 to 4 do { putfig(f, m); TRight(90) }
+ TGoto(x0 - x, y0 + y); every 1 to 4 do { putfig(f, m); TRight(90) }
+ TGoto(x0 - x, y0 - y); every 1 to 4 do { putfig(f, m); TRight(90) }
+ y +:= dy
+ if not continue() then
+ return
+ }
+ x +:= dx
+ }
+end
+
+
+procedure radial()
+ local f, i, j, nrings, rwidth, fwd, circ, nfig, da
+
+ f := mkfig(?8)
+ nrings := 5
+ rwidth := WAttrib("width") / (2 * nrings)
+ every i := 1 to nrings do {
+ circ := &pi * 2 * i * rwidth
+ nfig := integer(circ / 50)
+ nfig := nfig / 2 + ?nfig
+ da := 360.0 / nfig
+ every j := 0 to nfig-1 do {
+ TGoto(WAttrib("width") / 2, WAttrib("height") / 2)
+ TRight(-THeading() + 90 - j * da)
+ TSkip(rwidth * (i - 0.9))
+ putfig(f, rwidth)
+ if not continue() then
+ return
+ }
+ }
+end
+
+
+procedure mkfig(nseg)
+ local f
+ f := []
+ every 1 to nseg do {
+ put(f, ?0 / nseg) # draw
+ put(f, -90 + 180 * ?0) # turn
+ }
+ return f
+end
+
+procedure putfig(f, m)
+ local i
+ TSave()
+ every i := 1 to *f by 2 do {
+ TDraw(m * f[i])
+ TRight(f[i+1])
+ }
+ TRestore()
+end