aUCBLogo Demos and Tests / formulatest
			
				
			
			setCaseIgnored false
be formulatest
   ::formulas=
   [
      [a/((b+c)*f/g)]
      [a/((b+c)*(f/g))]
      [(A+1)/((B/(j-(g.iota)^alpha)+e)*f/g)]
      [arctan (sin Delta+Omega)^(2*pi/epsilon^zeta)/gamma y]
   ]
   cs
   setUpdateGraph false
   ht
   setLabelFont [Arial]
   setLabelSize [100 100]*0.5
   setLabelAlign 1 1
   setPenSize [5 5]*(LabelSize).1/100
   rt 90
   PenUp
   (reRandom 0)
   foreach ::formulas
   [   f1=Formula makeTree ?
      x=-400+300*(Int (#-1)/2)
      y=-290+350*(mod #-1 2)
      (f1'init x y)
      seth 90
      f1'draw
      f1'drawBoxes
   ]
   home
;   Formula::drawParen 600
   updateGraph
end
be Box
   local [x y w h]
end
be Formula expr
   local [op_ oop f1 f2 x y w h y0 paren pw]
   op_=[]
   f1=[]
   f2=[]
   paren=0
   pw=0
;   pr expr
   if isop expr.1
   [   op_=pop "expr
      if (ishorop op_) or2 op_=="/ or2 op_=="^ or2 op_==".
      [   f1=Formula expr.1
         f2=Formula expr.2
      ]
   ]
      
   be isop op_
      output op_=="* or2 op_=="+ or2 op_=="- or2 op_=="/
         or2 op_=="^ or2 op_==".
   end
   be ishorop op_
      output op_=="* or2 op_=="+ or2 op_=="-
   end
   
   be initwh oop_
      oop=oop_
      ifelse f1 != []   
      [   (f1'initwh op_)
         (f2'initwh op_)
         if ishorop op_
         [   w=opsizex.op_+(f1'w)+f2'w
            h=max f1'h f2'h
         ]
         if (op_=="* and2 (oop=="+ or2 oop=="-))
         or2 (oop=="* and2 (op_=="+ or2 op_=="-))
         or2 (oop=="^ and2 (op_=="+ or2 op_=="-))
         or2 (oop==". and2 (op_=="+ or2 op_=="-))
         [   paren=1
 ignore [
            s=(LabelSize)
            setLabelSize [1 1]*h*1.2
            psize=LabelSize "(
            setLabelSize s
            pw=psize.1*1.4
]            
            pw=h*0.3
            w=w+pw*2
         ]
         if op_=="/
         [   w=(max f1'w f2'w)+opsizex.op_*2
            h=(f1'h)+(f2'h)+opsizey.op_*2
         ]
         if op_=="^
         [   w=(f1'w)+(f2'w)+opsizex.op_*2
            h=(f1'h)+(f2'h)+opsizey.op_*2
         ]
         if op_==".
         [   w=(f1'w)+(f2'w)+opsizex.op_*2
            h=(f1'h)+(f2'h)+opsizey.op_*2
         ]
      ][   local [s]
         ifelse symboltable.expr != []
         [   s=LabelSize symboltable.expr
         ][   s=LabelSize expr
         ]
         w=s.1
         h=s.2
      ]
   end
   
   be initxy x_ y_
      x=x_
      y=y_
      if f1 != []
      [   if ishorop op_
         [   (f1'initxy x+pw*paren y)
            (f2'initxy x+pw*paren+opsizex.op_+f1'w y)
         ]
         if op_=="/
         [   mw=(max f1'w f2'w)/2
            (f1'initxy x+mw-(f1'w)/2+opsizex.op_ y+opsizey.op_)
            (f2'initxy f1'x+f1'w/2-(f2'w)/2 f1'findy0-opsizey.op_*2-(f2'h)/2)
         ]
         if op_=="^
         [   (f1'initxy x y)
            (f2'initxy f1'x+f1'w f1'findy0+f1'h/2+f2'h/2)
         ]
         if op_==".
         [   (f1'initxy x y)
            (f2'initxy f1'x+f1'w f1'findy0-f2'h/2)
         ]
      ]
   end
   
   be findy0
      ifelse f1 != []
      [   output min f1'findy0 f2'findy0
      ][   output y
      ]
   end
   
   be inity0 ymin
      ifelse f1 != []
      [   (f1'inity0 ymin)
         (f2'inity0 ymin)
         y0=findy0
      ][   y0=y-ymin
      ]
      y=y-ymin
   end
   
   be init0 x_ y_
      if f1 != []
      [   (f1'init0 x_ y_)
         (f2'init0 x_ y_)
      ]
      x=x+x_
      y=y+y_
      y0=y0+y_
   end
   be init x_ y_
      s=(LabelSize).1
      Formula::opsizex=Table (List 
         "* 0.2*s
         "+ 0.6*s
         "- 0.6*s
         "/ 0.3*s
         "^ 0
         ". 0)
      Formula::opsizey=Table (List 
         "* 0
         "+ 0
         "- 0
         "/ 0.4*s
         "^ 0
         ". 0)
      Formula::opx=Table (List 
         "* 0.00*s
         "+ 0.06*s
         "- 0.06*s
         "/ 0
         "^ 0
         ". 0)
      Formula::opy=Table (List 
         "* 0
         "+ 0
         "- 0
         "/ 0.2*s
         "^ 0
         ". 0)
      Formula::parensizex=0.3*s
      Formula::pareny=0.18
      Formula::symboltable=Table (List
         "alpha "a
         "beta "b
         "chi "c
         "delta "d
         "epsilon "e
         "gamma "g
         "eta "h
         "iota "i
         "phi "j
         "kappa "k
         "lambda "l
         "mu "m
         "nu "n
         "omikron "o
         "pi   "p
         ":pi "p
         "theta "q
         "rho "r
         "sigma "s
         "tau "t
         "omega "w
         "xi "x
         "psi "y
         "zeta "z
         
         "Alpha "A
         "Beta "B
         "Chi "C
         "Delta "D
         "Epsilon "E
         "Gamma "G
         "Eta "H
         "Iota "I
         "Phi "J
         "Kappa "K
         "Lambda "L
         "Mu "M
         "Nu "N
         "Omikron "O
         "Pi   "P
         ":Pi "P
         "Theta "Q
         "Rho "R
         "Sigma "S
         "Tau "T
         "Omega "W
         "Xi "X
         "Psi "Y
         "Zeta "Z)
      initwh []
      initxy 0 0
      inity0 findy0
      init0 x_ y_
   end
   
   be draw
      ifelse f1 != []
      [   f1'draw
         f2'draw
         setXY x+(f1'w)+opx.op_+pw*paren y+opy.op_
         lf=LabelFont
         setLabelFont [Symbol]
         if op_=="*   [Label char 215]
         if op_=="+   [Label "+]
         if op_=="-   [Label "-]
         if op_=="/   [setXY x+opsizex.op_/2 y0+f2'h+opy.op_ 
            PenDown setXY x+w-opsizex.op_/2 y0+f2'h+opy.op_ PenUp]
         if paren==1
         [   pu
            setXY x+pw/3 y0+h/2
            seth 0
            drawParen h
            setXY x+w-pw/5 y0+h/2
            seth 180
            drawParen h
            seth 90
            
ignore [
            s=(LabelSize)
            setLabelSize [1 1]*h*1.2
            setXY x y0+h*pareny
            
            Label "(
            setX x+w-pw
            Label ")
            setLabelSize s
]
         ]
         setLabelFont lf
      ][   setXY x y
         ifelse symboltable.expr != []
         [   lf=LabelFont
            setLabelFont [Symbol]
            Label symboltable.expr
            setLabelFont lf
         ][   Label expr
         ]
      ]
   end
   be drawParen h
      p0=Pos
      h0=Heading
      pd
      TessStart
      repeat 30
      [   forward h/60
         right 1
      ]
      left 1
      rt 60 fd 1.5*PenSize.1
      rt 120
      repeat Int 60*1
      [   forward h/60
         left 1
      ]
      right 1
      rt 120 fd 1.5*PenSize.1
      rt 60
      repeat 30
      [   forward h/60
         right 1
      ]
      TessEnd
      pu
   end
   
   be drawBoxes
      if f1 != []
      [   f1'drawBoxes
         f2'drawBoxes
      ]
      setXY x y0
      setFC HSBA random 360 1 1 0.3
      setH 0
      fillRect [0 0] List w h
   end   
end