Introducing Efronsitive–parametric 3D printable non-transitive dice

Two weeks ago, I found out about non-transitive dice from Hacker News. And I thought it would be a good simple project to build a 3D model for in OpenSCAD, after designing King’s Gambit, an open source 3D printable Chess set

It was definitely a lot easier to design than the chess set, and I managed to do it in an afternoon. I probably spent more time writing up the documentation and this blog post than I did actually designing the thing. 

The code repository is on github here. Feel free to fork the design and try to do other things with it, and send pull requests. 

What are non-transitive dice?

Non-transitive dice are a set of dice where no one dice has a better chance of winning head-to-head with another dice in the set. They’re like the rock-paper-scissors of the dice world.

The idea for them have been around since the 1970’s: Gardner, M. “Mathematical Games: The Paradox of the Nontransitive Dice and the Elusive Principle of Indifference.” Sci. Amer. 223 , 110-114, Dec. 1970.

When you look closely at the dice, they might have more than one face with the same number of pips (the little divets), or eve no pips at all. Some might have numbers above six as well. 

There are different sets of possible non-transitive dice, usually named after its inventor. The three I have implemented here are Efron, Grime, and Miwin. If you have others, feel free to fork, contribute, and send a pull request! 

Efron’s Dice

Screen_shot_2012-02-27_at_11

Efron’s dice are a set of four dice where each dice beats their predecessor by a probability of 2/3.

The dice is named and ordered by the color scheme where:

Blue > Magenta > Olive > Red > Blue

which means if you’re reading the wikipedia article, A corresponds to Blue, B to Magenta, C to Olive, and D to Red. The colors of the dice are in alphabetical order, to help you remember. This color scheme was adopted from here

Miwin’s Dice

Screen_shot_2012-02-27_at_11

Miwin’s dice are two sets of three dice each with the probability that it will have a higher number than another is 17/36; a lower number, 15/36.

Since there are only three dice, each dice will beat one and lose to the other on average.

The dice can be distinguished by color, or by the sum of their smallest two numbers. For example, the III dice in the Miwin set has faces 1 and 2 on it, which are the smallest two numbers on the dice. Add up 1 and 2, and you get 3, which is the name of that Miwin dice. Dices III, IV, and V, are in one set, and dices IX, X, and XI, are in the other.

These set of dice also has reverse non-transitivity. Normally, III beats IV. But if you remove the common faces, the dice reverses their intransitivity, meaning now IV beats III. This applies to the other two combinations of IV and V, and V and III.

Grime’s Dice

Grime’s dice is a set of 5 dice, each denoted by a color, where the order of which dice beats which is ordered in two ways:

Alphabetical order of the color's name
Blue > Magenta > Olive > Red > Yellow > Blue

By the length of each color's name
Red > Blue > Olive > Yellow > Magenta > Red

In general, the alphabetical chain is stronger than the word length chain. Overall, the average winning probability for one die is 63%

Like Miwin’s dice, Grime’s dice also has reverse non-transitivity. If you have two dice of each color, now the order for word length now flips so:

Magenta > Yellow > Olive > Blue > Red  >Magenta

With two dice, the chain ordered by word-length is stronger than the alphabetical chain. The average winning probability for two dice is 59%

Grime’s dice has other fascinating properties that I suggest you look at here.

Lessons Learned

I found that I spent most of my time writing in OpenSCAD doing refactoring. I’m not sure what the problem is yet, but it’s a symptom of some underlying problem with the programming language’s interface with the user. 

In addition, I also learned that you can put modules within another to help organize the code and not pollute the namespace, but there’s no way to access those modules outside of the containing module, so you can’t actually use it to namespace modules. I also leanred how to use default arguments in the module calls for friendlier programmer interface.

I also tried organizing the code so that there’s a src directory and a print directory, just like there’s a src/ and bin/ in software. However, it’s often not as simple as having a main.scad. Often times, demonstrating what it looks like assembled is different than arranging multiple pieces for printing. So I succumbed to the use of plate.scad to indicate that this is the file you should compile to STL to print. Sometimes, you have multiple plates, and you have to do all the compilation to STL by hand (unless I find a way to convert *.scad to *.stl in OpenSCAD on the command line), which makes it tedious. I think eventually, the printer driver software will allow you to arrange plates, but in the meantime, we’ll have to provide both a plate.scad and an assembly.scad.

Rounded corners are tedious to do. There are easier ways of programming rounded corners, by using the convex hull() or minkowski() methods, but both are so ridiculously slow at rendering (especially the latter), that it makes it pretty much impossible to use practically. 

