User:Brian Schott/code/turtleGraphics/2D

From J Wiki
Jump to: navigation, search

Download the script here: File:Tgsj.ijs
The script below is the original which does not use OpenGL. The downloaded script uses OpenGL.

NB. key turtle commands              ***************
NB. fd     move turtle(s) forward
NB. bk     move turtle(s) backward
NB. home   move turtle(s) to original position(s)
NB. pu     change penstate(s) to up
NB. pd     change penstate(s) to down
NB. pc     change the pencolor(s)

NB. key system status commands
NB. cs     clear the drawing screen
NB. iTS    initialize the turtle population
NB. show   report the state of the turtle(s)
NB. delay  change to slow or speed up drawings

require 'gl2 trig colortab'
coinsert'jgl2 bmsturtle'

NB. *coremove v an obverse for coinsert if 'base' = >coname ''
NB. monadic usage:        coremove 'localeOnBasesCopath'
NB. dyadic  usage: 'base' coremove 'localeOnBasesCopath'
coremove =: verb define
  y =. boxxopen y
  y coremove~ coname ''
  :
  x =. boxxopen x
  y =. boxxopen y
  x copath~ (copath x) -. y
)

NB. clear base of any 3D or Fraser Jackson turtle stuff
coremove 'bmsturtle3'
coremove 'fjturtle'
clear 'base'

delay =: 6!:3
Delay =: 0.02  NB. change to slow or speed up drawings

