Draw a Koch curve. See details: Koch curve

INCLUDE "H6:REALMATH.ACT"
 
DEFINE MAXSIZE="20"
 
INT ARRAY SinTab=[
  0 4 9 13 18 22 27 31 36 40 44 49 53 58 62 66 71 75 79 83
  88 92 96 100 104 108 112 116 120 124 128 132 136 139 143
  147 150 154 158 161 165 168 171 175 178 181 184 187 190
  193 196 199 202 204 207 210 212 215 217 219 222 224 226
  228 230 232 234 236 237 239 241 242 243 245 246 247 248
  249 250 251 252 253 254 254 255 255 255 256 256 256 256]
 
BYTE ARRAY
  depthStack(MAXSIZE),stageStack(MAXSIZE)
BYTE stacksize=[0]
 
INT FUNC Sin(INT a)
  WHILE a<0 DO a==+360 OD
  WHILE a>360 DO a==-360 OD
  IF a<=90 THEN
    RETURN (SinTab(a))
  ELSEIF a<=180 THEN
    RETURN (SinTab(180-a))
  ELSEIF a<=270 THEN
    RETURN (-SinTab(a-180))
  ELSE
    RETURN (-SinTab(360-a))
  FI
RETURN (0)
 
INT FUNC Cos(INT a)
RETURN (Sin(a-90))
 
BYTE FUNC IsEmpty()
  IF stacksize=0 THEN RETURN (1) FI
RETURN (0)
 
BYTE FUNC IsFull()
  IF stacksize=MAXSIZE THEN RETURN (1) FI
RETURN (0)
 
PROC Push(BYTE depth,stage)
  IF IsFull() THEN Break() FI
  depthStack(stacksize)=depth
  stageStack(stackSize)=stage
  stacksize==+1
RETURN
 
PROC Pop(BYTE POINTER depth,stage)
  IF IsEmpty() THEN Break() FI
  stacksize==-1
  depth^=depthStack(stacksize)
  stage^=stageStack(stacksize)
RETURN
 
PROC DrawKoch(INT x,y REAL POINTER len BYTE depth)
  BYTE stage
  INT angle=[180],c
  REAL rx,ry,r256,tmp1,tmp2
 
  IntToReal(x,rx)
  IntToReal(y,ry)
  IntToReal(256,r256)
 
  Push(depth,0)
 
  WHILE IsEmpty()=0
  DO
    Pop(@depth,@stage)
    IF depth=0 THEN
      Plot(x,y)
      ;x==+Cos(angle)*len/256
      c=Cos(angle)
      IntToRealForNeg(c,tmp1)
      RealDiv(tmp1,r256,tmp2)
      RealMult(tmp2,len,tmp1)
      RealAdd(rx,tmp1,tmp2)
      RealAssign(tmp2,rx)
      x=RealToInt(rx)
      ;y==-Sin(angle)*len/256
      c=Sin(angle)
      IntToRealForNeg(c,tmp1)
      RealDiv(tmp1,r256,tmp2)
      RealMult(tmp2,len,tmp1)
      RealSub(ry,tmp1,tmp2)
      RealAssign(tmp2,ry)
      y=RealToInt(ry)
      DrawTo(x,y)
    ELSE
      IF stage=1 THEN
        angle==-60
      ELSEIF stage=2 THEN
        angle==+120
      ELSEIF stage=3 THEN
        angle==-60
      FI
      IF stage<=3 THEN
        Push(depth,stage+1)
        Push(depth-1,0)
      FI
    FI
  OD
RETURN
 
PROC Main()
  BYTE CH=$02FC,COLOR1=$02C5,COLOR2=$02C6
  REAL len
 
  Graphics(8+16)
  Color=1
  COLOR1=$0C
  COLOR2=$02
 
  ValR("3.7",len)
  DrawKoch(10,140,len,4)
 
  DO UNTIL CH#$FF OD
  CH=$FF
RETURN