Boolean operations and hull


Take a look at OpenSCAD CheatSheet. You'll find that OpenSCAD provides only 2D or 3D fundamental modules, such as circle, square, sphere, cube, etc. You may, however, perform boolean operations on these modules to create a more complex model. These operations are union, difference and intersection. Besides, the hull transformation is also very useful in some situation.

union

A boolean operation which you've implicitly used before is union. As the name said, if you perform the union operation on a group of modules, they would be being united or joined. For example.

radius = 10;

circle(radius, $fn = 48);
translate([0, -radius, 0]) 
    square(radius * 2);

This example creates a circle and a square. A circle consists of many (infinite, actually) sides in geometry. The $fn parameter in the parameter list of the circle module is used to determine how many sides a circle has.

Then, I create a square, and its side length is the radius of the circle. The square is moved radius centimeters along the negative y-axis. So the result is:

Boolean operations and hull

In OpenSCAD, if you don't specify any boolean operation on modules, they are united automatically. Sometimes, you need to do some advanced actions on a particular group of modules; one way is defining a module to contains these modules, such as:

radius = 10;

module circle_and_square(radius) {
    circle(radius, $fn = 48);
    translate([0, -radius, 0]) 
        square(radius * 2);
}

rotate(-45) circle_and_square(radius);

The other way is using union to group these modules explicitly.

radius = 10;

rotate(-45) union() {
    circle(radius, $fn = 48);
    translate([0, -radius, 0]) 
        square(radius * 2);
}

Both ways generate the following model.

Boolean operations and hull

Defining a module for a small group of modules might be troublesome for you if those modules still don't reach a sub-goal. Using union will be more suitable in this situation. For example, you might want to use the previous code to create a love heart.

radius = 10;

module heart(radius) {
    rotated_angle = 45;
    diameter = radius * 2;
    $fn = 48;

    rotate(-rotated_angle) union() {
        circle(radius);
        translate([0, -radius, 0]) 
            square(diameter);
    }

    translate([cos(rotated_angle) * diameter, 0, 0]) 
        circle(radius);
}

heart(radius);

It leaves a question for you. Why is the last circle translated cos(rotated_angle) * diameter centimeters to make a heart?

Boolean operations and hull

difference

The difference operation subtracts the follow-up modules from the first one. For example, you probably want to carve a word in the heart.

radius = 20;

module heart(radius) {
    rotated_angle = 45;
    diameter = radius * 2;
    $fn = 48;

    rotate(-rotated_angle) union() {
        circle(radius);
        translate([0, -radius, 0]) 
            square(diameter);
    }

    translate([cos(rotated_angle) * diameter, 0, 0]) 
        circle(radius);
}

difference() {
    heart(radius);
    text("LOVE");
}

In this example, you use difference to subtract the word from the heart. It will generate the model below.

Boolean operations and hull

intersection

The intersection operation creates the intersection of all modules. It keeps the overlapped portion. To illustrate, how to put a character on a sphere surface? You may use difference to subtract a smaller sphere from a bigger sphere. It generates a hollow sphere. Then, create a text and linear_extrude it to create an intersection with the hollow sphere.

character = "A";
font_size = 10;
thickness = 1;

module hollow_sphere(radius, thickness) {
    $fn = 48;
    inner_radius = radius - thickness;

    difference() {
        sphere(radius);
        sphere(inner_radius);
    }    
}

module sphere_character(ch, font_size, thickness) {
    font_offset = font_size / 2;

    intersection() {
        hollow_sphere(font_size, thickness);
        linear_extrude(font_size * 2) 
            translate([-font_offset, -font_offset, 0]) 
                text(ch, size = font_size);
    }
}

sphere_character(character[0], font_size, thickness);
sphere(font_size - thickness, $fn = 48);

This example is a comprehensive exercise containing union, difference and intersection. Appropriately combining boolean operations could generate many complex models. As shown in this example, you should define modules to encapsulate these basic models. It makes the code more readable, and you can use these basic models some other day.

This example generates a model below.

Boolean operations and hull

hull

The hull is classified into Transformatons in OpenSCAD CheatSheet.

When seen for the first time, you probably don't understand what it can do. The word “hull” means the outer covering of anything. If you hull several modules, you create the outer cover for them. If those modules are 2D objects, you may imagine that a rope bound these modules. To illustrate, you create two circles first.

radius = 10;
circle(radius);
translate([2 * radius, 0, 0]) 
    circle(radius);

It generates a model below.

Boolean operations and hull

Then, hull these two circles.

radius = 10;
hull() {
    circle(radius);
    translate([2 * radius, 0, 0]) 
        circle(radius);
}

The result is below.

Boolean operations and hull

If you hull 3D objects, you may imagine that a plastic wrap seal these objects. For example. The code below hull two cylinders.

radius = 10;
hull() {
    linear_extrude(10) 
        circle(radius);
    linear_extrude(20) 
        translate([2 * radius, 0, 0]) 
            circle(radius);
}

The model generated is shown below.

Boolean operations and hull

Here's a question for you. In the earlier example, I created a heart which had a right angle at the bottom. Can you make it round, such as the model below? Hint: It would be easier if you leverage the hull transformation.

Boolean operations and hull