Well, other than that, I’m looking for other simple projects to model. Have fun with the parametric dice, and send me a pull request!

A brand is a pointer

Media_httpfarm5static_ccrhb

Unevolved Brands by Graham Smith via flickr.com

As someone with an engineering background, I was always far more concerned with the features of the product I was building, rather than the hype and bullshit that gets built up by marketing. But eventually, I changed my mind about marketing. The practice of something and its intent are two separate things. 

The core intent of marketing is actually about clear communication and teaching others so they can understand your product, use your product, and stay with it. Given you actually have something of value for others to make their lives better, they will need help understanding how and why you’re able to do that. [1] 

Part of being able to clearly communicate your product is having a brand or a positioning. So what is a brand? Is it a great looking logo? Or great looking packaging? I’d argue that those are just manifestations of its core purpose:

A brand is essentially a pointer.

Just as in you have memory addresses pointing to other sections of memory, a brand is a pointer that uniquely refers to a product, whether it’s a 5 word description, a logo, commercial, or nowadays, an internet meme. Every time you think of solving a problem or doing an activity, chances are, you only think of one or two solutions. 

Where do you go if you want to play with toy bricks?
Where do you go if you want to see funny videos?
Where do you go if you want to review your personal finances?
Where do you go if you want to read rants about Apple?

When you’re describing your startup or your product to other people, it needs to be simple and succinct enough to write a pointer in their minds about a specific problem they need solved. So that the next time they want this problem solved, they think of your product. Or even better, the next time someone asks them how to solve a particular problem, they’ll be reminded of your product.

That’s why you so often hear the phrase, “It’s X for Y” when someone’s describing their startup. As clichéd as the phrase is, it’s effective in giving the listener a mental hook to hang their understanding on. 

But, “my product does more than that!” you might retort. Don’t fall into this trap of feeling sheepish that your product only solves one problem. Many startups fail because they don’t even manage to do that. Clearly, in the four examples I gave above, you can do far more with their products than what I described, but the four short problem descriptions above is what reminds you of those products. It gets your product’s foot in the door of someone’s mind so they can start exploring what else your product does. The enemy of most beginning products is not a lack of features, but obscurity. 

In addition, smart people can usually think a step or two out, but they need some basis to work from. When you’ve established “It’s X for Y” for your product in someone’s mind, they’re free to let their imagination fly. They’ll probably come up with more ideas and perspectives than you would have thought of. But if you never get them there, you won’t be able to reap the benefits of people’s enthusiasm and imagination. 

Lastly, having a pointer to your product helps with narrowing down your minimum viable product if you can describe it succinctly. Many times, when you’re in the early stages of product development, you’re not actually quite sure what you’re building as of yet. Having a short description goes a long way in focusing your efforts and help determine what your MVP should be. The less you can describe what the core functionality should be, the longer it will take for you to launch, and the longer it’ll take for you to get feedback on whether you’re even on track or not.

So think long and hard about how to whittle down what your product is suppose to do, if it can only do one thing. If you get stuck, If your product is useless if it doesn’t do X, then keep X. If your product is still useful without X, then cut X.

If you get stuck, think about control tower software. Despite it being very complicated and having lots of features, it’s only suppose to do one thing its core: land planes. Your product should just land planes too, by analogy. And the next time someone needs to land their plane, they’ll think of you.

[1] Marketing gets a bad rap because, often times people do marketing even when they have shitty products or products that are inherently harmful.

How to write modules with fallback default arguments in OpenSCAD

While refactoring King’s Gambit in OpenSCAD, I wanted to make a rounded-corner cylinder module that also behaved like the regular cylinder module. In the regular cylinder module, you can write arguments in a variety of ways.

cylinder(10, 10, 20);
cylinder(h = 10, r1 = 10, r2 = 20);
cylinder(h = 10, r=20);

As you see above, you can either pass in arguments by order (like most programming languages), or by name (like in Objective-C and passing hashes in Ruby). And if the argument “r” exists, it override the values for “r1” and “r2”.

I wanted to be able to write this kind of module as well. Of note, there is no pattern matching in OpenSCAD, there are no variables and only constants in OpenSCAD, and there is no nil or null in OpenSCAD. There is an undefined state that constants can be in, but no test for their undef state, since it’s unspecified. Thus, we’re left with using default arguments as a work around. This close as I have figured it out:

module rounded_cylinder(h, r1, r2, r = "undefined") {
  module helper(h, r1, r2) {
    // I'm just going to render a regular cylinder here for simplicity. 
    // Pretend this section has multiple lines of code.
    cylinder(h, r1, r2);
  }

