On this page:
3.1 Coordinates
3.2 Contexts
3.3 Basic Types
coord?
color?
3.4 3D Primitives
sphere
rects
cube
capsule
half-space
interpolation-surface
3.5 2D Primitives
circle
rect
3.6 Combinators
union
intersection
difference
smooth-union
3.7 Transforms
at
translate
scale
rotate
color
iso
extrude
slice
mirror-x
mirror-y
mirror-z
repeat-x
radial-repeat
6.3.90.900

3 Ruckus Language Reference

Ruckus design files start with a lang line:

 #lang ruckus package: ruckus

Ruckus is based on Racket. You don’t need to know Racket to do basic work in Ruckus, but as designs become more complicated, Racket’s features can be a huge help.

3.1 Coordinates

All coordinates in Ruckus are relative.

Primitive objects (see below) are always created at the origin of their local coordinate frame. The relationship between an object’s local coordinates and world coordinates can be controlled by transforms, such as at and rotate.

For example, this sphere sits at the origin:

#lang ruckus
 
(sphere 100)

We can make two spheres, separated by 200 units, using at to shift them in space:

#lang ruckus
 
(at '(100 0 0) (sphere 100))
(at '(-100 0 0) (sphere 100))

The coordinates are relative, not absolute; they measure distance from the local origin. We can shift the local origin by wrapping the whole shebang in more at. The coordinates get added together. Thus, here we define two spheres, at locations '(100 55 0) and '(-100 55 0). They are still 200 units apart, just shifted by 55 units in one direction.

#lang ruckus
 
(at '(0 55 0)
  (at '(100 0 0) (sphere 100))
  (at '(-100 0 0) (sphere 100)))

This might seem a little pathological, but if we wrap the inside in a function, we have a reusable chunk we can place wherever we want:

#lang ruckus
 
(define (spheres-200-units-apart)
  (at '(100 0 0) (sphere 100))
  (at '(-100 0 0) (sphere 100)))
 
(at '(0 55 0) (spheres-200-units-apart))
(at '(0 110 0) (spheres-200-units-apart))
; ... and so on

This reusability is the real strength of using relative coordinates.

3.2 Contexts

Ruckus distinguishes between 2D and 3D contexts.

The top level of a design file is a 3D context. In a 3D context, you can only use 3D primitives, like sphere and rects, because 2D primitives don’t make sense in 3D.

#lang ruckus
 
; 3D context here.
(sphere 100)

Any function called from a 3D context is also in a 3D context:

#lang ruckus
 
(define (my-sphere)
  ; Because this is called from a 3D context, its contents are
  ; also in a 3D context.
  (sphere 100))
 
(my-sphere)  ; called here

You can switch into a 2D context by using a projection transform, which specifies how to project flat 2D objects into 3D space. Currently, only one projection transform is available: extrude.

Within a 2D context you can only use 2D primitives, such as circle and rect.

#lang ruckus
 
; 3D context on the outside...
(extrude 100
  ; ...but 2D context on the inside.
  (circle 100))

To complete the circle, you can also use 3D shapes in a 2D context by using a slicing transform, which specifies how to smash a 3D object into a flat 2D shape. Currently, only one slicing transform is available: slice, which produces a cross-section.

#lang ruckus
 
; 3D context on the outside...
(extrude 100
  ; ...2D context on the inside...
  (circle 100)
  (slice
    ; ...and a chewy 3D center.
    (cube 170)))

3.3 Basic Types

procedure

(coord? v)  boolean?

  v : any?
Returns #t if v is a coordinate, #f otherwise.

A coordinate is a list of real numbers, where the length of the list corresponds to the current context: three numbers in 3D, two in 2D.

procedure

(color? v)  boolean?

  v : any?
Returns #t if v is a color literal, #f otherwise.

A color literal may be:

3.4 3D Primitives

These primitives can be employed in any 3D context.

syntax

(sphere radius)

(sphere #:radius radius)
(sphere #:diameter diameter)
 
  radius : real?
  diameter : real?
Generates a sphere, centered at the origin, with its size specified by either radius or diameter.

Radius is the default way of specifying a sphere. We provide the #:diameter keyword as an option, because otherwise some designs wind up littered with divide-by-twos to convert specified diameters to radii. The #:radius keyword can help contrast with #:diameter in designs where both are used.

syntax

(rects size-x size-y size-z)

 
  size-x : real?
  size-y : real?
  size-z : real?
Generates a rectangular solid, centered around the origin, with the extent along each axis given by size-x, size-y, and size-z.

syntax

(cube size)

 
  size : real?
Shorthand for a rectangular solid that is the same size along each axis, i.e. a cube.

This is exactly equivalent to the following definition:

(define (cube size)
  (rects size size size))

syntax

(capsule height radius)

 
  height : real?
  radius : real?
A capsule is like a cylinder, but its ends are rounded like spheres instead of flat.

The capsule form generates a capsule, centered around the origin, and extending along the Z axis. height gives the distance between the center points of the two ending spheres, and radius gives the radius of the capsule and the ending spheres.

Note that the actual length of a capsule along Z is given by (+ height (* 2 radius)).

syntax

(half-space normal distance)

 
  normal : coord?
  distance : real?
Generates a half-space, which divides all of space into two sections (inside and outside) split by a plane.

The plane’s normal is given by normal, and its distance from the origin along the normal is distance. Positive distances include the origin in the "inside" part of space; negative distances exclude it.

The normal will be normalized internally by Ruckus, so you can use any vector.

syntax

(interpolation-surface constraints)

Generates an interpolated implicit surface using Turk’s algorithm for least curvature given the surface constraints.

constraints must be a list. Each item in the list can be one of two kinds, basic points and points with normal vectors.

Basic points (as lists of three reals) are points in space that are on the surface of the object.

Points with normals are given as a list of two points. The first is a basic point on the surface, and the second is taken as a normal vector pointing out of the surface at that point.

At least one point in the constraints list must have a normal.

This is still under development and is pretty hairy.

3.5 2D Primitives

syntax

(circle radius)

(circle #:radius radius)
(circle #:diameter diameter)
 
  radius : real?
  diameter : real?
Generates a circle whose size is specified by either radius or diameter.

radius is the default way of specifying a circle. We provide the #:diameter keyword as an alternative for designs that prefer to specify dimensions that way, and #:radius for contrast in designs that mix both styles.

syntax

(rect size-x size-y)

 
  size-x : real?
  size-y : real?
Generates a rectangle, centered around the origin, whose dimensions on the X and Y axis are given by size-x and size-y, respectively.

3.6 Combinators

syntax

(union form ...)

Combines all its child forms so that they act as a single object. The result is as if each of the children were simply overlaid on the others: any piece that is solid in at least one child is also solid in the union.

Most combinators implicitly union their children, so an explicit union is rarely necessary.

(union
  (cube 330)
  (sphere 200))

syntax

(intersection form ...)

Intersects all its child forms. The result is solid only in those areas that are solid in all child forms.

(intersection
  (cube 330)
  (sphere 200))

syntax

(difference first-form other-forms ...)

Starting with the first-form, subtracts each of the other-forms. Areas are solid in the result only if they are solid in first-form and not solid in any of other-forms.

Unlike intersection, difference is sensitive to the order of its child forms. The first-form is treated specially. As a result, using difference is the main case where you may want to use an explicit union to group several objects together into a single form.

(difference
  (cube 330)
  (sphere 200))

syntax

(smooth-union radius form ...)

 
  radius : real?
Like union, but the creases where the child forms would intersect are rounded to a minimum curvature radius.

(smooth-union 10
  (cube 330)
  (sphere 200))

3.7 Transforms

syntax

(at vector forms ...)

 
  vector : coord?
Shifts child forms so that their origin is at the point vector in the current coordinate space.

vector should be a valid vector in the current context: in 3D, a list of three real numbers; in 2D, a list of two. vector may be written in place as a literal, or taken from a variable.

at implicitly wraps its children in a union.

translate is a synonym for at.

(at '[0 100 0]
  (cube 330)
  (sphere 200))

syntax

(translate vector forms ...)

 
  vector : coord?
translate is a wordy synonym for at.

syntax

(scale ratio forms ...)

(scale vector forms ...)
 
  ratio : real?
  vector : (coord?)
Adjusts the size of child forms around their common origin.

When called with ratio, the single ratio is applied equally to all axes.

When called with vector, separate ratios are applied to each axis: in 3D contexts, three ratios are required, and in 2D, two are required.

scale implicitly wraps its children in a union.

(scale 1/2 (sphere 200))
(scale '[1 1/2 1/5] (cube 330))

syntax

(rotate angle forms ...)

(rotate angle #:around axis forms ...)
 
  angle : real?
  axis : (or/c 'x 'y 'z coord?)
Rotates child forms around their common origin.

In 2D contexts, the first version must be used, and the rotation is always counter-clockwise by angle degrees around the Z axis.

In 3D contexts, the second version must be used, and the axis must be provided.

axis can be one of the literal symbols 'x, 'y, or 'z, designating the X, Y, or Z axes, respectively.

axis can also be a literal vector, given as a list of three numbers. In this case the vector will be normalized internally.

rotate implicitly wraps its children in a union.

(rotate 45 #:around 'z
  (sphere 200)
  (cube 330))

syntax

(color col forms ...)

 
  col : color?
Assigns a color to child forms.

The color col is represented as a list of real numbers, giving the fraction of red, green, and blue as a number between 0 and 1.

Color is currently only significant in the Ruckus visualizer.

(color '[0 0 1]
  (sphere 200)
  (cube 330))

syntax

(iso shift forms ...)

 
  shift : real?
Applies an isolevel shift to child forms, which will outset their surfaces if shift is positive, or inset if shift is negative.

(iso +20
  (cube 330))

syntax

(extrude height forms ...)

 
  height : real?
Extrudes 2D child forms along the Z axis into a 3D solid of height height centered around the XY plane.

To apply extrude to 3D child forms, you must combine it with slice, as shown in the example below.

(extrude 200
  (at '[100 0]
    (circle 100)))
(extrude 40
  (slice
    (at '[-100 0 0]
      (cube 200))))

syntax

(slice forms ...)

Converts 3D forms into 2D by intersecting them with the XY plane. This is useful to convert an arbitrary cross-section of a 3D object into a 2D outline, which can then be manipulated or extruded.

syntax

(mirror-x forms ...)

Mirrors child forms around the YZ plane, causing the result to be symmetric along the X axis and symmetric around the YZ plane.

syntax

(mirror-y forms ...)

Mirrors child forms around the XZ plane, causing the result to be symmetric along the Y axis and symmetric around the XZ plane.

syntax

(mirror-z forms ...)

Mirrors child forms around the XY plane, causing the result to be symmetric along the Z axis and symmetric around the XY plane.

This version is illegal in 2D contexts, since there is no Z axis.

syntax

(repeat-x period forms ...)

 
  period : real?
Takes a period-unit-wide slice of the child forms around the YZ plane and repeats it infinitely along the X axis.

syntax

(radial-repeat count forms ...)

 
  count : integer?
Makes the child forms count-way radially symmetric around the Z axis.