Union of 3D shapes created by a loop

202 views Asked by At

I have this module to create tetrahedra:

module draw_tetrahedra(tetrahedron_table)
{
    for (i = [0:len(tetrahedron_table) - 1])
    {
        indices = tetrahedron_table[i];

        echo("**RESULT tetrahedron ", i, " indices: ", indices);

        p0 = edges_and_corners[indices[0]];
        p1 = edges_and_corners[indices[1]];
        p2 = edges_and_corners[indices[2]];
        p3 = edges_and_corners[indices[3]];

        color([ 1, 0, 0, 0.5 ])
            polyhedron(points = [ p0, p1, p2, p3 ], faces = [ [ 0, 1, 2 ], [ 0, 2, 3 ], [ 0, 3, 1 ], [ 1, 2, 3 ] ]);
    }
}

I call it like this:

tetrahedron_table = [
    [ 1, 15, 3, 19 ],
    [ 1, 14, 15, 19 ],
    [ 1, 14, 19, 18 ],
    [ 1, 18, 19, 17 ],
    [ 1, 3, 9, 17 ],
    [ 17, 19, 3, 16 ],
    [ 9, 3, 8, 17 ],
    [ 8, 17, 3, 16 ],
];

draw_tetrahedra(tetrahedron_table);

It creates tetrahedra like this:

Screenshot

How can I get a union of all the tetrahedra created by the loop?

Update

I just simply did wrap the entire loop inside the union() function like this, but it didn't unify them:

module draw_tetrahedra(tetrahedron_table)
{
    union()
    {
        for (i = [0:len(tetrahedron_table) - 1])
        {
            indices = tetrahedron_table[i];

            echo("**RESULT tetrahedron ", i, " indices: ", indices);

            p0 = edges_and_corners[indices[0]];
            p1 = edges_and_corners[indices[1]];
            p2 = edges_and_corners[indices[2]];
            p3 = edges_and_corners[indices[3]];

            color([ 1, 0, 0, 0.5 ])
                polyhedron(points = [ p0, p1, p2, p3 ], faces = [ [ 0, 1, 2 ], [ 0, 2, 3 ], [ 0, 3, 1 ], [ 1, 2, 3 ] ]);
        }
    }
}
3

There are 3 answers

0
Megidd On

Eventually, I just computed the vertices/points by a loop:

function tetrahedra_points(tetrahedron_table) =
    [for (i = [0:len(tetrahedron_table) -
                 1])[edges_and_corners[tetrahedron_table[i][0]], edges_and_corners[tetrahedron_table[i][1]],
                     edges_and_corners[tetrahedron_table[i][2]], edges_and_corners[tetrahedron_table[i][3]]]];

and then did a union of the tetrahedra without any loop:

tetrahedron_table = [
    [ 1, 15, 3, 19 ],
    [ 1, 14, 15, 19 ],
    [ 1, 14, 19, 18 ],
    [ 1, 18, 19, 17 ],
    [ 1, 3, 9, 17 ],
    [ 17, 19, 3, 16 ],
    [ 9, 3, 8, 17 ],
    [ 8, 17, 3, 16 ],
];

points = tetrahedra_points(tetrahedron_table = tetrahedron_table);

union()
{
    polyhedron(points = points[0], faces = [ [ 0, 1, 2 ], [ 0, 2, 3 ], [ 0, 3, 1 ], [ 1, 2, 3 ] ]);
    polyhedron(points = points[1], faces = [ [ 0, 1, 2 ], [ 0, 2, 3 ], [ 0, 3, 1 ], [ 1, 2, 3 ] ]);
    polyhedron(points = points[2], faces = [ [ 0, 1, 2 ], [ 0, 2, 3 ], [ 0, 3, 1 ], [ 1, 2, 3 ] ]);
    polyhedron(points = points[3], faces = [ [ 0, 1, 2 ], [ 0, 2, 3 ], [ 0, 3, 1 ], [ 1, 2, 3 ] ]);
    polyhedron(points = points[4], faces = [ [ 0, 1, 2 ], [ 0, 2, 3 ], [ 0, 3, 1 ], [ 1, 2, 3 ] ]);
    polyhedron(points = points[5], faces = [ [ 0, 1, 2 ], [ 0, 2, 3 ], [ 0, 3, 1 ], [ 1, 2, 3 ] ]);
    polyhedron(points = points[6], faces = [ [ 0, 1, 2 ], [ 0, 2, 3 ], [ 0, 3, 1 ], [ 1, 2, 3 ] ]);
    polyhedron(points = points[7], faces = [ [ 0, 1, 2 ], [ 0, 2, 3 ], [ 0, 3, 1 ], [ 1, 2, 3 ] ]);
}
4
Cadeyrn On

I can't check it by myself (because you didn't include edges_and_corners) but I think what you did in your update was right. However if the points of the faces of a polyhedron are given in the wrong order (see here), the boolean operations you do on it can be messed up.

If it doesn't solve the problem, add edges_and_corners so I can try my guesses.

UPDATE

The last face was misoriented : replace faces = [ [ 0, 1, 2 ], [ 0, 2, 3 ], [ 0, 3, 1 ], [ 1, 2, 3 ] ] by faces = [ [ 0, 1, 2 ], [ 0, 2, 3 ], [ 0, 3, 1 ], [ 3, 2, 1 ] ].

0
image_doctor On

As an alternative approach, it always seems that specifying the edge order in polyhedra is tortuous, a tetrahedron can be constructed out of the negative shape of rotated cubes and then differencing. By mirroring and joining tetrahedra you can also create a octahedron.

tetrahedron constructed from rotated, differenced cubes

module tetrahedron(base){    
h=sin(60)*base;
translate([0,0,h])difference()
{
 translate([0,0,-h/2])cube([base,base,h],center=true);
 for(i=[0:3])rotate([0,0,i*90])rotate([0,60,0])translate([0,-base/2,0])cube(base);
};
}

module octahedron(base) { union(){ tetrahedron(base); mirror([0,0,1])tetrahedron(base); }; }

octahedron(10);

octahedron