  if (r == "undefined") {
    helper(h, r1, r2);
  } else {
    helper(h, r, r);
  }
}

rounded_cylinder(4, 4, 2);
translate([10, 0, 0]) rounded_cylinder(4, r = 4);
translate([20, 0, 0]) rounded_cylinder(4, r1 = 4, r2 = 2);
translate([30, 0, 0]) rounded_cylinder(4, r1 = 4);
translate([40, 0, 0]) rounded_cylinder(4, r2 = 2);
translate([50, 0, 0]) rounded_cylinder(4);

Default_args

As you can see, I set the default value of “r” to “undefined”, and then tested for whether it’s undefined or not, and rendered the correct helper accordingly, since there’s no actual test for whether a variable is undefined or not.

Note that because there are no variables in OpenSCAD, all constants need to be defined in the beginning of a module. Thus, you can’t redefine constants inside the two branches of the if statement.

Also note that you can either repeat the same code twice in each branch of the if statement, or you can define a helper module inside rounded_cylinder and make a call to it in each branch, as shown above. The helper module only exists within the scope of rounded_cylinder and won’t pollute the global namespace.

Introducing King’s Gambit a parametric open source chess set

King’s Gambit [1] is a little project I’ve been working for the better part of a week and a half. It’s a parametric 3D model chess set in OpenSCAD that’s printable on a 3D printer

Kings_gambit

A Programmer’s Modeling Tool

OpenSCAD is described as a programmer’s solid 3D modeling tool. You can write scripts using constructive model geometry (CSG) to construct 3D models. CSG is simply where you take primitive shapes like spheres, cubes, and cylinders and perform operations with them like union, intersection, and difference to produce objects of appreciable complexity.

To get started in OpenSCAD is pretty simple, as it’s not a hard language to learn. Just a cursory reading through the user manual and googling for some tutorials will make it easy to get started. However, there are some little gotchas. [2][3]

The biggest advantage OpenSCAD for me is that it makes 3D modeling accessible to programmers. It lets me leverage the existing programming tools that I know, such as vim and git to be productive. Instead of being faced with a dizzying array of buttons in an interface like most CAD software, OpenSCAD uses 3 simple primitive shapes, and 3 major CSG operations for me to build upon. In addition, OpenSCAD makes it easy to make parametric models, where the dimensions of the model aren’t hard coded and can be adjusted according to a user’s needs. 

However, there are ways in which it can improve. There are certain operations that can be used to produce rounded corners, such as the Minkowski sum, but it’s too slow to be useful for that. [4] 

As for the language itself, there are some common language features that are missing, such as blocks as first class objects, object properties, pattern matching, etc. Therefore, I found it difficult to create abstractions that I’d like, or to encapsulate variables cleanly for parametric modeling. I’ll write more about this in detail in a later post, as I gain more experience. Perhaps there are other ways to do things that I’m not yet aware of.

Inspired by the Staunton Design

King’s Gambit is inspired by the original Staunton chess set, the most recognizable chess pieces in the world. However, it is a little different, as I designed all the pieces myself from scratch. Given that this is the first time I’ve designed any 3D solid model, I’d say that it turned out pretty well. 

Most of the pieces were pretty easy to design, and I spent most of my time refactoring and doing geometric math, rather than scratching my head about why it’s not rendering correctly. It’s said that any programming language worth learning will make you think a little differently. I found it to be a little bit of an adjustment to picture in my mind how to combine different primitives in order to get the desired shape.

The bishop’s mitre is a sphere unioned with a cone with a rectangular volume subtracted from it to create the slot. You simply union another sphere for the dollop on top.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
module bishop_head(head_ratio, neck_radius) {
  translate([0, 0, neck_radius])
    difference() {
      // the bishop head with a dollop on top
      union() {
        teardrop(head_ratio, neck_radius)
          translate([0, 0, -neck_radius / 3]) sphere(neck_radius / 3);
      }

      // the bishop slot
      rotate(a = -45, v=[0, 1, 0])
        translate([neck_radius / 4, -neck_radius, 0])
          cube([neck_radius * 2, neck_radius * 2, neck_radius / 4]);
    }
}

The rook’s turret is a cylinder with a bullet (which itself is a cylinder unioned with a sphere) subtracted out of the top to get the valley. Then using a for loop, we can subtract out rectangular volumes at every 60 degrees to get the recognizable ramparts.

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
module rook_battlement(height, radius) {
  neck_radius = radius;
  battlement_radius = 1.4 * radius;
  inner_battlement_radius = 0.6 * battlement_radius;

