Dice Puzzle

by Maker_Me in Workshop > 3D Printing

894 Views, 8 Favorites, 0 Comments

Dice Puzzle

Würfel.JPG
Augen.JPG

I have created a puzzle dice. As a model I have taken the thingiverse thing 199871 created by Hank Dietz, Lexington USA. It is a dice that was cut into nine blocks. What I didn't like about the dice was that the eyes of the dice had to be colored by hand. I wanted a slightly larger die. And I wanted to print the eyes in a different color and glue them in. I would like to describe here how I developed the dice in OpenSCAD.

Supplies

OpenSCAD

3D-Printer

Filament in two colors

Designing the Cube With OpenSCAD

dice_0.png

First I thought about how to create the individual blocks. I didn't want to create each block individually, so I defined a nested array in OpenSCAD. Each line represents one block. In the order top, front, bottom, back, left, right the individual sides of the blocks are described. For each side of a block two numbers are given which describe the positions of the concave (first entry) and convex (second entry) eyes.

dots=[[[5,0],[0,5],[5,0],[2,0],[0,0],[1,0]], //block 0
      [[5,0],[0,6],[2,0],[5,0],[1,0],[0,0]], //block 1
      [[0,0],[4,0],[2,0],[2,0],[0,0],[0,0]], //block 2
      [[0,0],[0,7],[0,1],[1,0],[1,0],[0,0]], //block 3
      [[5,0],[4,2],[0,2],[1,0],[1,0],[1,0]], //block 4
      [[5,0],[0,5],[0,7],[0,0],[1,0],[1,0]], //block 5
      [[5,0],[5,0],[1,0],[0,0],[0,0],[1,0]], //block 6
      [[5,0],[0,0],[0,2],[0,0],[0,0],[0,0]], //block 7
      [[2,0],[4,0],[0,2],[4,1],[1,0],[0,0]]];//block 8


The numbers are a binary representation of the three possible positions of an elevation or depression on each side of a block. The three possibilities are on the far left (1 = &001), in the middle (2 = &010) or on the right (4 = &100). The numbers with the & are the binary representation.

Explanation:

Block 0 has the representation

[[5,0],[0,5],[5,0],[2,0],[0,0],[1,0]],

This means that on the top (first field [5,0]) there is a recess on the left (1) and on the right (4) (1+4 = 5) but there are no elevations. On the front side (second field [0,5]) there are no recesses, but on the left and right there is an elevation.

In this way each side of each block was defined.

Next I needed a module because from this description the blocks were created.

Module Setdots

module setdots(n=0,konkav=true) {
    echo(n);
    if ((n%2)==1) {
        translate([-(length-width)/2,0,0]) ball(radius=width/4,konkav=konkav);
    }
    if ((n==2)||(n==3)||(n==6)||(n==7)) {
        translate([0,0,0]) ball(radius=width/4,konkav=konkav);
    }
    if (n>=4) {
        translate([+(length-width)/2,0,0]) ball(radius=width/4,konkav=konkav);
    }
}

In this way each side of each block was defined.

The module setdot places the elevations/depressions on the blocks. It is told by the parameter n at which positions an indentation or elevation should be placed. The first if-statement is the query if the given parameter is odd, i.e. 1, 3, 5 or 7. For this the remainder is determined by a division by 2. If the remainder is 1, then the number is odd. Another possibility would have been to connect the query with logical or.

The second if-statement checks for the middle position whether an elevation or depression must be generated. Here the possible values are linked with an or query. In case the parameter n is equal to 2,3,6 or 7, a deepening/increase is set.

The last if statement checks whether an elevation/deepening must be set on the right. This is the case if the parameter n is greater than or equal to 4.

Module Ball

Each if statement in the module setdots calls the module ball if necessary and passes the radius and whether it is an indentation (concave=true) or an elevation (concave=false).

module ball(radius=1,konkav=true) {
    if (konkav) {
        sphere(r=radius);
    } else {
        fudge = 1/cos(180/$fn);
        sphere(r=(radius+wall)*fudge);
        echo(fudge);
    }
}

The ball module creates a sphere. For an indentation, the radius is slightly increased so that later the elevation and indentation fit into each other.

Module Blocks

dice_0_1.png
dice_0_2.png
dice_0_3.png

The module block is informed via the parameter which which of the 9 blocks is to be generated. The parameter which may be in the range from 0 to 8. The module consists of two nested boolean operations. The outer operation is a difference(), inside is a union().

module block(wich=0) {
    difference() {
        union() {
            cube([length,width,width],center=true);
            translate([0,0,width/2]) setdots(dots[wich][0][1],konkav=true);
            translate([0,-width/2,0]) setdots(dots[wich][1][1],konkav=true);
            translate([0,0,-width/2]) setdots(dots[wich][2][1],konkav=true);
            translate([0,width/2,0]) setdots(dots[wich][3][1],konkav=true);        
            if (dots[wich][4][1]==1) {
                translate([-length/2,0,0]) ball(radius=width/4,konkav=true);
            }
            if (dots[wich][5][1]==1) {
                translate([length/2,0,0]) ball(radius=width/4,konkav=true);
            }
        }
        translate([0,0,width/2]) setdots(dots[wich][0][0],konkav=false);
        translate([0,-width/2,0]) setdots(dots[wich][1][0],konkav=false);
        translate([0,0,-width/2]) setdots(dots[wich][2][0],konkav=false);
        translate([0,width/2,0]) setdots(dots[wich][3][0],konkav=false);        
        if (dots[wich][4][0]==1) {
            translate([-length/2,0,0]) ball(radius=width/4,konkav=false);
        }
        if (dots[wich][5][0]==1) {
            translate([length/2,0,0]) ball(radius=width/4,konkav=false);
        }
    }
}


