Skip to content
Carl Davidson edited this page Aug 8, 2016 · 76 revisions

##The OpenSCAD General Library of Relativity

Table of Contents

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:

Render Module Replaces
[[https://raw.githubusercontent.com/davidson16807/relativity.scad/master/images/primitives/box.png width=150px]] box
[[https://raw.githubusercontent.com/davidson16807/relativity.scad/master/images/primitives/rod.png width=150px]] rod
[[https://raw.githubusercontent.com/davidson16807/relativity.scad/master/images/primitives/ball.png width=150px]] ball

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]

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. 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);

Styling (AKA "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. 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]] [[https://raw.githubusercontent.com/davidson16807/relativity.scad/master/images/csg/differed.png
[[hulled CSG-operations#hulled]] [[https://raw.githubusercontent.com/davidson16807/relativity.scad/master/images/csg/hulled.png
[[intersected CSG-operations#intersected]] [[https://raw.githubusercontent.com/davidson16807/relativity.scad/master/images/csg/intersected.png
[[show CSG-operations#show]] [[https://raw.githubusercontent.com/davidson16807/relativity.scad/master/images/csg/show.png
[[hide CSG-operations#hide]] [[https://raw.githubusercontent.com/davidson16807/relativity.scad/master/images/csg/hide.png
colored [[https://raw.githubusercontent.com/davidson16807/relativity.scad/master/images/csg/colored.png width=100px]]
scaled [[https://raw.githubusercontent.com/davidson16807/relativity.scad/master/images/csg/scaled.png width=100px]]
resized [[https://raw.githubusercontent.com/davidson16807/relativity.scad/master/images/csg/resized.png width=100px]]
mirrored [[https://raw.githubusercontent.com/davidson16807/relativity.scad/master/images/csg/mirrored.png width=100px]]
rotated [[https://raw.githubusercontent.com/davidson16807/relativity.scad/master/images/csg/rotated.png width=100px]]
translated [[https://raw.githubusercontent.com/davidson16807/relativity.scad/master/images/csg/translated.png width=100px]]

##Selectors

Selectors are the means through which CSG operations specify class. Selectors are strings whose format is meant to resemble a subset of CSS selector syntax.

Illustrations below uses the following code:

colored("blue", ...)
ball(50, $class="parent")
{
    align(x)
    ball(40, $class="child A")
    align(x)
    ball(30, $class="grandchild");
    
    align(z)
    ball(40, $class="child B")
    align(z)
    ball(30, $class="grandchild");
    
    align(-x)
    ball(40, $class="child C")
    align(-x)
    ball(30, $class="grandchild");
}

As of version 2015.02.14, selectors support the following syntax:

Selector Description Comments
  • | | selects all primitives | A,B | | Selects all primitives of class "A" or "B" | note the lack of whitespace not(A) | | Selects all primitives where $class does not contain "A" | child.A | | Selects all primitives both of class "child" and "A". NOTE: this differs from CSS, where "." indicates a selection based on class parent grandchild | | Selects all primitives of class "grandchild" with any ancestor of class "parent" | parent>grandchild | | Selects all primitives of class "grandchild" whose parent is of class "parent". All "grandchild" objects have "child" objects as their parent, so no object is selected. | parent child,B grandchild | | Note how operators are applied - operators are applied left to right. There is no order of operation. (parent child),B grandchild | | Selects two types of primitives. The first type is of class "grandchild" with ancestor of class "A". The second type is of class "grandchild" with ancestor of class "B". NOTE: Normal operator precedence is overridden by parentheses, unlike CSS.

Note that syntax shown above may be subject to change. This is particularly the case where incongruities exist with the CSS selector syntax.

Demos

Link Render Description
Tree [[https://raw.githubusercontent.com/davidson16807/relativity.scad/master/demos/tree/7.png width=200px]]
Stepper Motor [[https://raw.githubusercontent.com/davidson16807/relativity.scad/master/demos/motor/14.png width=200px]]
Motor Mount [[https://raw.githubusercontent.com/davidson16807/relativity.scad/master/demos/mount/2.png width=200px]]
Human Body [[http://thingiverse-production-new.s3.amazonaws.com/renders/ad/09/2b/a0/8c/render_preview_featured.jpg width=200px]]
[[Flower width=200px]]
[[Centipede width=200px]]
Clone this wiki locally