  cylinder(0.2 * height, neck_radius, battlement_radius);
  translate([0, 0, 0.2 * height]) {
    difference() {
      // the battlement
      cylinder(0.8 * height, battlement_radius, battlement_radius);

      // cut out the loopholes
      for (i = [0:5]) {
        rotate(a = [0, 0, i * 360 / 6])
          translate([-1.5, 0, 0.5 * height])
            cube([3, 10, 4]);
      }

      // cut out circular space at top
      translate([0, 0, 0.5 * height]) {
        cylinder(height, inner_battlement_radius, inner_battlement_radius);
        sphere(inner_battlement_radius);
      }
    }
  }
}

I found the knight to be the hardest to design, as it had the most organic shape out of all the pieces, so it’s not easily constructed from primitives. I ended up making two profiles in Inkscape and exported them as DXF files to be imported into OpenSCAD. I then extruded the 2D profiles and intersected them. at an angle. They didn’t quite have the desired effect, but it’s serviceable for the time being. 

One thing I had to watch out for were overhangs. 3D printers have a tougher time with models with overhangs without support material, so instead of sharp grooves, I tended to have sloping saucers, and torus rings for decor.

I have a library of parts that I refactored out of the chess pieces to make them more reusable, if people wanted to make different versions or variations of the pieces. I will spend more time to pull them out into a library if necessary, but for the time being, they’re going to be part of King’s Gambit.

Fork it!

Though there’s a 1849 British design patent on the Staunton design, it looks like it has long expired. With a quick search on the internets, it seems like it’s generally accepted amongst chess set makers to not copyright derivatives of the Staunton design. I intend to release King’s Gambit under some sort of copyleft license, but as of this moment, I’m not sure whether it should be under creative commons or LGPL, since creative commons is not well-applied to software. Being in OpenSCAD, it’s definitely software, and yet, it describes an object.

I encourage you to fork it and make improvements upon it. I’ve printed some of the pieces out, but not all of them yet, so there may be some bugs that need fixing. In addition, though I tried to make all the pieces as parametric as I can, I know I might have hard coded some of the pieces along the way. So if you find that you can’t print out a 100mm tall pawn by adjusting the parameter, fix it and send a pull request!

Hopefully, this will encourage you to check out OpenSCAD and try designing a couple things yourself, seeing how it’s within reach of most programmers.

With 3D printing starting to be more accessible, I think it’s important to have the equivalent of open source projects for fundamental libraries that produce gears, pulleys, and other machines. When something fundamental becomes digitized, we will want to share it, and have the freedoms to adjust it as we see fit for our own use without restricting the use for other people. I’m pretty excited to see where this will all lead.

[1] King’s Gambit is an old chess opening that’s not used much anymore at the master level. The idea of a sacrific that puts the king at risk for a calculated advantage is amusing, so I named it after that.

[2] For Mac users, you need to use the (currently) development version 2012.01.25+. Then under Preferences -> Advanced, check the box for “Goldfeather”. This is a workaround for the current bug with the underlying OpenGL drivers with Intel GPUs. 

[3] You need to first compile and render your model using CGAL (F6, not just F5), before you’re able to export to STL files (common exchange format). Otherwise, you won’t be prompted to do so.

[4] For those of you that are Electrical Engineers, the Minkowski is kinda like convolution of polygons.

Addendum tips to the Inkscape to OpenSCAD dxf tutorial

Media_http4bpblogspot_qdhun

OpenSCAD is a programmer’s solid geometric modeler. You can make complex objects from a combination of spheres, cylinders, and rectangular volumes. However, sometimes, you have more organic shapes that you need to model, like the knight in a chess set. That’s where an interactive modeler comes in handy. You can use Inkscape to draw a 2D shape, and extrude it in 3D in OpenSCAD. 

I’ve found the tutorial I’ve linked above works, but you have to make sure that you make the paths segments, or else OpenSCAD won’t display it. Also, note the dimensions that you’re drawing in, since you’re drawing on A4 paper by default in Inkscape, the extruded model in OpenSCAD viewer might just be off screen, so make sure you zoom out.

Also, every time you change the DXF file, you need to flush the cache in the OpenSCAD viewer in order to get the DXF file to reload. It’s under “Design -> Flush Caches”. And then you can reload and compile (F4).

In addition, in your .scad file, loading the file with linear_extrude is deprecated. Use this instead:

linear_extrude(height=50) import("star.dxf");

where import() is the child of linear_extrude. Hopefully, this will help you avoid some pitfalls of modeling with DXF files. Happy modeling!