I first look at the inner nesting with the union().

A block is created in the desired dimensions. Then the required elevations are created for each side in turn.

The outer nesting with difference() creates the required recesses.


Module Dot

The last thing to do was to generate the eyes to paste into the indentations. This is done by the dot() module. First a sphere is created, which is then hollowed out by a difference() function. At last a part is cut off so that a shell remains. This last cut is not quite centered. More than half of the sphere is cut off so that the shells sink into the depressions on the beams.

module dot() {
    radius=width/4;
    fudge = 1/cos(180/$fn);
    difference() {
        sphere(r=(radius+wall));
        sphere(r=radius*fudge);
        translate([0,0,-(radius+wall)/2+wall/2]) cube([2*(radius+wall),2*(radius+wall),radius+2*wall],center=true);
    }
}

The Entire Code

$fn = $preview ? 12 : 72;

width=20;
distance=1;
length=3*width+2*distance;
wall=1.5;

// binaer
// 1  =  dot left
// 2  =  dot middle
// 4  =  dot right

// first digit  =  konkav
// second digit =  konvex


// Order:
// top, front, bottom, back, left, right

dots=[[[5,0],[0,5],[5,0],[2,0],[0,0],[1,0]], //block 0
      [[5,0],[0,6],[2,0],[5,0],[1,0],[0,0]], //block 1
      [[0,0],[4,0],[2,0],[2,0],[0,0],[0,0]], //block 2
      [[0,0],[0,7],[0,1],[1,0],[1,0],[0,0]], //block 3
      [[5,0],[4,2],[0,2],[1,0],[1,0],[1,0]], //block 4
      [[5,0],[0,5],[0,7],[0,0],[1,0],[1,0]], //block 5
      [[5,0],[5,0],[1,0],[0,0],[0,0],[1,0]], //block 6
      [[5,0],[0,0],[0,2],[0,0],[0,0],[0,0]], //block 7
      [[2,0],[4,0],[0,2],[4,1],[1,0],[0,0]]];//block 8


module ball(radius=1,konkav=true) {
    if (konkav) {
        sphere(r=radius);
    } else {
        fudge = 1/cos(180/$fn);
        sphere(r=(radius+wall)*fudge);
        echo(fudge);
    }
}

module dot() {
    radius=width/4;
    fudge = 1/cos(180/$fn);
    difference() {
        sphere(r=(radius+wall));
        sphere(r=radius*fudge);
        translate([0,0,-(radius+wall)/2+wall/2]) cube([2*(radius+wall),2*(radius+wall),radius+2*wall],center=true);
    }
}

module setdots(n=0,konkav=true) {
    echo(n);
    if ((n%2)==1) {
        translate([-(length-width)/2,0,0]) ball(radius=width/4,konkav=konkav);
    }
    if ((n==2)||(n==3)||(n==6)||(n==7)) {
        translate([0,0,0]) ball(radius=width/4,konkav=konkav);
    }
    if (n>=4) {
        translate([+(length-width)/2,0,0]) ball(radius=width/4,konkav=konkav);
    }
}

module block(wich=0) {
    difference() {
        union() {
            cube([length,width,width],center=true);
            translate([0,0,width/2]) setdots(dots[wich][0][1],konkav=true);
            translate([0,-width/2,0]) setdots(dots[wich][1][1],konkav=true);
            translate([0,0,-width/2]) setdots(dots[wich][2][1],konkav=true);
            translate([0,width/2,0]) setdots(dots[wich][3][1],konkav=true);        
            if (dots[wich][4][1]==1) {
                translate([-length/2,0,0]) ball(radius=width/4,konkav=true);
            }
            if (dots[wich][5][1]==1) {
                translate([length/2,0,0]) ball(radius=width/4,konkav=true);
            }
        }
        translate([0,0,width/2]) setdots(dots[wich][0][0],konkav=false);
        translate([0,-width/2,0]) setdots(dots[wich][1][0],konkav=false);
        translate([0,0,-width/2]) setdots(dots[wich][2][0],konkav=false);
        translate([0,width/2,0]) setdots(dots[wich][3][0],konkav=false);        
        if (dots[wich][4][0]==1) {
            translate([-length/2,0,0]) ball(radius=width/4,konkav=false);
        }
        if (dots[wich][5][0]==1) {
            translate([length/2,0,0]) ball(radius=width/4,konkav=false);
        }
    }
}



block(0);  // 0-8
//dot();

Generate the Stl Files

To create the necessary object files the module block must be called with the parameters 0 to 8. Each object must be saved. The shells for the eyes of the cube must be created with a call to dot(). Or use the provided stl files.

One Last Detail

FL9XWRWL27US8AO.jpeg

I find the puzzle very difficult to solve. Unless you have the picture of the cube on which you see the 6, the 2 and the 3. With this help, I and almost all the recipients of the puzzle have had no problems solving it.