summaryrefslogtreecommitdiffstats
path: root/virtual-programs/shapes.folk
blob: 56824eff4d6ed6d1dc04e133ec6afb91db38086f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# sides 2 => line
# sides 3 => triangle
# sides 4 => square
When /someone/ wishes to draw a shape with /...options/ {
  set numPoints [dict get $options sides]
  set c [dict get $options center]
  set r [dict get $options radius]
  set radians [dict_getdef $options radians 0]
  set color [dict_getdef $options color white]
  set filled [dict_getdef $options filled false]

  set p [list 0 0]
  set center $p
  set points [list $p]

  set incr [expr {2 * 3.14159 / $numPoints}]
  set a [expr {$incr + 3.14159}]
  for {set i 0} {$i < $numPoints} {incr i} {
    set p [vec2 add $p [vec2 scale [list [expr {cos($a)}] [expr {sin($a)}]] $r]]
    lappend points $p
    # Accumulate center
    set center [vec2 add $center $p]
    set a [expr {$a + $incr}]
  }
  set center [vec2 scale $center [expr {1.0/$numPoints}]]

  set points [lmap v $points {
      set v [vec2 sub $v $center]
      set v [vec2 rotate $v $radians]
      set v [vec2 add $v $c]
      set v
  }]

  if {$filled} {
    Wish to draw a polygon with points $points color $color
  } else {
    Wish to draw a stroke with points $points width 1 color $color
  }
}

set shapes [dict create triangle 3 square 4 pentagon 5 hexagon 6 \
                septagon 7 octagon 8 nonagon 9]
When /someone/ wishes /p/ draws a /shape/ {
  # TODO: This is a hack because rest pattern doesn't match empty
  # sequence at end.
  Wish $p draws a $shape with color white
}
When /someone/ wishes /p/ draws an /shape/ { Wish $p draws a $shape }
When /someone/ wishes /p/ draws a /shape/ with /...options/ & /p/ has region /r/ {
  lassign [region centroid $r] x y
  set width [region width $r]
  set height [region height $r]
  lassign [dict_getdef $options offset {0 0}] offsetX offsetY
  set radius [dict_getdef $options radius 50]
  set color [dict_getdef $options color white]
  set filled [dict_getdef $options filled false]
  set thickness [dict_getdef $options thickness 5]
 
  if {$offsetX != 0} {
    set x [expr {$x + $offsetX}]
  }
  if {$offsetY != 0} {
    set y [expr {$y + $offsetY}]
  }

  set angle [region angle $r]
  set p [list $x $y]

  if {$shape eq "circle"} {
      Wish to draw a circle with center $p radius $radius thickness $thickness color $color filled $filled
  } elseif {[dict exists $shapes $shape]} {
      Wish to draw a shape with sides [dict get $shapes $shape] \
          center $p radius $radius radians $angle color $color filled $filled
  } else {
      Wish to draw a shape with sides 2 \
          center $p radius $radius radians $angle color $color filled $filled
  }
}
When /someone/ wishes /p/ draws an /shape/ with /...options/ {
  Wish $p draws a $shape with {*}$options
}

Claim $this has demo {
  Wish $this draws a circle
  Wish $this draws a triangle with color skyblue
  Wish $this draws a triangle with color green offset {280 0}
  Wish $this draws a pentagon with color gold offset {200 0}
  Wish $this draws an octagon with color red offset {250 80}

  When the clock time is /t/ {
    set offsetVector [list [sin $t] [cos $t]]
    set offsetVector [::vec2::scale $offsetVector 105]
    Wish $this draws a circle with color palegoldenrod offset $offsetVector
  }

  # This toggles a square between filled and unfilled
  When $this has region /r/ & the clock time is /t/ {
    lassign [region centroid $r] x y
    set fill [expr {round(sin($t) * 2) % 2 == 0}]
    set y [- $y 150]
    Wish to draw a shape with sides 4 center [list [- $x 100] $y] radius 60 color white filled $fill
  }

  Wish $this is outlined white
}