NB. set sm =: smoutput to see "home's" intermediate steps
sm =:[

NB. ***********************************************************
NB. Table of Contents
NB. suggesting some example moves    *************** START HERE
NB. setting global parameter values  ***************
NB.    ***begin 'bmsturtle' locale***
NB. defining some globals            ***************
NB. main turtle control              ***************
NB. main graphics initialization     ***************
NB. turtle state dbase verbs         ***************
NB. main graphics update verbs       ***************
NB. setting turtle parameter values  ***************
NB. turtle initialization verbs      ***************
NB. ***********************************************************



NB. suggesting some example moves    ***************

help =: 0 : 0
  NB. You can experiment with the system after "running"
  NB.   the script file, by placing your cursor on each
  NB.   line in turn and pressing Control-r .
  NB. It's easier to use the Control-r trick if first
  NB.   you copy this information to a "New ijs" window
  NB.   (created with "^N").
  NB. You should see the graphics screen change and you
  NB.   may get feedback on the text .ijx screen, too.

  rt 0  NB. shows the turtle's or turtles' heading(s)
  fd 0  NB. shows the turtle's or turtles' position(s)
  fd 10 _20
  rt 30 90
  fd 20 10
  rt 90 30


  cs ''
  iTS 2 NB. restores all params to original values
  rt 0  NB. shows the turtle's or turtles' heading(s)
  fd 0  NB. shows the turtle's or turtles' position(s)
  fd 10 _20
  rt 30 90
  fd 20 10
  rt 90 30

  cs ''
  ''[iTS 2 NB. output suppressed with ''[
  rt 0
  2 repeats fd 5 _5
  4 repeats do'rt 90[fd 20'   NB. do argument read from right
  4 repeats dO'fd 20[rt 90'   NB. dO argument read from  left
  SC =: SC0  NB. reinitialize StateChange database
  20 repeats do 'rt 18[5 repeats do ''rt 72[fd 13'''
  +/"_1 SC    NB. determine amount of change
  avg"_1 SC   NB. determines average change
  25 _25 (2 repeats fdrt) 30 30[cs'' NB. "fdrt" has left and right args

  cs ''
  rt 0
  fd 0
  penup 0   NB. no change to turtle 1; penup for 0
  fd 25 _25
  fd 25 _25
  show 0

  cs ''
  ''[iTS 3
  pendown 2 0  NB. no change to turtle 1, pendown turtles 0 and 2
  10 5 _5(5 repeats fdrt) 30 30 30
  show 1 2

  cs ''
  ''[iTS _5  NB. negative number for number of turtles!
  rt 0

  NB. Next example is a much more complex initialization
  NB. it suggests a manual alternative to the verb iTS
  NB. This initialization creates 2 turtles
  cs ''
  ''[".;._2 SampleTs NB. Gives two turtle samples
  NoTs =. 2
  State =: 0$~NoTs,#StateNames
  rnd State[(NoTs$ each BasicTvalues) state each BasicTnames
  NB. SC0 =: SC =: StateChange =: 0$~  NoTs,0,#StateChangeNames NB. unsparse
  SC0 =: SC =: StateChange =: $. 0$~  NoTs,0,#StateChangeNames NB. sparse
  P0 =: Position =: (NoTs,2)$0 0 250 _200
  heading =. ,"_1 rz rfd ,Heading
  position =. putP Position
  rnd State[(position;heading) state each ;:'Position Heading'
  Position =: P0
  Heading =: H0
  TNorth =: Pengap trmln getpl tfl traingle"1 putP Turtlesize
  rt 0
  2 repeats fd 10 _10
  5 _5(2 repeats fdrt)30 30
  show 1
)

coclass 'bmsturtle'           NB. give system its own locale


NB. setting global parameter values  ***************

''[do (_11}."1 COLORTABLE),"1 ',:' ,"1] _11{."1 COLORTABLE

Bkgrd =: White
Pengap =: 2
Screen_center =: 500 500
D =: Dimensions =: 2  NB. set 3D system to 2D

NB. defining some globals            ***************

NB. matrix and vector verbs
det =: -/ . *
mp =: +/ . *
mfv =: _3&(]\)"1    NB. matrix from vector


NB. verbs for drawing lines and rotating turtles
libi =: laminateInsertedBetweenItems =: ,/"_1 NB. columns stay in tact
length =: +/&.:*:"1
limitTrim =: [<.([:(<0 0)&{"2(>./@:])"2)%6: NB. 1/6th of height
Ls =: limitTrim * [: (%length) |@(-/"2@])
tfl =: tesselateForLines =: (1 1,:2 3)&(,;._3)"2
getpl =: getplough =: _3: ]\"_2 ({. , {:)"_1
trmln =: trimlines =: ]-Ls*"2[: (],:"1-@])((*@:]*<:&:|)(-/"2))

NB. some shortcuts to using 3D system for 2D & 3D turtles
MaskH =. >(D-2)&{0 1 0;1 1 1
getH =: MaskH&#"1
putH =: MaskH&expand"1   NB. not used
MaskP =. >(D-2)&{1 1 0;1 1 1
getP =: MaskP&#"1
putP =: MaskP&expand"1

NB. for hyp and angle between hyp and side of right triangle
la =: lengthangle =: *.@j./
ang =: {:@la
hyp =: {.@la

sp =: [: +/ *                     NB. sum of products
nrmlz =: ] % [: length ]
angl =: [: arccos sp&nrmlz       NB. angle between two vectors

I3 =:  =@i. 3
i3 =: I3"_
rx0=: (cos,-@sin),:(sin,cos)
ry0=: (cos,sin),:(-@sin,cos)
rz0=: rx0
bip=: <"1@(,"0/~)                 NB. Table of boxed index pairs
bipx =: (bip 1 2)"_
bipy =: (bip 2 0)"_
bipz =: (bip 0 1)"_

rx=: ''&(rx0@]`bipx`i3})"0
ry=: ''&(ry0@]`bipy`i3})"0
rz=: ''&(rz0@]`bipz`i3})"0

pitch0 =: rx
roll0  =: ry@:-
yaw0   =: rz@:-

NB. verbs for user input and output
arow =: ,"1             NB. append rows
copies =: $,:
yxs =: $~#              NB. copy x to number of y's
nneQ =: ~:&#            NB. argument #s not equal?
okvaluesQ =: [:  *./ +./@(=/)
mtQ =: 0&e.@$
changetodown =:-.@[`[`1:  @.(>:@])"0
changetoup   =:-.@[`[`0:  @.(>:@])"0
tfd =: turtlefromdegrees =: rfd @: (360&|)@:(90&+)  @: -
dft =: degreesfromturtle =: 360&| @: dfr @: (-@:(-&(pi%2)))

IVC =: InitialVerbCharacters =: a.{~91,97+i. 26
verbB =: [ e.~ [: {.&> [: ;: ] NB. creates a boolean list marking verbs
dO =: IVC&([: ". [: ; [: |. verbB <@(;:^:_1);.1 ;:@])

NB. Fraser Jackson contributed the next three verbs:
NB.  rep, repeat, and (O)on

NB.  rep Generates code to be executed
rep =: 3 : 0
  'n action' =: y
  (n*#action)$action
)

NB.  repeat displays
repeat =: 3 : 0
  ".rep y
)
NB. *then v laminates two vectors otherwise uses join
then =: 4 : 0
  dx =. $$x
  dy =. $$y
  if. (dx>2)+. dy>2 do. 'Domain Error' return. end.
  if. (dx<2)*. dy<2 do. x,:y return. end.
  x,y
)

NB.  square
NB. repeat 4 ; 'fd 30' then 'rt 90'

NB.  rotated squares
NB. repeat 24 ; (rep 4; 'fd 30' then 'rt 90') then 'rt 15'

input =: 1!:1@1:
dOO =: verb define
  90 dOO y
  :
  if. y-:'' do.y =. 5 end.
  select. input''
  case. ,'' do. return.
  case. ,'f' do. fd  y
  case. ,'r' do. rt x
  case. ,'b' do. fd  -y
  case. ,'l' do. rt -x
  end.
  x dOO y
)

NB. main turtle control              ***************

NB.* right v degrees of turn for each or all turtles
NB. usage: rt 30  or rt 30 _60 30 for three turtles
rt =: right =: monad define
if. (1<#State) *. (1=#y) do.
  y =. yxs&State y
end.
if. State nneQ ,y do.
  'Supply ',(":#State),' turn values.'
  return.
end.

NB. get State info
localnames =. 'turtleerase turtlestate heading position turtlesize'
statenames =. ;:'Turtleerase Turtlestate Heading Position Turtlesize'
(localnames) =. state each statenames

NB. erase old turtle
if. (1<:+/,turtlestate) *. 1<:+/,turtleerase do.
  tfe =. trimmed_front_edge =. libi position +"1 TNorth mp"1 2 mfv heading
  tfe erasedraw"2 1&((,turtleerase)&#)State
end.

NB. update SC and State
C =. SCN aindex 'HeadingH'
D =. - rfd 360|y
SC =: C aC D
heading =. (mfv state 'Heading') mp~"1 2 rz D
heading state 'Heading'

NB. draw new turtle
if. 1<:+/,turtlestate do.
  tfe =. trimmed_front_edge =. libi position +"1 TNorth mp"1 2 heading
  tfe objectdraw"2 1&((,turtlestate)&#)State
end.
delay Delay
glshowx ''

NB. update user's information
'Heading';Heading =: 360&|dft ang"1 getP nrmlz state 'HeadingH' NB. convert to user degrees
)

lt =: left =: monad define
rt -y
)

NB.* forward v movement distance of for each or all turtles
NB. usage: fd 10  or fd 10 _10 5 for three turtles
fd =: forward =: monad define
if. (1<#State) *. (1=#y) do.
  y =. yxs&State y
end.
if. State nneQ ,y do.
  'Supply ',(":#State),' move values.' return.
end.

NB. get State info
localnames =. 'penstate turtleerase turtlestate heading position turtlesize stepsize'
statenames =. ;:'Penstate Turtleerase Turtlestate Heading Position Turtlesize Stepsize'
(localnames) =. state each statenames

NB. erase old turtle
if. (1<:+/,turtlestate) *. 1<:+/,turtleerase do.
  tfe =. trimmed_front_edge =. libi position +"1 TNorth mp"1 2 mfv heading
  tfe erasedraw"2 1&((,turtleerase)&#)State
end.

NB. update SC and State
oldposition =. position
C =. SCN aindex 'Distance'
D =. , stepsize*y
SC =: C aC D
position =. oldposition + D * state 'HeadingH'
position state 'Position'

NB. draw new turtle
if. 1<:+/,turtlestate do.
  tfe =. trimmed_front_edge =. libi position +"1 TNorth mp"1 2 mfv heading
  tfe objectdraw"2 1&((,turtlestate)&#)State
end.

NB. draw new path
if. 1<:+/,penstate do.
  State linesdraw"1 &((,penstate)&#) oldposition arow position
end.
delay Delay
glshowx ''

NB. update user's information
'Position';Position =: getP state  'Position'
)

bk =: back =: monad define
fd -y
)

NB.* home v reset the turtles' Heading and Postion
NB.         to its/their starting value
NB.         updating StateChange, also.
NB.         Other states remain unchanged.
NB. argument can be '' or a list of turtle numbers
NB.   where turtle numbers begin with 0
home =: homeTurtleState =: monad define
if. y-:'' do.
  y =. i. #State
end.
y =. ,~. y
if. ((#State)<:>./y) do.
  'Supply only turtle values between 0 and ',(":<:#State),' .'
  return.
end.

geth =. 1&{"2             NB. get H row
NB. get State info
'position heading stepsize' =. state each ;: 'Position Heading Stepsize'

NB. put initial turtle position & heading temps
P =. (y{putP P0) y}position
H =. (y{rz rfd ,H0) y}heading =. mfv heading
distance =. length P- position

NB. in 3 steps (rt, fd, rt) execute "home"

NB. step 1
'tdet tang' =. |:(tpos =. P-position) ((*@det@,:),angl)&getP thead =.  geth heading

turn =. i. 0
for. i. # tdet do.
  if. {.tdet do.
    turn =. turn,(*@{.tdet)*{.tang
  else.
    turn =. turn,(0,pi){.~*tpos mp&(*@{.) thead
  end.
  tdet =. }. tdet
  tpos =. }. tpos
  tang =. }. tang
  thead =. }. thead
end.
sm 'rt ',":[tmp =. 360&|dfr turn
sm rt tmp

NB. step 2
sm 'fd ',":[tmp =. distance%,stepsize
sm fd tmp

NB. step 3
'tdet tang' =. |:(tpos =. geth H) ((*@det@,:),angl)&getP thead =. state'HeadingH'

turn =. i. 0
for. i. # tdet do.
  if. {.tdet do.
    turn =. turn,(*@{.tdet)*{.tang
  else.
    turn =. turn,(0,pi){.~*tpos mp&(*@{.) thead
  end.
  tdet =. }. tdet
  tpos =. }. tpos
  tang =. }. tang
  thead =. }. thead
end.
sm 'rt ',":[tmp =. ,360&|dfr turn
rt tmp
)


NB.* penup v make turtle path for turtles listed by number
NB. usage: penup '' or penup 0 1 2 3 for all four turtles
pu =: penup =: monad define
if. y-:'' do.
  y =. i. #State
end.
y =. ,~. y
if. ((#State)<:>./y) do.
  'Supply only turtle values between 0 and ',(":<:#State),' .'
  return.
end.

NB. update SC and State
oldpenstate =. state 'Penstate'
penstate =. 0 y} oldpenstate
D =. penstate - oldpenstate
C =. SCN aindex 'Penstate'
SC =: C aC D
penstate state 'Penstate'

NB. update user's info
Penstate =: ,state 'Penstate'
'Penstate';,Penstate
)

NB.* pendown v make turtle path for turtles listed by number
NB. usage: pendown '' or pendown 0 1 2 3 for all four turtles
pd =: pendown =: monad define
if. y-:'' do.
  y =. i. #State
end.
y =. ,~. y
if. ((#State)<:>./y) do.
  'Supply only turtle values between 0 and ',(":<:#State),' .'
  return.
end.

NB. update SC and State
oldpenstate =. state 'Penstate'
penstate =. 1 y} oldpenstate
D =. penstate - oldpenstate
C =. SCN aindex 'Penstate'
SC =: C aC D
penstate state 'Penstate'

NB. update user's info
Penstate =: ,state 'Penstate'
'Penstate';Penstate
)

pencolor =: verb define
  NB.* pencolor v [indices of turtles] pencolor colors to assign
  NB. See the list of colors by typing COLORTABLE.
  NB. Turtle indices are 0 1 2 ...
  y pencolor~i.#State
  :
  x =. ,x
  if. (y nneQ x) *. 1~:#y do.
    'The number of colors must be 1 or the same as the number of turtles listed.'
    return.
  end.
  if. (1<#y) *.x nneQ y do.
    'Supply 1 or ',(":#x),' pencolor values.' return.
  end.

  NB. update SC and State
  oldpencolor =. state 'Pencolor'
  newpencolor =. (((#x),3)$,y) x} oldpencolor
  D =. newpencolor - oldpencolor
  C =. SCN aindex 'Pencolor'
  SC =: C aC1 D
  newpencolor state 'Pencolor'

  NB. update user's info
  Pencolor =: state 'Pencolor'
  'Pencolor';Pencolor
)

NB. enable one-liner turtle movement sequences
repeats =: conjunction define
  for. i. m
  do. v y
  end.
  :
  for. i. m
  do. x v y
  end.
)

NB. a handy verb that combines J and turtle commands
rtfd =: rightforward =: dyad define
rt x
fd y
)

NB. a handy verb that combines J and turtle commands
fdrt =: forwardright =: dyad define
fd x
rt y
)

NB.* show v show values of the turtle parameters
NB. argument can be '' or a list of turtle numbers
NB.   where turtle numbers begin with 0
NB. also note that output of "heading" is in radians
show =: showTurtleState =: monad define
if. y-:'' do.
  y =. i. #State
end.
y =. ,~. y
if. ((#State)<:>./y) do.
  'Supply only turtle values between 0 and ',(":<:#State),' .'
  return.
end.
NB. prints heading in radians, not degrees -- all in columns
NB. BasicTnames,. y&{ each state each BasicTnames

NB. prints some facts in rows and some in columns
NB. because global singleton values are saved indiviually as rows
BasicTnames,. y&{ each do each BasicTnames
)

NB. The next two verbs are rather complex and should be used
NB.    with care by experienced users.
NB.* pendownchange v make turtle path show or change status of penstate
NB. usage: pendownchange 1 or pendownchange 0 1 _1 1 for four turtles
NB. arg values of  1 mean put the penstates to pendown
NB. arg values of _1 mean to reverse the current penstates
NB. arg values of 0 mean NOT to change the penstates
pendownchange =: monad define
  if. (1<#,y) *. 0=+/,|y do.
    'Use penupchage to set penstates to penup.'
    return. end.
    if. (-. mtQ,y) *. -. _1 0 1 &okvaluesQ ,y do.
      'Supply only _1s, zeros and ones.'
      return.
    end.
    if. (1<#,y) *.State nneQ ,y do.
      'Supply 1 or ',(":#State),' pendownchange (_1, 0, or 1) values.'
      return.
    end.
    oldpenstate =. state 'Penstate'
    if. (y-:'') +. (y-:1) do.
      y =.  yxs&State 1
    else.
      y =. ,y
    end.
    penstate =. oldpenstate changetodown y
    D =. |penstate - oldpenstate
    C =. SCN aindex 'Penstate'
    SC =: C aC D
    N =. SN aindex 'Penstate'
    State =: N aS penstate
    Penstate =: ,state 'Penstate'
    'Penstate';Penstate
)

NB.* penupchange v hide turtle path or change status of penstate
NB. usage: penupchange 1 or penupchange 0 1 _1 1 for four turtles
NB. arg values of 1 mean put the penstates to penup
NB. arg values of _1 mean to reverse the current penstates
NB. arg values of 0 mean NOT to change the penstates
penupchange =: monad define
  if. (1<#,y) *. 0=+/,|y
  do. 'Use pendownchange to set penstates to pendown.'
    return.
  end.
  if. (-. mtQ,y) *. -. _1 0 1 &okvaluesQ ,y
  do. 'Supply only _1s, zeros and ones.'
    return.
  end.
  if. (1<#,y) *.State nneQ ,y do.
    'Supply 1 or ',(":#State),' penupchange (_1, 0 or 1) values.'
    return.
  end.
  oldpenstate =. state 'Penstate'
  if. (y-:'') +. (y-:1) do.
    Penstate =:  yxs&State 0
  else. y =. ,y
  end.
  penstate =. oldpenstate changetoup y
  D =. |penstate - oldpenstate
  C =. SCN aindex 'Penstate'
  SC =: C aC D
  N =. SN aindex 'Penstate'
  State =: N aS penstate
  Penstate =: ,state 'Penstate'
  'Penstate';Penstate
)

NB. main graphics initialization     ***************

SCREEN =: noun define
  pc Screen;
  xywh 6 6 100 100;cc Left isigraph rightmove bottommove;
  pas 6 6;pcenter;ptop;
  rem form end;
)

Screen_run =: monad define
wd SCREEN
wd 'pshow;'
wd 'psel Screen'
)

tgsj_run =: monad define
if. -. (502 <: ".1 2 3&{  9!:14 '') do.
  'You must be using a J version 5.02a or later.'
  return.
end.
smoutput 'Look for examples near the beginning of the script.'

NB. creates user's info for sample data
''[".;._2 SampleTs NB. Gives two turtle samples

NB. initialize shell State database
State0 =: State =: 0$~2,#StateNames
SampleTvalues state each BasicTnames

NB. initialize special user info
Heading =: 360&| dfr arccos getH nrmlz state 'HeadingH'

NB. initialize shell SC database
NB. SC0 =: SC =: StateChange =: 0$~  (|y),0,#StateChangeNames NB. unsparse
SC0 =: SC =: StateChange =: $. 0$~  2,0,#StateChangeNames NB. sparse

NB. initialize shell turtle
TNorth =: Pengap trmln getpl tfl traingle"1 putP Turtlesize

if. y do.  Screen_run '' end.

rt 0
smoutput 'type "help" for a very little'
)

Screen_close=: 3 : 0
wd'pclose'
)

NB. turtle state dbase verbs         ***************

yfx =: {."1~ #@]                 NB. (#y) taken from x
amemb =: ,:@] {."1@:E. yfx       NB. all members of y in x
aindex =: amemb # i.@#@[         NB. all indices of y in x
num =: [:{:2:{.!.1 $             NB. columns of matrix or 1 for vector
rnd =: <.@(0.5&+)                NB. can round off State/SC output


NB. for updating the turtle state array
aS =: alterState =: 4 : 'y  ({;&x i.@#State)}State'

NB.  State is queried or modified by state
NB.  Notice that in dyadic use, global State is modified*****
NB.* state v retrieve y in State : x amends y, and State is updated
NB.  usage: heading =. state 'Heading'
NB.         state each ;:'Heading Position'
NB.         (0 0;750 300,:~Screen_center)state each ;:'Heading Position'
state =: verb define
  State {"1~ SN aindex y
  :
  i =. SN aindex y
  if. ($,.x) -: $State {"1~i do.
    State =: (,.x) ({;&i i.@#State)} State
  else.
    smoutput 'The shape of ',y,' in State is different from ',": x
    return.
  end.
)


NB. below is for summarizing or modifiying SC (StateChange dbase)
NB. useful for averaging state-change dbase
avg =: +/ % +/@(~:&0)  NB. denominator counts ~:0

NB. for updating the turtle state-change history array
NB.   when the trait is a scalar
NB.  Notice that in dyadic use, global SC is modified*****
aC =: appendChange =: dyad define
filler =. 0$~(#y),#SCN
SC,"_1 y x }"0 1 filler
)

NB. for updating the turtle state-change history array
NB.   when the trait is a vector
NB.  Notice that in dyadic use, global SC is modified*****
aC1 =: appendChange =: dyad define
filler =. 0$~(#y),#SCN
SC,"_1 y x }"1 filler
)

NB.* sc v retrieve y in SC : x appends y, and SC is updated
NB.  usage: (0 0;20 50) sc each"0 ;:'HeadingH Distance'
NB.      above example is for two-turtles state
NB.  Notice that in dyadic use, global State is modified*****
sc =: verb define
  ;/SC {"1~ SCN aindex y
  :
  i =. SCN aindex y
  if. ($,.x) -: ${:"_1 SC {"1~i do.
    filler =. 0$~(#x),#SCN
    SC =: SC,"_1 (,.x) ({;&i i.@#State)} filler
    sc y          NB. verb is recursive
  else.
    'The shape of ',y,' in SC is different from ',": x
  end.
)

NB. main graphics update verbs       ***************

objectdraw =: dyad define
  x =. , Screen_center +"1 getP x
  turtlecolor =. y{~ SN aindex 'Turtlecolor'
  pensize =. y{~ SN aindex 'Pensize'
  penstyle =. y{~ SN aindex 'Penstyle'
  wd'psel Screen'
  glmap MM_DEFAULT
  glrgb Red
  glbrush''
  glrgb turtlecolor
  glpen pensize , penstyle
  gllines  "1 x
  NB. glshowx''
)

erasedraw =: dyad define
  x =. , Screen_center +"1 getP x
  pensize =. y{~ SN aindex 'Pensize'
  penstyle =. y{~ SN aindex 'Penstyle'
  wd'psel Screen'
  glmap MM_DEFAULT
  glrgb Red
  glbrush''
  glrgb Bkgrd
  glpen pensize , penstyle
  gllines  "1  x
  NB. glshowx''
)

linesdraw =: dyad define
  y =. ,Screen_center +"1 getP&mfv y
  pencolor =. x{~ SN aindex 'Pencolor'
  pensize =. x{~ SN aindex 'Pensize'
  penstyle =. x{~ SN aindex 'Penstyle'
  wd'psel Screen'
  glmap MM_DEFAULT
  glrgb Red
  glbrush''
  glrgb pencolor
  glpen pensize, penstyle
  gllines y
  NB. glshowx''
)

cs =: clearscreen =: monad define
wd'psel Screen'
glclear ''
glmap MM_DEFAULT
glshow''
)

NB. setting turtle parameter values  ***************

BasicTnames =: <;._2 noun define
Position
Heading
Pencolor
Pensize
Penstyle
Turtlecolor
Turtlesize
Turtleploughshape
Penstate
Turtlestate
Turtleerase
Stepsize
)

SampleTs =: noun define
  P0 =: Position =: getP 2 3$0 0 0 250 _200 0
  H0 =: Heading =: 0,:90
  Pencolor  =: Black,Blue
  Pensize =: 2 3
  Penstyle =: 0 0
  Turtlecolor =: Red,Blue
  Turtlesize =: getP 12 51 0,:9 30 0 NB. (halfwidth,height)
  Turtleploughshape =: 1 1
  Penstate =: 1 1
  Turtlestate =: 1 1
  Turtleerase =: 1 1
  Stepsize =: 5 5
)

SampleTvalues =: <@". ;._2 noun define
2 3$0 0 0 250 _200 0
,"_1 rz 0,pi%2
Black,Blue
2 3
0 0
Red,Blue
putP 12 51,:9 30
1 1
1 1
1 1
1 1
5 5
)

SN =: StateNames =: ];._2 ] 0 : 0
PositionX
PositionY
PositionZ
HeadingLX
HeadingLY
HeadingLZ
HeadingHX
HeadingHY
HeadingHZ
HeadingUX
HeadingUY
HeadingUZ
PencolorR
PencolorG
PencolorB
Penstate
Pensize
Penstyle
Turtlestate
Turtleerase
TurtlecolorR
TurtlecolorG
TurtlecolorB
TurtlesizeW
TurtlesizeH
TurtlesizeZ
Turtleploughshape
Stepsize
)

SCN =: StateChangeNames =: ];._2 ] 0 : 0
HeadingLD
HeadingHD
HeadingUD
DistanceD
PencolorRD
PencolorGD
PencolorBD
PenstateD
PensizeD
PenstyleD
TurtlestateD
TurtleeraseD
TurtlecolorRD
TurtlecolorGD
TurtlecolorBD
TurtlesizeWD
TurtlesizeHD
TurtlesizeZD
TurtleploughshapeD
Stepsize
)

BasicTvalues =: <@". ;._2 noun define
putP 1 2$0 0
,:1 0 0 0 1 0 0 0 1
Black
2
0
Blue
putP ,:9 30
1
1
1
1
5
)

NB. turtle initialization verbs      ***************

NB.* tP v ambivalent produces initial Turtle positions on unit circle
NB. usage: [radius] tP no_of_turtles
NB. positive y produces equi-distant turtles
NB. negative y produces turtles of random distance
NB. programmed by Paul Chapmans
regular =. i. % ]
irregular =. (? % ])&1000000@|
list =. irregular`regular@.(= |)@]
thetas =. 2p1"_ * list
r =. * (| > 1:)
tP =: turtlePosition =: (1: $: ]) : (r +.@r. thetas) f.

NB. usage: traingle"1 Turtlesize
NB. turtles start heading up, but math "0" faces right
oft =: originforturtles =: 0:,1&{,0:
mults =: 0 1 2 0 3 2 1 3{4 3$1 _1 0 0 0 0 0 _1 1 _1 _1 0
traingle =: oft+"1 *"1/&mults

NB.* initTurtleState v (ambivalent)
NB. usage: [rows of (x,y) headings] initTStateBasic (no. of Ts)
NB. eg. (2 1$ 90 45         ) iTS 2  NB. create 2 identical turtles
NB.           iTS  4                 NB. create 4 identical turtles
NB.           iTS _4                 NB. create 4 identical turtles
iTS =: initTurtleState =: verb define
y iTS~ 0#~|y
:
y =. | y
if. y~:#x  do.
  'The number of turtle headings must equal the number of turtles.'
  return.
end.
if. (~:<.)y do.
  'Number of Turtles must be integer.'
  return.
end.

NB. initialize default State
State =:  0$~y,#StateNames
(y&# each BasicTvalues) state each BasicTnames

NB. initialize user info
P0 =: Position =: 200 tP y
H0 =: Heading =: x

NB. convert user info to dbase format
heading =. ,"_1 rz rfd ,Heading
position =. putP Position

NB. revise default State
(position;heading) state each ;:'Position Heading'

NB. revise user info
(BasicTnames) =: state each BasicTnames
Position =: P0
Heading =: H0
Turtlesize =: getP Turtlesize

NB. keep copy of initial State
State0 =: State

NB. create State Change shell
NB. SC0 =: SC =: StateChange =: 0$~  y,0,#StateChangeNames NB. unsparse
SC0 =: SC =: StateChange =: $. 0$~  y,0,#StateChangeNames NB. sparse

NB. initialize turtle shape
TNorth =: Pengap trmln getpl tfl traingle"1 putP Turtlesize

rt 0
StateNames;|:State0
)

coclass 'base'
NB. To initialize tgsj WITHOUT a new viewing screen,
NB.     supply a zero argument: tgsj_run 0 .
tgsj_run ''