chiark / gitweb /
quacks-ingredients: wip counts
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 16 Feb 2020 21:08:39 +0000 (21:08 +0000)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 16 Feb 2020 21:08:39 +0000 (21:08 +0000)
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
quacks-ingredients-counts
quacks-ingredients-counts.scad

index 870970a9c718d296b1aca93b2a98ac8780ae34b1..6ee3500196c5dcf72a75a6b7003f9b09409d6233 100755 (executable)
@@ -29,16 +29,17 @@ sub wrtoplevel () {
     my $nrows = ceil($total / $rowsz);
     my $ix = 0;
     print "// total=$total, rowsz=$rowsz, nrows=$nrows\n";
-    foreach my $ndots (sort keys %$cs) {
-       my $c = $cs->{$ndots};
+    foreach my $nspots (sort keys %$cs) {
+       my $c = $cs->{$nspots};
        print <<END;
   union(){
-    \$ndots = $ndots;
+    Frame(\$phase, token_pitch * [ $rowsz + 0.5, $nrows ]);
+    \$nspots = $nspots;
 END
        while ($c--) {
            my $xy = sprintf "[ %5.1f, %5.1f ]",
-               $ix / $nrows - 0.5 * $rowsz,
-               $ix % $nrows - 0.5 * $nrows;
+               int($ix / $nrows) - 0.5 * ($rowsz-1),
+               $ix % $nrows - 0.5 * ($nrows-1);
            print "    translate(token_pitch * $xy) Token_L();\n";
            $ix++;
        }
index 97503e3c002de0d9f282b7e1dc07f947b20b113e..1c33a55bcca6054dbb6d1da992cdb9dcc3fd8d32 100644 (file)
 module Black(){ ////toplevel
 // total=18, rowsz=5, nrows=4
   union(){
-    $ndots = 1;
-    translate(token_pitch * [  -2.5,  -2.0 ]) Token_L();
-    translate(token_pitch * [  -2.2,  -1.0 ]) Token_L();
-    translate(token_pitch * [  -2.0,   0.0 ]) Token_L();
-    translate(token_pitch * [  -1.8,   1.0 ]) Token_L();
-    translate(token_pitch * [  -1.5,  -2.0 ]) Token_L();
-    translate(token_pitch * [  -1.2,  -1.0 ]) Token_L();
-    translate(token_pitch * [  -1.0,   0.0 ]) Token_L();
-    translate(token_pitch * [  -0.8,   1.0 ]) Token_L();
-    translate(token_pitch * [  -0.5,  -2.0 ]) Token_L();
-    translate(token_pitch * [  -0.2,  -1.0 ]) Token_L();
-    translate(token_pitch * [   0.0,   0.0 ]) Token_L();
-    translate(token_pitch * [   0.2,   1.0 ]) Token_L();
-    translate(token_pitch * [   0.5,  -2.0 ]) Token_L();
-    translate(token_pitch * [   0.8,  -1.0 ]) Token_L();
-    translate(token_pitch * [   1.0,   0.0 ]) Token_L();
-    translate(token_pitch * [   1.2,   1.0 ]) Token_L();
-    translate(token_pitch * [   1.5,  -2.0 ]) Token_L();
-    translate(token_pitch * [   1.8,  -1.0 ]) Token_L();
-  };
-  union(){
-    $ndots = 2;
-  };
-  union(){
-    $ndots = 3;
-  };
-  union(){
-    $ndots = 4;
+    Frame($phase, token_pitch * [ 5 + 0.5, 4 ]);
+    $nspots = 1;
+    translate(token_pitch * [  -2.0,  -1.5 ]) Token_L();
+    translate(token_pitch * [  -2.0,  -0.5 ]) Token_L();
+    translate(token_pitch * [  -2.0,   0.5 ]) Token_L();
+    translate(token_pitch * [  -2.0,   1.5 ]) Token_L();
+    translate(token_pitch * [  -1.0,  -1.5 ]) Token_L();
+    translate(token_pitch * [  -1.0,  -0.5 ]) Token_L();
+    translate(token_pitch * [  -1.0,   0.5 ]) Token_L();
+    translate(token_pitch * [  -1.0,   1.5 ]) Token_L();
+    translate(token_pitch * [   0.0,  -1.5 ]) Token_L();
+    translate(token_pitch * [   0.0,  -0.5 ]) Token_L();
+    translate(token_pitch * [   0.0,   0.5 ]) Token_L();
+    translate(token_pitch * [   0.0,   1.5 ]) Token_L();
+    translate(token_pitch * [   1.0,  -1.5 ]) Token_L();
+    translate(token_pitch * [   1.0,  -0.5 ]) Token_L();
+    translate(token_pitch * [   1.0,   0.5 ]) Token_L();
+    translate(token_pitch * [   1.0,   1.5 ]) Token_L();
+    translate(token_pitch * [   2.0,  -1.5 ]) Token_L();
+    translate(token_pitch * [   2.0,  -0.5 ]) Token_L();
+  };
+  union(){
+    Frame($phase, token_pitch * [ 5 + 0.5, 4 ]);
+    $nspots = 2;
+  };
+  union(){
+    Frame($phase, token_pitch * [ 5 + 0.5, 4 ]);
+    $nspots = 3;
+  };
+  union(){
+    Frame($phase, token_pitch * [ 5 + 0.5, 4 ]);
+    $nspots = 4;
   };
 }
 module Blue(){ ////toplevel
 // total=34, rowsz=6, nrows=6
   union(){
-    $ndots = 1;
-    translate(token_pitch * [  -3.0,  -3.0 ]) Token_L();
-    translate(token_pitch * [  -2.8,  -2.0 ]) Token_L();
-    translate(token_pitch * [  -2.7,  -1.0 ]) Token_L();
-    translate(token_pitch * [  -2.5,   0.0 ]) Token_L();
-    translate(token_pitch * [  -2.3,   1.0 ]) Token_L();
-    translate(token_pitch * [  -2.2,   2.0 ]) Token_L();
-    translate(token_pitch * [  -2.0,  -3.0 ]) Token_L();
-    translate(token_pitch * [  -1.8,  -2.0 ]) Token_L();
-    translate(token_pitch * [  -1.7,  -1.0 ]) Token_L();
-    translate(token_pitch * [  -1.5,   0.0 ]) Token_L();
-    translate(token_pitch * [  -1.3,   1.0 ]) Token_L();
-    translate(token_pitch * [  -1.2,   2.0 ]) Token_L();
-    translate(token_pitch * [  -1.0,  -3.0 ]) Token_L();
-    translate(token_pitch * [  -0.8,  -2.0 ]) Token_L();
-  };
-  union(){
-    $ndots = 2;
-    translate(token_pitch * [  -0.7,  -1.0 ]) Token_L();
-    translate(token_pitch * [  -0.5,   0.0 ]) Token_L();
-    translate(token_pitch * [  -0.3,   1.0 ]) Token_L();
-    translate(token_pitch * [  -0.2,   2.0 ]) Token_L();
-    translate(token_pitch * [   0.0,  -3.0 ]) Token_L();
-    translate(token_pitch * [   0.2,  -2.0 ]) Token_L();
-    translate(token_pitch * [   0.3,  -1.0 ]) Token_L();
-    translate(token_pitch * [   0.5,   0.0 ]) Token_L();
-    translate(token_pitch * [   0.7,   1.0 ]) Token_L();
-    translate(token_pitch * [   0.8,   2.0 ]) Token_L();
-  };
-  union(){
-    $ndots = 3;
-  };
-  union(){
-    $ndots = 4;
-    translate(token_pitch * [   1.0,  -3.0 ]) Token_L();
-    translate(token_pitch * [   1.2,  -2.0 ]) Token_L();
-    translate(token_pitch * [   1.3,  -1.0 ]) Token_L();
-    translate(token_pitch * [   1.5,   0.0 ]) Token_L();
-    translate(token_pitch * [   1.7,   1.0 ]) Token_L();
-    translate(token_pitch * [   1.8,   2.0 ]) Token_L();
-    translate(token_pitch * [   2.0,  -3.0 ]) Token_L();
-    translate(token_pitch * [   2.2,  -2.0 ]) Token_L();
-    translate(token_pitch * [   2.3,  -1.0 ]) Token_L();
-    translate(token_pitch * [   2.5,   0.0 ]) Token_L();
+    Frame($phase, token_pitch * [ 6 + 0.5, 6 ]);
+    $nspots = 1;
+    translate(token_pitch * [  -2.5,  -2.5 ]) Token_L();
+    translate(token_pitch * [  -2.5,  -1.5 ]) Token_L();
+    translate(token_pitch * [  -2.5,  -0.5 ]) Token_L();
+    translate(token_pitch * [  -2.5,   0.5 ]) Token_L();
+    translate(token_pitch * [  -2.5,   1.5 ]) Token_L();
+    translate(token_pitch * [  -2.5,   2.5 ]) Token_L();
+    translate(token_pitch * [  -1.5,  -2.5 ]) Token_L();
+    translate(token_pitch * [  -1.5,  -1.5 ]) Token_L();
+    translate(token_pitch * [  -1.5,  -0.5 ]) Token_L();
+    translate(token_pitch * [  -1.5,   0.5 ]) Token_L();
+    translate(token_pitch * [  -1.5,   1.5 ]) Token_L();
+    translate(token_pitch * [  -1.5,   2.5 ]) Token_L();
+    translate(token_pitch * [  -0.5,  -2.5 ]) Token_L();
+    translate(token_pitch * [  -0.5,  -1.5 ]) Token_L();
+  };
+  union(){
+    Frame($phase, token_pitch * [ 6 + 0.5, 6 ]);
+    $nspots = 2;
+    translate(token_pitch * [  -0.5,  -0.5 ]) Token_L();
+    translate(token_pitch * [  -0.5,   0.5 ]) Token_L();
+    translate(token_pitch * [  -0.5,   1.5 ]) Token_L();
+    translate(token_pitch * [  -0.5,   2.5 ]) Token_L();
+    translate(token_pitch * [   0.5,  -2.5 ]) Token_L();
+    translate(token_pitch * [   0.5,  -1.5 ]) Token_L();
+    translate(token_pitch * [   0.5,  -0.5 ]) Token_L();
+    translate(token_pitch * [   0.5,   0.5 ]) Token_L();
+    translate(token_pitch * [   0.5,   1.5 ]) Token_L();
+    translate(token_pitch * [   0.5,   2.5 ]) Token_L();
+  };
+  union(){
+    Frame($phase, token_pitch * [ 6 + 0.5, 6 ]);
+    $nspots = 3;
+  };
+  union(){
+    Frame($phase, token_pitch * [ 6 + 0.5, 6 ]);
+    $nspots = 4;
+    translate(token_pitch * [   1.5,  -2.5 ]) Token_L();
+    translate(token_pitch * [   1.5,  -1.5 ]) Token_L();
+    translate(token_pitch * [   1.5,  -0.5 ]) Token_L();
+    translate(token_pitch * [   1.5,   0.5 ]) Token_L();
+    translate(token_pitch * [   1.5,   1.5 ]) Token_L();
+    translate(token_pitch * [   1.5,   2.5 ]) Token_L();
+    translate(token_pitch * [   2.5,  -2.5 ]) Token_L();
+    translate(token_pitch * [   2.5,  -1.5 ]) Token_L();
+    translate(token_pitch * [   2.5,  -0.5 ]) Token_L();
+    translate(token_pitch * [   2.5,   0.5 ]) Token_L();
   };
 }
 module Green(){ ////toplevel
 // total=38, rowsz=7, nrows=6
   union(){
-    $ndots = 1;
-    translate(token_pitch * [  -3.5,  -3.0 ]) Token_L();
-    translate(token_pitch * [  -3.3,  -2.0 ]) Token_L();
-    translate(token_pitch * [  -3.2,  -1.0 ]) Token_L();
-    translate(token_pitch * [  -3.0,   0.0 ]) Token_L();
-    translate(token_pitch * [  -2.8,   1.0 ]) Token_L();
-    translate(token_pitch * [  -2.7,   2.0 ]) Token_L();
-    translate(token_pitch * [  -2.5,  -3.0 ]) Token_L();
-    translate(token_pitch * [  -2.3,  -2.0 ]) Token_L();
-    translate(token_pitch * [  -2.2,  -1.0 ]) Token_L();
-    translate(token_pitch * [  -2.0,   0.0 ]) Token_L();
-    translate(token_pitch * [  -1.8,   1.0 ]) Token_L();
-    translate(token_pitch * [  -1.7,   2.0 ]) Token_L();
-    translate(token_pitch * [  -1.5,  -3.0 ]) Token_L();
-    translate(token_pitch * [  -1.3,  -2.0 ]) Token_L();
-    translate(token_pitch * [  -1.2,  -1.0 ]) Token_L();
-  };
-  union(){
-    $ndots = 2;
-    translate(token_pitch * [  -1.0,   0.0 ]) Token_L();
-    translate(token_pitch * [  -0.8,   1.0 ]) Token_L();
-    translate(token_pitch * [  -0.7,   2.0 ]) Token_L();
-    translate(token_pitch * [  -0.5,  -3.0 ]) Token_L();
-    translate(token_pitch * [  -0.3,  -2.0 ]) Token_L();
-    translate(token_pitch * [  -0.2,  -1.0 ]) Token_L();
-    translate(token_pitch * [   0.0,   0.0 ]) Token_L();
-    translate(token_pitch * [   0.2,   1.0 ]) Token_L();
-    translate(token_pitch * [   0.3,   2.0 ]) Token_L();
-    translate(token_pitch * [   0.5,  -3.0 ]) Token_L();
-  };
-  union(){
-    $ndots = 3;
-  };
-  union(){
-    $ndots = 4;
-    translate(token_pitch * [   0.7,  -2.0 ]) Token_L();
-    translate(token_pitch * [   0.8,  -1.0 ]) Token_L();
-    translate(token_pitch * [   1.0,   0.0 ]) Token_L();
-    translate(token_pitch * [   1.2,   1.0 ]) Token_L();
-    translate(token_pitch * [   1.3,   2.0 ]) Token_L();
-    translate(token_pitch * [   1.5,  -3.0 ]) Token_L();
-    translate(token_pitch * [   1.7,  -2.0 ]) Token_L();
-    translate(token_pitch * [   1.8,  -1.0 ]) Token_L();
-    translate(token_pitch * [   2.0,   0.0 ]) Token_L();
-    translate(token_pitch * [   2.2,   1.0 ]) Token_L();
-    translate(token_pitch * [   2.3,   2.0 ]) Token_L();
-    translate(token_pitch * [   2.5,  -3.0 ]) Token_L();
-    translate(token_pitch * [   2.7,  -2.0 ]) Token_L();
+    Frame($phase, token_pitch * [ 7 + 0.5, 6 ]);
+    $nspots = 1;
+    translate(token_pitch * [  -3.0,  -2.5 ]) Token_L();
+    translate(token_pitch * [  -3.0,  -1.5 ]) Token_L();
+    translate(token_pitch * [  -3.0,  -0.5 ]) Token_L();
+    translate(token_pitch * [  -3.0,   0.5 ]) Token_L();
+    translate(token_pitch * [  -3.0,   1.5 ]) Token_L();
+    translate(token_pitch * [  -3.0,   2.5 ]) Token_L();
+    translate(token_pitch * [  -2.0,  -2.5 ]) Token_L();
+    translate(token_pitch * [  -2.0,  -1.5 ]) Token_L();
+    translate(token_pitch * [  -2.0,  -0.5 ]) Token_L();
+    translate(token_pitch * [  -2.0,   0.5 ]) Token_L();
+    translate(token_pitch * [  -2.0,   1.5 ]) Token_L();
+    translate(token_pitch * [  -2.0,   2.5 ]) Token_L();
+    translate(token_pitch * [  -1.0,  -2.5 ]) Token_L();
+    translate(token_pitch * [  -1.0,  -1.5 ]) Token_L();
+    translate(token_pitch * [  -1.0,  -0.5 ]) Token_L();
   };
-}
-module Orange(){ ////toplevel
-// total=20, rowsz=5, nrows=4
   union(){
-    $ndots = 1;
-    translate(token_pitch * [  -2.5,  -2.0 ]) Token_L();
-    translate(token_pitch * [  -2.2,  -1.0 ]) Token_L();
-    translate(token_pitch * [  -2.0,   0.0 ]) Token_L();
-    translate(token_pitch * [  -1.8,   1.0 ]) Token_L();
-    translate(token_pitch * [  -1.5,  -2.0 ]) Token_L();
-    translate(token_pitch * [  -1.2,  -1.0 ]) Token_L();
-    translate(token_pitch * [  -1.0,   0.0 ]) Token_L();
-    translate(token_pitch * [  -0.8,   1.0 ]) Token_L();
-    translate(token_pitch * [  -0.5,  -2.0 ]) Token_L();
-    translate(token_pitch * [  -0.2,  -1.0 ]) Token_L();
-    translate(token_pitch * [   0.0,   0.0 ]) Token_L();
-    translate(token_pitch * [   0.2,   1.0 ]) Token_L();
-    translate(token_pitch * [   0.5,  -2.0 ]) Token_L();
-    translate(token_pitch * [   0.8,  -1.0 ]) Token_L();
-    translate(token_pitch * [   1.0,   0.0 ]) Token_L();
-    translate(token_pitch * [   1.2,   1.0 ]) Token_L();
-    translate(token_pitch * [   1.5,  -2.0 ]) Token_L();
-    translate(token_pitch * [   1.8,  -1.0 ]) Token_L();
-    translate(token_pitch * [   2.0,   0.0 ]) Token_L();
-    translate(token_pitch * [   2.2,   1.0 ]) Token_L();
+    Frame($phase, token_pitch * [ 7 + 0.5, 6 ]);
+    $nspots = 2;
+    translate(token_pitch * [  -1.0,   0.5 ]) Token_L();
+    translate(token_pitch * [  -1.0,   1.5 ]) Token_L();
+    translate(token_pitch * [  -1.0,   2.5 ]) Token_L();
+    translate(token_pitch * [   0.0,  -2.5 ]) Token_L();
+    translate(token_pitch * [   0.0,  -1.5 ]) Token_L();
+    translate(token_pitch * [   0.0,  -0.5 ]) Token_L();
+    translate(token_pitch * [   0.0,   0.5 ]) Token_L();
+    translate(token_pitch * [   0.0,   1.5 ]) Token_L();
+    translate(token_pitch * [   0.0,   2.5 ]) Token_L();
+    translate(token_pitch * [   1.0,  -2.5 ]) Token_L();
   };
   union(){
-    $ndots = 2;
+    Frame($phase, token_pitch * [ 7 + 0.5, 6 ]);
+    $nspots = 3;
   };
   union(){
-    $ndots = 3;
+    Frame($phase, token_pitch * [ 7 + 0.5, 6 ]);
+    $nspots = 4;
+    translate(token_pitch * [   1.0,  -1.5 ]) Token_L();
+    translate(token_pitch * [   1.0,  -0.5 ]) Token_L();
+    translate(token_pitch * [   1.0,   0.5 ]) Token_L();
+    translate(token_pitch * [   1.0,   1.5 ]) Token_L();
+    translate(token_pitch * [   1.0,   2.5 ]) Token_L();
+    translate(token_pitch * [   2.0,  -2.5 ]) Token_L();
+    translate(token_pitch * [   2.0,  -1.5 ]) Token_L();
+    translate(token_pitch * [   2.0,  -0.5 ]) Token_L();
+    translate(token_pitch * [   2.0,   0.5 ]) Token_L();
+    translate(token_pitch * [   2.0,   1.5 ]) Token_L();
+    translate(token_pitch * [   2.0,   2.5 ]) Token_L();
+    translate(token_pitch * [   3.0,  -2.5 ]) Token_L();
+    translate(token_pitch * [   3.0,  -1.5 ]) Token_L();
   };
+}
+module Orange(){ ////toplevel
+// total=20, rowsz=5, nrows=4
   union(){
-    $ndots = 4;
+    Frame($phase, token_pitch * [ 5 + 0.5, 4 ]);
+    $nspots = 1;
+    translate(token_pitch * [  -2.0,  -1.5 ]) Token_L();
+    translate(token_pitch * [  -2.0,  -0.5 ]) Token_L();
+    translate(token_pitch * [  -2.0,   0.5 ]) Token_L();
+    translate(token_pitch * [  -2.0,   1.5 ]) Token_L();
+    translate(token_pitch * [  -1.0,  -1.5 ]) Token_L();
+    translate(token_pitch * [  -1.0,  -0.5 ]) Token_L();
+    translate(token_pitch * [  -1.0,   0.5 ]) Token_L();
+    translate(token_pitch * [  -1.0,   1.5 ]) Token_L();
+    translate(token_pitch * [   0.0,  -1.5 ]) Token_L();
+    translate(token_pitch * [   0.0,  -0.5 ]) Token_L();
+    translate(token_pitch * [   0.0,   0.5 ]) Token_L();
+    translate(token_pitch * [   0.0,   1.5 ]) Token_L();
+    translate(token_pitch * [   1.0,  -1.5 ]) Token_L();
+    translate(token_pitch * [   1.0,  -0.5 ]) Token_L();
+    translate(token_pitch * [   1.0,   0.5 ]) Token_L();
+    translate(token_pitch * [   1.0,   1.5 ]) Token_L();
+    translate(token_pitch * [   2.0,  -1.5 ]) Token_L();
+    translate(token_pitch * [   2.0,  -0.5 ]) Token_L();
+    translate(token_pitch * [   2.0,   0.5 ]) Token_L();
+    translate(token_pitch * [   2.0,   1.5 ]) Token_L();
+  };
+  union(){
+    Frame($phase, token_pitch * [ 5 + 0.5, 4 ]);
+    $nspots = 2;
+  };
+  union(){
+    Frame($phase, token_pitch * [ 5 + 0.5, 4 ]);
+    $nspots = 3;
+  };
+  union(){
+    Frame($phase, token_pitch * [ 5 + 0.5, 4 ]);
+    $nspots = 4;
   };
 }
 module Purple(){ ////toplevel
 // total=15, rowsz=4, nrows=4
   union(){
-    $ndots = 1;
-    translate(token_pitch * [  -2.0,  -2.0 ]) Token_L();
-    translate(token_pitch * [  -1.8,  -1.0 ]) Token_L();
-    translate(token_pitch * [  -1.5,   0.0 ]) Token_L();
-    translate(token_pitch * [  -1.2,   1.0 ]) Token_L();
-    translate(token_pitch * [  -1.0,  -2.0 ]) Token_L();
-    translate(token_pitch * [  -0.8,  -1.0 ]) Token_L();
-    translate(token_pitch * [  -0.5,   0.0 ]) Token_L();
-    translate(token_pitch * [  -0.2,   1.0 ]) Token_L();
-    translate(token_pitch * [   0.0,  -2.0 ]) Token_L();
-    translate(token_pitch * [   0.2,  -1.0 ]) Token_L();
-    translate(token_pitch * [   0.5,   0.0 ]) Token_L();
-    translate(token_pitch * [   0.8,   1.0 ]) Token_L();
-    translate(token_pitch * [   1.0,  -2.0 ]) Token_L();
-    translate(token_pitch * [   1.2,  -1.0 ]) Token_L();
-    translate(token_pitch * [   1.5,   0.0 ]) Token_L();
+    Frame($phase, token_pitch * [ 4 + 0.5, 4 ]);
+    $nspots = 1;
+    translate(token_pitch * [  -1.5,  -1.5 ]) Token_L();
+    translate(token_pitch * [  -1.5,  -0.5 ]) Token_L();
+    translate(token_pitch * [  -1.5,   0.5 ]) Token_L();
+    translate(token_pitch * [  -1.5,   1.5 ]) Token_L();
+    translate(token_pitch * [  -0.5,  -1.5 ]) Token_L();
+    translate(token_pitch * [  -0.5,  -0.5 ]) Token_L();
+    translate(token_pitch * [  -0.5,   0.5 ]) Token_L();
+    translate(token_pitch * [  -0.5,   1.5 ]) Token_L();
+    translate(token_pitch * [   0.5,  -1.5 ]) Token_L();
+    translate(token_pitch * [   0.5,  -0.5 ]) Token_L();
+    translate(token_pitch * [   0.5,   0.5 ]) Token_L();
+    translate(token_pitch * [   0.5,   1.5 ]) Token_L();
+    translate(token_pitch * [   1.5,  -1.5 ]) Token_L();
+    translate(token_pitch * [   1.5,  -0.5 ]) Token_L();
+    translate(token_pitch * [   1.5,   0.5 ]) Token_L();
   };
   union(){
-    $ndots = 2;
+    Frame($phase, token_pitch * [ 4 + 0.5, 4 ]);
+    $nspots = 2;
   };
   union(){
-    $ndots = 3;
+    Frame($phase, token_pitch * [ 4 + 0.5, 4 ]);
+    $nspots = 3;
   };
   union(){
-    $ndots = 4;
+    Frame($phase, token_pitch * [ 4 + 0.5, 4 ]);
+    $nspots = 4;
   };
 }
 module Red(){ ////toplevel
 // total=30, rowsz=6, nrows=5
   union(){
-    $ndots = 1;
-    translate(token_pitch * [  -3.0,  -2.5 ]) Token_L();
-    translate(token_pitch * [  -2.8,  -1.5 ]) Token_L();
-    translate(token_pitch * [  -2.6,  -0.5 ]) Token_L();
-    translate(token_pitch * [  -2.4,   0.5 ]) Token_L();
-    translate(token_pitch * [  -2.2,   1.5 ]) Token_L();
-    translate(token_pitch * [  -2.0,  -2.5 ]) Token_L();
-    translate(token_pitch * [  -1.8,  -1.5 ]) Token_L();
-    translate(token_pitch * [  -1.6,  -0.5 ]) Token_L();
-    translate(token_pitch * [  -1.4,   0.5 ]) Token_L();
-    translate(token_pitch * [  -1.2,   1.5 ]) Token_L();
-    translate(token_pitch * [  -1.0,  -2.5 ]) Token_L();
-    translate(token_pitch * [  -0.8,  -1.5 ]) Token_L();
+    Frame($phase, token_pitch * [ 6 + 0.5, 5 ]);
+    $nspots = 1;
+    translate(token_pitch * [  -2.5,  -2.0 ]) Token_L();
+    translate(token_pitch * [  -2.5,  -1.0 ]) Token_L();
+    translate(token_pitch * [  -2.5,   0.0 ]) Token_L();
+    translate(token_pitch * [  -2.5,   1.0 ]) Token_L();
+    translate(token_pitch * [  -2.5,   2.0 ]) Token_L();
+    translate(token_pitch * [  -1.5,  -2.0 ]) Token_L();
+    translate(token_pitch * [  -1.5,  -1.0 ]) Token_L();
+    translate(token_pitch * [  -1.5,   0.0 ]) Token_L();
+    translate(token_pitch * [  -1.5,   1.0 ]) Token_L();
+    translate(token_pitch * [  -1.5,   2.0 ]) Token_L();
+    translate(token_pitch * [  -0.5,  -2.0 ]) Token_L();
+    translate(token_pitch * [  -0.5,  -1.0 ]) Token_L();
   };
   union(){
-    $ndots = 2;
-    translate(token_pitch * [  -0.6,  -0.5 ]) Token_L();
-    translate(token_pitch * [  -0.4,   0.5 ]) Token_L();
-    translate(token_pitch * [  -0.2,   1.5 ]) Token_L();
-    translate(token_pitch * [   0.0,  -2.5 ]) Token_L();
-    translate(token_pitch * [   0.2,  -1.5 ]) Token_L();
-    translate(token_pitch * [   0.4,  -0.5 ]) Token_L();
-    translate(token_pitch * [   0.6,   0.5 ]) Token_L();
-    translate(token_pitch * [   0.8,   1.5 ]) Token_L();
+    Frame($phase, token_pitch * [ 6 + 0.5, 5 ]);
+    $nspots = 2;
+    translate(token_pitch * [  -0.5,   0.0 ]) Token_L();
+    translate(token_pitch * [  -0.5,   1.0 ]) Token_L();
+    translate(token_pitch * [  -0.5,   2.0 ]) Token_L();
+    translate(token_pitch * [   0.5,  -2.0 ]) Token_L();
+    translate(token_pitch * [   0.5,  -1.0 ]) Token_L();
+    translate(token_pitch * [   0.5,   0.0 ]) Token_L();
+    translate(token_pitch * [   0.5,   1.0 ]) Token_L();
+    translate(token_pitch * [   0.5,   2.0 ]) Token_L();
   };
   union(){
-    $ndots = 3;
+    Frame($phase, token_pitch * [ 6 + 0.5, 5 ]);
+    $nspots = 3;
   };
   union(){
-    $ndots = 4;
-    translate(token_pitch * [   1.0,  -2.5 ]) Token_L();
-    translate(token_pitch * [   1.2,  -1.5 ]) Token_L();
-    translate(token_pitch * [   1.4,  -0.5 ]) Token_L();
-    translate(token_pitch * [   1.6,   0.5 ]) Token_L();
-    translate(token_pitch * [   1.8,   1.5 ]) Token_L();
-    translate(token_pitch * [   2.0,  -2.5 ]) Token_L();
-    translate(token_pitch * [   2.2,  -1.5 ]) Token_L();
-    translate(token_pitch * [   2.4,  -0.5 ]) Token_L();
-    translate(token_pitch * [   2.6,   0.5 ]) Token_L();
-    translate(token_pitch * [   2.8,   1.5 ]) Token_L();
+    Frame($phase, token_pitch * [ 6 + 0.5, 5 ]);
+    $nspots = 4;
+    translate(token_pitch * [   1.5,  -2.0 ]) Token_L();
+    translate(token_pitch * [   1.5,  -1.0 ]) Token_L();
+    translate(token_pitch * [   1.5,   0.0 ]) Token_L();
+    translate(token_pitch * [   1.5,   1.0 ]) Token_L();
+    translate(token_pitch * [   1.5,   2.0 ]) Token_L();
+    translate(token_pitch * [   2.5,  -2.0 ]) Token_L();
+    translate(token_pitch * [   2.5,  -1.0 ]) Token_L();
+    translate(token_pitch * [   2.5,   0.0 ]) Token_L();
+    translate(token_pitch * [   2.5,   1.0 ]) Token_L();
+    translate(token_pitch * [   2.5,   2.0 ]) Token_L();
   };
 }
 module White(){ ////toplevel
 // total=32, rowsz=6, nrows=6
   union(){
-    $ndots = 1;
-    translate(token_pitch * [  -3.0,  -3.0 ]) Token_L();
-    translate(token_pitch * [  -2.8,  -2.0 ]) Token_L();
-    translate(token_pitch * [  -2.7,  -1.0 ]) Token_L();
-    translate(token_pitch * [  -2.5,   0.0 ]) Token_L();
-    translate(token_pitch * [  -2.3,   1.0 ]) Token_L();
-    translate(token_pitch * [  -2.2,   2.0 ]) Token_L();
-    translate(token_pitch * [  -2.0,  -3.0 ]) Token_L();
-    translate(token_pitch * [  -1.8,  -2.0 ]) Token_L();
-    translate(token_pitch * [  -1.7,  -1.0 ]) Token_L();
-    translate(token_pitch * [  -1.5,   0.0 ]) Token_L();
-    translate(token_pitch * [  -1.3,   1.0 ]) Token_L();
-    translate(token_pitch * [  -1.2,   2.0 ]) Token_L();
-    translate(token_pitch * [  -1.0,  -3.0 ]) Token_L();
-    translate(token_pitch * [  -0.8,  -2.0 ]) Token_L();
-    translate(token_pitch * [  -0.7,  -1.0 ]) Token_L();
-    translate(token_pitch * [  -0.5,   0.0 ]) Token_L();
-    translate(token_pitch * [  -0.3,   1.0 ]) Token_L();
-    translate(token_pitch * [  -0.2,   2.0 ]) Token_L();
-    translate(token_pitch * [   0.0,  -3.0 ]) Token_L();
-    translate(token_pitch * [   0.2,  -2.0 ]) Token_L();
-  };
-  union(){
-    $ndots = 2;
-    translate(token_pitch * [   0.3,  -1.0 ]) Token_L();
-    translate(token_pitch * [   0.5,   0.0 ]) Token_L();
-    translate(token_pitch * [   0.7,   1.0 ]) Token_L();
-    translate(token_pitch * [   0.8,   2.0 ]) Token_L();
-    translate(token_pitch * [   1.0,  -3.0 ]) Token_L();
-    translate(token_pitch * [   1.2,  -2.0 ]) Token_L();
-    translate(token_pitch * [   1.3,  -1.0 ]) Token_L();
-    translate(token_pitch * [   1.5,   0.0 ]) Token_L();
-  };
-  union(){
-    $ndots = 3;
-    translate(token_pitch * [   1.7,   1.0 ]) Token_L();
-    translate(token_pitch * [   1.8,   2.0 ]) Token_L();
-    translate(token_pitch * [   2.0,  -3.0 ]) Token_L();
-    translate(token_pitch * [   2.2,  -2.0 ]) Token_L();
-  };
-  union(){
-    $ndots = 4;
+    Frame($phase, token_pitch * [ 6 + 0.5, 6 ]);
+    $nspots = 1;
+    translate(token_pitch * [  -2.5,  -2.5 ]) Token_L();
+    translate(token_pitch * [  -2.5,  -1.5 ]) Token_L();
+    translate(token_pitch * [  -2.5,  -0.5 ]) Token_L();
+    translate(token_pitch * [  -2.5,   0.5 ]) Token_L();
+    translate(token_pitch * [  -2.5,   1.5 ]) Token_L();
+    translate(token_pitch * [  -2.5,   2.5 ]) Token_L();
+    translate(token_pitch * [  -1.5,  -2.5 ]) Token_L();
+    translate(token_pitch * [  -1.5,  -1.5 ]) Token_L();
+    translate(token_pitch * [  -1.5,  -0.5 ]) Token_L();
+    translate(token_pitch * [  -1.5,   0.5 ]) Token_L();
+    translate(token_pitch * [  -1.5,   1.5 ]) Token_L();
+    translate(token_pitch * [  -1.5,   2.5 ]) Token_L();
+    translate(token_pitch * [  -0.5,  -2.5 ]) Token_L();
+    translate(token_pitch * [  -0.5,  -1.5 ]) Token_L();
+    translate(token_pitch * [  -0.5,  -0.5 ]) Token_L();
+    translate(token_pitch * [  -0.5,   0.5 ]) Token_L();
+    translate(token_pitch * [  -0.5,   1.5 ]) Token_L();
+    translate(token_pitch * [  -0.5,   2.5 ]) Token_L();
+    translate(token_pitch * [   0.5,  -2.5 ]) Token_L();
+    translate(token_pitch * [   0.5,  -1.5 ]) Token_L();
+  };
+  union(){
+    Frame($phase, token_pitch * [ 6 + 0.5, 6 ]);
+    $nspots = 2;
+    translate(token_pitch * [   0.5,  -0.5 ]) Token_L();
+    translate(token_pitch * [   0.5,   0.5 ]) Token_L();
+    translate(token_pitch * [   0.5,   1.5 ]) Token_L();
+    translate(token_pitch * [   0.5,   2.5 ]) Token_L();
+    translate(token_pitch * [   1.5,  -2.5 ]) Token_L();
+    translate(token_pitch * [   1.5,  -1.5 ]) Token_L();
+    translate(token_pitch * [   1.5,  -0.5 ]) Token_L();
+    translate(token_pitch * [   1.5,   0.5 ]) Token_L();
+  };
+  union(){
+    Frame($phase, token_pitch * [ 6 + 0.5, 6 ]);
+    $nspots = 3;
+    translate(token_pitch * [   1.5,   1.5 ]) Token_L();
+    translate(token_pitch * [   1.5,   2.5 ]) Token_L();
+    translate(token_pitch * [   2.5,  -2.5 ]) Token_L();
+    translate(token_pitch * [   2.5,  -1.5 ]) Token_L();
+  };
+  union(){
+    Frame($phase, token_pitch * [ 6 + 0.5, 6 ]);
+    $nspots = 4;
   };
 }
 module Yellow(){ ////toplevel
 // total=29, rowsz=6, nrows=5
   union(){
-    $ndots = 1;
-    translate(token_pitch * [  -3.0,  -2.5 ]) Token_L();
-    translate(token_pitch * [  -2.8,  -1.5 ]) Token_L();
-    translate(token_pitch * [  -2.6,  -0.5 ]) Token_L();
-    translate(token_pitch * [  -2.4,   0.5 ]) Token_L();
-    translate(token_pitch * [  -2.2,   1.5 ]) Token_L();
-    translate(token_pitch * [  -2.0,  -2.5 ]) Token_L();
-    translate(token_pitch * [  -1.8,  -1.5 ]) Token_L();
-    translate(token_pitch * [  -1.6,  -0.5 ]) Token_L();
-    translate(token_pitch * [  -1.4,   0.5 ]) Token_L();
-    translate(token_pitch * [  -1.2,   1.5 ]) Token_L();
-    translate(token_pitch * [  -1.0,  -2.5 ]) Token_L();
-    translate(token_pitch * [  -0.8,  -1.5 ]) Token_L();
-    translate(token_pitch * [  -0.6,  -0.5 ]) Token_L();
+    Frame($phase, token_pitch * [ 6 + 0.5, 5 ]);
+    $nspots = 1;
+    translate(token_pitch * [  -2.5,  -2.0 ]) Token_L();
+    translate(token_pitch * [  -2.5,  -1.0 ]) Token_L();
+    translate(token_pitch * [  -2.5,   0.0 ]) Token_L();
+    translate(token_pitch * [  -2.5,   1.0 ]) Token_L();
+    translate(token_pitch * [  -2.5,   2.0 ]) Token_L();
+    translate(token_pitch * [  -1.5,  -2.0 ]) Token_L();
+    translate(token_pitch * [  -1.5,  -1.0 ]) Token_L();
+    translate(token_pitch * [  -1.5,   0.0 ]) Token_L();
+    translate(token_pitch * [  -1.5,   1.0 ]) Token_L();
+    translate(token_pitch * [  -1.5,   2.0 ]) Token_L();
+    translate(token_pitch * [  -0.5,  -2.0 ]) Token_L();
+    translate(token_pitch * [  -0.5,  -1.0 ]) Token_L();
+    translate(token_pitch * [  -0.5,   0.0 ]) Token_L();
   };
   union(){
-    $ndots = 2;
-    translate(token_pitch * [  -0.4,   0.5 ]) Token_L();
-    translate(token_pitch * [  -0.2,   1.5 ]) Token_L();
-    translate(token_pitch * [   0.0,  -2.5 ]) Token_L();
-    translate(token_pitch * [   0.2,  -1.5 ]) Token_L();
-    translate(token_pitch * [   0.4,  -0.5 ]) Token_L();
-    translate(token_pitch * [   0.6,   0.5 ]) Token_L();
+    Frame($phase, token_pitch * [ 6 + 0.5, 5 ]);
+    $nspots = 2;
+    translate(token_pitch * [  -0.5,   1.0 ]) Token_L();
+    translate(token_pitch * [  -0.5,   2.0 ]) Token_L();
+    translate(token_pitch * [   0.5,  -2.0 ]) Token_L();
+    translate(token_pitch * [   0.5,  -1.0 ]) Token_L();
+    translate(token_pitch * [   0.5,   0.0 ]) Token_L();
+    translate(token_pitch * [   0.5,   1.0 ]) Token_L();
   };
   union(){
-    $ndots = 3;
+    Frame($phase, token_pitch * [ 6 + 0.5, 5 ]);
+    $nspots = 3;
   };
   union(){
-    $ndots = 4;
-    translate(token_pitch * [   0.8,   1.5 ]) Token_L();
-    translate(token_pitch * [   1.0,  -2.5 ]) Token_L();
-    translate(token_pitch * [   1.2,  -1.5 ]) Token_L();
-    translate(token_pitch * [   1.4,  -0.5 ]) Token_L();
-    translate(token_pitch * [   1.6,   0.5 ]) Token_L();
-    translate(token_pitch * [   1.8,   1.5 ]) Token_L();
-    translate(token_pitch * [   2.0,  -2.5 ]) Token_L();
-    translate(token_pitch * [   2.2,  -1.5 ]) Token_L();
-    translate(token_pitch * [   2.4,  -0.5 ]) Token_L();
-    translate(token_pitch * [   2.6,   0.5 ]) Token_L();
+    Frame($phase, token_pitch * [ 6 + 0.5, 5 ]);
+    $nspots = 4;
+    translate(token_pitch * [   0.5,   2.0 ]) Token_L();
+    translate(token_pitch * [   1.5,  -2.0 ]) Token_L();
+    translate(token_pitch * [   1.5,  -1.0 ]) Token_L();
+    translate(token_pitch * [   1.5,   0.0 ]) Token_L();
+    translate(token_pitch * [   1.5,   1.0 ]) Token_L();
+    translate(token_pitch * [   1.5,   2.0 ]) Token_L();
+    translate(token_pitch * [   2.5,  -2.0 ]) Token_L();
+    translate(token_pitch * [   2.5,  -1.0 ]) Token_L();
+    translate(token_pitch * [   2.5,   0.0 ]) Token_L();
+    translate(token_pitch * [   2.5,   1.0 ]) Token_L();
   };
 }