-
Notifications
You must be signed in to change notification settings - Fork 25
Home
##The OpenSCAD General Library of Relativity
Centering
Alignment
Orientation
Sizing
Styling
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.
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 = [0,0,0]|
anchor = [-1,0,0]
Y|
anchor = [0,1,0] |
anchor = [0,0,0] |
anchor = [0,-1,0]
Z|
anchor = [0,0,1] |
anchor = [0,0,0]|
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]);
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([0,0,0]) |
align([-1,0,0])
Y |
align([0,1,0]) |
align([0,0,0]) |
align([0,-1,0])
Z |
align([0,0,1]) |
align([0,0,0]) |
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);
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]);
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. You can still use the original cylinder
primitive when circumstances call for it, but a better idea might be to perform the hull between two rods, one of infinitesimal height.
hulled() rod(d=30, h=infinitesimal) rod(d=10, h=20);
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. This is similar to the way you write using nested tags in html. Just like html, there is a system for performing operations on the tree-like structure. In html, there's css. In relativity, there's the CSG operations:
Module | Demo | Code |
---|---|---|
[[differed | CSG-operations#differed]] | ![]() |
[[hulled | CSG-operations#hulled]] | ![]() |
[[intersected | CSG-operations#intersected]] | ![]() |
[[show | CSG-operations#show]] | ![]() |
[[hide | CSG-operations#hide]] | ![]() |
colored | ![]() |
colored("red", "hole") |
scaled | ![]() |
scaled(0.95, "hole") |
resized | ![]() |
resized([47,47,47], "hole") |
mirrored | ![]() |
mirrored(y) |
rotated | ![]() |
rotated(22*z, class="hole") |
translated | ![]() |
translated(10*z, class="hole") |