Tetris, openscad and datastructures

I bumped into an openscad script this morning to create Tetris shapes It seemed to be all numbers and I find that rather unsatisfactory. The other Tetris projects seem to be raw STL files. It would be more powerful to represent the shapes as data and then use that data to generate different forms of the shapes, for example a solid or an outline.

Data structures in openscad are limited to 0-based multi-dimensional arrays, but that's enough to represent the Tetris shapes as

tetris =[
              ["I" , "cyan",    [[0,0],[1,0],[2,0],[3,0]] ],
              ["J" , "blue",    [[0,0],[1,0],[2,0],[0,1]] ],
              ["L" , "orange",  [[0,0],[1,0],[2,0],[2,1]] ],
              ["O",  "yellow",  [[0,0],[1,0],[1,1],[0,1]] ],
              ["S" , "green",   [[0,0],[1,0],[1,1],[2,1]] ],
              ["T" , "purple",  [[0,0],[1,0],[2,0],[1,1]] ],
              ["Z" , "red",     [[0,1],[1,1],[1,0],[2,0]] ]
           ] ;

(An even more minimal representation would be an algorithm which generates the 7 possible  tetronimos but I dont know how to do trhat, and it's not so general)

With the coordinates of the squares of a piece, we can create a solid:

module solid(shape,base,height) {
       for (i = [0:3 ]) 
           assign(sq= shape[i])
               translate([base*sq[0] ,base *sq[1]] ) square(base);

piece= tetris[5];  // only integer indexes, no dictionary 
color(piece[1]) solid(piece[2],10,4);

Creating outline and box shapes proved trickier. I couldn't use minkowski() to add a perimeter because this makes the piece bigger and then they don't fit. The trick seems to be to subtract the solid from a larger solid and use minkowski() to add a perimeter to that solid including the space. Now we have a large solid with a hole smaller that the original solid, so if we take the intersection of the original solid with this large object, we are left with just the perimeter created by minkowski() as the outline.

   eps = 0.1;  // to ensure complete removal
   large=200; // big enough to enclose the object 
   module outline(shape,base,height,thickness)  {
   intersection() {
       minkowski() {
         difference () {
            translate ([0,0,height/2]) cube([large,large,height] ,center=true);
            translate([0,0,-eps]) solid(shape,base,height+ 2 * eps);
$fn=20; // to round the corners 
piece= tetris[5];  

A Box is an outline sitting on a base.  To make a cookie cutter (lots of cookie baking in the US it seems), sit one outline on a thicker outline, or put a perimeter on the base.

Thingiverse provides a customizer interface which uses the openscad code + structured comments to create a form to define a shape from which an STL file can be generated. Neat.



Hi Kit,

I’m going to keep this short and sweet. I think it’s really great what you are doing with your programming blog, and you’ve got great insights in your field. As an expert in topics such as software dev and resources for the API community, I’m are reaching out to you to participate in an API community we’re building.

If you decide to join, we will publish the title of your posts and the first few sentences of each post on an API website. If readers want to read the full story, they’ll be pushed to your blog. The benefits are straightforward: increased exposure and more traffic to your site.

If you’re interested or have any questions, please send me an email with “API” in the subject line and I’ll send you a link to activate your account (or an answer questions).

I look forward to you joining our community!

Kindest regards,
Tina Jin