Skip to content
Carl Davidson edited this page Nov 7, 2015 · 76 revisions

##The OpenSCAD General Library of Relativity

Table of Contents

Centering
Alignment
Orientation
Scaling
CSG
Demos

This OpenSCAD library adds functionality to size, position, and orient objects relative to other geometric primitives.

To do so, the library introduces a new set of modules to replace the default geometric primitives in OpenSCAD:

Module Replaces
box cube
rod cylinder
ball sphere

All the original geometry primitives are still there if you need them, and you can decide how much or how little to use them. The new primitives have most all the behavior of their old counterparts, but with two important distinctions.

Centering

First, in place of center is a new attribute, anchor. This attribute specifies where the axis of rotation is to be placed relative to the object. The anchor attribute is given as a vector whose elements range from -1 (e.g. bottom of axis) to 1 (e.g. top of axis). A value of 0 indicates the anchor is to be centered along an axis.

| +1 | 0 | -1 --------- | --------- | --------- | --------- X| anchor = [1,0,0] anchor = [1,0,0] | anchor = [0,0,0] anchor = [0,0,0]| anchor = [-1,0,0] anchor = [-1,0,0] Y| anchor = [0,1,0] anchor = [0,1,0] | anchor = [0,0,0] anchor = [0,0,0] | anchor = [0,-1,0] anchor = [0,-1,0] Z| anchor = [0,0,1] anchor = [0,0,1] | anchor = [0,0,0] anchor = [0,0,0]| anchor = [0,0,-1] anchor = [0,0,-1]

The following statements are equivalent:

cube(50, center=false);
box(50, anchor=[-1,-1,-1]);

cube(50, center=true);
box(50, anchor=[0,0,0]);

cylinder(50, center=false);
rod(50, anchor=[0,0,-1]);

sphere(50, center=false);
ball(50, anchor=[0,0,0]);

Alignment

The second distinction among these new primitives allows for the creation of child objects. By default, a child object is positioned with its origin at the center of its parent:

box(50, anchor=[0,0,-1])
    sphere(d=55);

this however can be changed using of a second operation, align:

box(50, anchor=[0,0,-1])
    align([0,0,1])
    sphere(d=60);

You can align objects along any axis. The value passed to align() is a vector whose elements range from -1 (e.g. bottom of axis) to 1 (e.g. top of axis). A value of 0 indicates an object is to be placed at the center of its parent along that axis.

|+1 | 0 | -1 --------- | --------- | --------- | --------- X | align([1,0,0]) align([1,0,0]) | align([0,0,0]) align([0,0,0]) | align([-1,0,]0) align([-1,0,]0) Y | align([0,1,0]) align([0,1,0]) | align([0,0,0]) align([0,0,0]) | align([0,-1,]0) align([0,-1,]0) Z | align([0,0,1]) align([0,0,1]) | align([0,0,0]) align([0,0,0]) | align([0,0,-]1) align([0,0,-]1)

The above examples use sphere() as their child object. However, ball() can also be be used as a child. Using ball() will allow us to combine align() and anchor, making it easy to stack objects end-to-end:

box(50, anchor=[0,0,-1])
align([0,0,1])
ball(50, anchor=[0,0,-1])
align([0,0,1])
rod(50, anchor=[0,0,-1]);

To allow for readable code, relativity.scad comes with a few constants representing commonly used values for the align operator:

top = [0,0,1];
center=[0,0,0];
bottom = [0,0,-1];
x = [1,0,0];
y = [0,1,0];
z = [0,0,1];

There are also two special variables that are exposed by the align() module, $inward and $outward. $inward points towards the center of a parent object, while $outward points away from it.

The anchor parameter defaults to $inward. This is meant to facilitate stacking objects. All told, the code above can be rewritten:

box(50)
align(top)
ball(50)
align(top)
rod(50);

Orientation

Child objects by default will maintain the same z-axis orientation as their parent objects

box(50, anchor=[0,0,-1])
align([0,1,0])
rod(d=50, h=50, anchor=[0,-1,0]);

This, however, can be changed with the use of another module, orient. The orient module will redirect the top of a child object to face a given direction. Sometimes rotation using orient can be more intuitive than using rotate

box(50, anchor=[0,0,-1])
align([0,1,0])
orient([0,1,1])
rod(d=50, h=50, anchor=[0,0,-1]);

Sizing

relativity.scad exposes a dynamic variable, $parent_size, in case there are any unforeseen circumstances where something needs to be done relative to a parent object. This can also be used when setting the size of a child, say, when creating a fractal:

box([50,50,50])
align(top)
box(0.8*$parent_size)
align(top)
box(0.8*$parent_size);

The tree demo provides a good example for the parent() and $parent_size functionality.

To ease the use of $parent_size, geometric primitives for rod and ball accept size as their first parameter argument, much like cube and box.

rod([50,50,50])
align(top)
rod(0.8*$parent_size)
align(top)
rod(0.8*$parent_size);

An interesting consequence to this means you can pass rod and ball different values for x,y, and z:

rod([50,50,50])
align(top)
rod([$parent_size.x*.5, $parent_size.y*.7, $parent_size.z*.9])
align(top)
rod([$parent_size.x*.5, $parent_size.y*.7, $parent_size.z*.9]);

Another, more unfortunate side effect means rod does not currently support multiple diameters/radii through the d1 and d2 parameters. This may change as need arises, but for now you can still use the original cylinder primitive when circumstances call for it.

CSG

Relativity.scad transforms the way you work with objects in OpenSCAD. You'll find yourself working a lot more with "tree-like" structures, where geometric primitives nest inside one another. The library borrows heavily from web development technologies like jQuery to help you manipulate these structures. Object manipulation is done by specifying the class of object on which you want to perform an operation. There are several functions that expose this behavior:

Module Description
[[differed CSG-operations#differed]]
[[hulled CSG-operations#hulled]]
[[intersected CSG-operations#intersected]]
[[show CSG-operations#show]]
[[hide CSG-operations#hide]]
[[attach CSG-operations#attach]]
mirrored forms bilaterally symmetric objects using the mirror() function
rotated forms radially symmetric objects by repeated calls to rotate()
translated forms repeating patterns by repeated calls to translate()

Demos

Clone this wiki locally