# [OpenSCAD] Unusual hull() and minkowski modelling

doug moen doug at moens.org
Fri Jun 17 23:24:16 EDT 2016

```There are some open issues requesting point, line segment and path objects
in the 2D plane, for the purpose of DXF export for laser cutting. Eg,

I don't consider laser cutting a good enough reason by itself to add these
features. However, if these features are important for supporting solid
sweep, morph, and other modelling operations, then it looks more
worthwhile, and laser cutter support is just an added bonus.

Proper support for these kinds of objects would obviously include being
able to see them in preview, and having well defined semantics when used
with all geometric operations (eg, CGAL doesn't crash).

In the 2D subsystem, a reasonable set of degenerate shape constructors
might be
* point([x,y])
* path([[x1,y1], [x2,y2], ...], open=true)
* boundary() 2dShape

A path is a connected series of line segments. An open path has a start and
end point, while a closed path is a loop where the start and end are
connected. So, you can sweep along a path. The boundary() operation
converts a proper 2D shape into the closed path representing its perimeter.

In 3D, we'd have the same primitives, plus a mesh primitive for
constructing a surface, with the same arguments as polyhedron, but the mesh
wouldn't have to be manifold. The boundary() operation on a 3D object would
also return a surface.

Plus, of course, we add some special rules, eg so that scale(0) shape
returns a point.

On 16 June 2016 at 23:54, Ronaldo <rcmpersiano at gmail.com> wrote:

> I have found from a discussion in another thread a whole new set of
> possibilities of modelling with hull() and minkowski(). I will present here
> some of them.
>
> To start consider the following module definitions:
>
> > module square3(a,b) scale([a,b,0]) cube(1,center=true);
> > module circle3(r=1) scale([1,1,0]) cylinder(r=r);
> > module point3(p)    translate(p)   scale(0) cube();
>
> Essentially, the first and second are a cube and a cylinder smashed onto
> the
> xy plane, and the third a  cube shrinked to the origin. They don't have
> volume and the last one does not have even an area. They are 2D and 0D
> "shapes" but they are 3D objects in some sense (the reason I added a 3 in
> their names).
>
> If you try to preview any of them you will see nothing. But they are not
> empty sets. For instance, you can hull() the point3() with a sphere and get
> a drop like model:
>
> > hull() { sphere(5); point3([0,0,12]); }
>
> or start the model of a T-joint:
>
> > hull() { translate([0,-10,0]) rotate([90,0,0]) circle3(5,10);
> > cylinder(r=5,h=20,center=true); }
>
> It is possible to do intersections of those shapes with real 3D forms
> before
> the hull:
>
> > hull() {
> >     intersection(){ cube(20); circle3(7); }
> >     translate([0,0,20]) sphere(10);}
>
> Or even make the hull() of just those strange forms to make a cone:
>
> > translate([0,-20,0]) hull() { circle3(5); point3([0,0,10]); }
>
> Let us add one 1D object to the arsenal:
>
> > module segment3(p,p0=[0,0,0]) {
> >     q = p-p0;
> >     l = norm(q);
> >     b = acos(q[2]/l);
> >     c = atan2(q[1],q[0]);
> >     translate(p0)
> >         rotate([0, b, c])
> >             scale([0,0,l])
> >                 cube(1);
> > }
>
> Now the cube is smashed to an edge then rotate and scaled in such a way to
> bring the edge (a line segment) to lay between the points p and p0. Again
> you can't see any preview of segment3(). But it appears when you do the
> hull
> of a set of them:
>
> > module tetrahedron(h){
> >     hull() {
> >         segment3([0,0,h]); // a segment from [0,0,h] to [0,0,0]
> >         segment3([h,0,0]);
> >         segment3([0,h,0]);
> >     }
> > }
>
> Now minkowski. This operator is more restricted. To do a minkowski you need
> at least one real 3D object. So when I tried change the hull() in the
> tetrahedron() to a minkowski I got a system crash. In other trials, I got
> one CGAL error message or nothing at all.
>
> But there is a lot of interesting thing to do with the operator. For
> instance, a solid linear extrusion:
>
> > module solid_linear_extrude(h=1){
> >     minkowski(){
> >         children();
> >         segment3([0,0,h]);
> >     }
> > }
> > solid_linear_extrude(20) difference(){ sphere(10); cylinder(r=5,
> > h=30,center=true); }
>
> This code took a longer time to preview but it worked. It is easy and
> faster
> do it with hull().
>
> But hull() does not solve the sweep operation. Minkowski does with the
> module:
>
> > module sweep_solid(line) {
> >     for(i=[0:len(line)-2])
> >         minkowski(){
> >             children();
> >             segment3(line[i],line[i+1]);
> >         }
> > }
>
> We cannot sweep a 2D shape with sweep_solid() but it is possible to sweep a
> sphere(), a cube or, if you have plenty of time, any 3D model. Note that
> this is a translational sweep.
>
> Finally, an interesting approach to morphing using minkowski:
>
> > module morphing(t) {
> >     minkowski() {
> >         scale((1-t)) children(0);
> >         scale(t) children(1);
> >     }
> > }
>
> that is applied here to a sphere and a cylinder in an animation:
>
> > morphing(1/2-cos(360*\$t)/2) { A(); B(); }
> > module A() rotate([90,0,0]) cylinder(r=3,h=15,center=true);
> > module B() translate([20,0,0]) sphere(5);
>
> For any given 0<t<1,  morphing(t) is a blend of the two children.
>
>
>
> --
> View this message in context:
> Sent from the OpenSCAD mailing list archive at Nabble.com.
>
> _______________________________________________