Skip to content

Booleans and hulls

Booleans combine shapes of one kind: Solids with Solids, Sketches with Sketches. A Path has none; see Paths.

Expression Means
a + b a.union(b)
a - b a.difference(b)
a & b a.intersection(b)

Both sides are Solids, or both are Sketches. Anything else is a TypeError ('-' can't combine Solid and Sketch). For two Paths, + joins them.

a = cube(10)
b = cube(10).translate(5, 0, 0)
puts (a + b).volume # 1500
puts (a - b).volume # 500
puts (a & b).volume # 500
shape.union(other, ...)

The shape and every other one together. Each argument is a shape of the receiver’s kind or an Array of them.

Returns: the receiver’s kind.

Raises: TypeError naming the argument and index for anything else, nil included. Leave optional parts out with compact:

with_boss = false
boss = with_boss ? cylinder(r: 4, h: 6) : nil
rib = cube([2, 20, 6])
part = cube(20).union([boss, rib].compact)
shape.difference(other, ...)

The shape with every other one taken away: a.difference(b, c) is a - b - c. The arguments are as union’s.

Returns: the receiver’s kind.

holes = [[5, 5], [35, 5]].map { |(x, y)| cylinder(d: 3.4, h: 10).translate(x, y, -1) }
plate = cube(x: 40, y: 10, z: 3).difference(holes)
shape.intersection(other, ...)

What the shape and every other one have in common. The arguments are as union’s.

Returns: the receiver’s kind.

An empty list follows set theory, so a list of optional parts that ends up empty is never an error:

  • a.union([]) and a.difference([]) are a.
  • a.intersection([]) is the empty shape.
part = cube(10)
puts part.union([]).volume # 1000
puts part.intersection([]).empty? # true
shape.hull(other, ...)

The convex hull of the shape and every other one: the smallest convex shape that holds them all. The arguments are as union’s; with none, it is the hull of the shape alone. A Sketch’s hull is a Sketch, its round ends arcs in a drawing.

Returns: the receiver’s kind.

slot = circle(5).hull(circle(5).translate(x: 20))
standoff = cylinder(d: 8, h: 2).hull(cylinder(d: 5, h: 10))
union([solid, ...])
batch_hull([solid, ...])

The union or the convex hull of every Solid in one Array, as a single operation.

  • union([]) is the empty Solid.
  • batch_hull([]) is an ArgumentError, a hull of nothing being no shape.
  • Both take Solids only; anything else is a TypeError.

Returns: Solid.

pins = [cylinder(r: 2, h: 10), cylinder(r: 2, h: 10).translate(x: 20)]
casing = union(pins)
wrap = batch_hull(pins)
solid.minkowski(other)

The Minkowski sum of two Solids: other swept over every point of the solid. With a sphere it rounds every edge and grows the solid by the sphere’s radius; offset does that in one call.

Returns: Solid.

rounded = cube(10).minkowski(sphere(1))
puts rounded.bbox.min.inspect # [-1, -1, -1]

A union of copies of a part is one fused Solid, and so one part in the parts list. To count the copies, assemble them instead.