Cord/docs/cordial-reference.md

8.6 KiB

Cordial Language Reference

Cordial is the primary source language for the Cord geometry system. It compiles to a trigonometric intermediate representation (TrigGraph) which can be evaluated as an f64 reference, compiled to WGSL shaders for GPU raymarching, or lowered to pure CORDIC shift-and-add arithmetic.

File extension: .crd


Variables

let r = 5
let height = 2 * pi
let s: Obj = sphere(r)
  • let introduces a new variable.
  • : Obj type annotation marks a variable as a renderable 3D object.
  • Variables can be reassigned: r = 10 (no let on reassignment).

Constants

Name Value
pi, PI 3.14159...
e, E 2.71828...
x Input X coord
y Input Y coord
z Input Z coord
reg NaN register

x, y, z are the spatial coordinates — use them to build mathematical expressions and SDF fields directly.


Arithmetic

Syntax Operation
a + b Addition
a - b Subtraction
a * b Multiplication
a / b Division
a ^ b Power (²,³ optimized)
-a Negation

Precedence: unary > power > multiplicative > additive. Parentheses for grouping: (a + b) * c.


Comments

// line comment
/= also a line comment

/* block comment */
/* nested /* block */ comments */

Trig Functions

Function Aliases Description
sin(x) Sine
cos(x) Cosine
tan(x) Tangent
asin(x) arcsin Inverse sine
acos(x) arccos, arcos Inverse cosine
atan(x) arctan Inverse tangent
sinh(x) Hyperbolic sine
cosh(x) Hyperbolic cosine
tanh(x) Hyperbolic tangent
asinh(x) arcsinh Inverse hyperbolic sine
acosh(x) arccosh, arcosh Inverse hyperbolic cosine
atanh(x) arctanh Inverse hyperbolic tangent

Math Functions

Function Aliases Description
sqrt(x) Square root
exp(x) e^x
ln(x) log Natural logarithm
abs(x) Absolute value
hypot(a, b) √(a² + b²)
atan2(y, x) Two-argument arctangent
min(a, b) Minimum
max(a, b) Maximum
length(a, b) mag Magnitude (2D or 3D)
mix(a, b, t) lerp Linear interpolation
clip(x, lo, hi) clamp Clamp to range
smoothstep(e0, e1, x) Hermite interpolation
quantize(x, step) Snap to grid

SDF Primitives

These construct signed distance fields centered at the origin. All dimensions are half-extents (centered geometry).

Function Arguments Description
sphere(r) radius Sphere
box(hx, hy, hz) half-extents Axis-aligned box
cylinder(r, h) radius, half-height Z-axis cylinder
ngon(n, side) sides (≥3), side length Regular polygon prism
N-gon(side) side length Shorthand: 6-gon(2) = hexagonal prism

Transforms

Transforms take an SDF as the first argument and modify its coordinate space.

Function Aliases Arguments Description
translate(sdf, tx, ty, tz) mov, move SDF + offsets Translate
rotate_x(sdf, angle) rx SDF + radians Rotate around X
rotate_y(sdf, angle) ry SDF + radians Rotate around Y
rotate_z(sdf, angle) rz SDF + radians Rotate around Z
scale(sdf, factor) SDF + uniform scale Uniform scale
mirror_x(sdf) mx SDF Mirror across YZ plane
mirror_y(sdf) my SDF Mirror across XZ plane
mirror_z(sdf) mz SDF Mirror across XY plane

CSG Boolean Operations

Function Aliases Arguments Description
union(a, b) two SDFs Union (min)
intersect(a, b) two SDFs Intersection (max)
diff(a, b) subtract two SDFs Difference (max(a, -b))

Waveform Functions

Function Arguments Description
saw(x) input Sawtooth wave
tri(x) input Triangle wave
square(x) input Square wave

DSP / Signal Functions

Function Arguments Description
am(signal, carrier, depth) Amplitude modulation
fm(signal, carrier, index) Frequency modulation
lpf(signal, cutoff) Low-pass filter approximation
hpf(signal, cutoff) High-pass filter approximation
bpf(signal, lo, hi) Band-pass filter approximation
dft(signal, n) Discrete Fourier approximation
hilbert(x) envelope Analytic signal envelope
phase(x) Instantaneous phase

User-Defined Functions

f(a, b) = a^2 + b^2
let result = f(3, 4)

Define with name(params) = body. Body extends to the next newline or semicolon. Functions are expanded inline at each call site.


Schematics (sch)

Schematics are parameterized multi-statement blocks — like functions but with full block bodies containing let bindings, intermediate variables, and arbitrary nesting. The last expression is the return value.

sch Bracket(w, h, t) {
    let plate: Obj = box(w, h, t)
    let rib: Obj = box(t, h/2, t)
    union(plate, translate(rib, w/2, 0, 0))
}

let b = Bracket(10, 5, 0.5)
cast(b)

Schematics can call other schematics and user-defined functions. They can contain any number of statements.

sch Peg(r, h) {
    let shaft = cylinder(r, h)
    let head = translate(sphere(r * 1.5), 0, 0, h)
    union(shaft, head)
}

sch PegRow(n, spacing) {
    map(i, 0..n) { translate(Peg(0.5, 3), i * spacing, 0, 0) }
}

Iteration (map)

map evaluates a body for each integer in a range and unions all results. Iteration is unrolled at parse time — the TrigGraph is a DAG with no runtime loops.

map(variable, start..end) { body }
  • variable — bound to each integer in [start, end)
  • start..end — exclusive range; bounds must resolve to constants
  • body — any expression or block; can reference the iteration variable
  • All iterations are unioned (min)
  • Max 1024 iterations

Examples

// Row of 5 spheres along X
let row = map(i, 0..5) { translate(sphere(1), i * 3, 0, 0) }

// Ring of 8 spheres
let ring = map(i, 0..8) {
    rotate_z(translate(sphere(0.5), 5, 0, 0), i * pi/4)
}

// Grid using nested maps inside a schematic
sch Grid(nx, ny, spacing) {
    map(i, 0..nx) {
        map(j, 0..ny) {
            translate(sphere(0.4), i * spacing, j * spacing, 0)
        }
    }
}

let g = Grid(4, 6, 2)
cast()

Since map is an expression, it works anywhere: inside let bindings, as arguments to functions, inside schematic bodies, or nested in other maps.


Rendering with cast()

Nothing renders without an explicit cast() call.

Syntax Effect
cast() Render all defined variables
cast(name) Render a specific variable
name.cast() Dot syntax (Obj-typed variables only)

Multiple cast() calls accumulate. The GUI provides a Render button that inserts cast() automatically when new variables exist since the last cast.

Example

let a: Obj = sphere(3)
let b: Obj = box(4, 2, 1)
let c: Obj = translate(a, 5, 0, 0)
cast()

This renders a, b, and c as a union. Without cast(), nothing appears.


Plotting with plot()

Syntax Effect
plot() Plot all bare expressions
plot(expr) Plot a specific expression

The GUI provides a Plot button that inserts plot() when new expressions exist since the last plot.

Example

sin(x) * exp(-x^2)
plot()

Complete Example

// Bolt head: hexagonal prism with a sphere on top
let head: Obj = 6-gon(3)
let dome: Obj = translate(sphere(3.2), 0, 0, 1.5)
let cap: Obj = intersect(head, dome)

// Shaft
let shaft: Obj = cylinder(1.2, 8)
let bolt: Obj = union(translate(cap, 0, 0, 8), shaft)

// Cross hole
let slot: Obj = box(0.4, 3, 10)
let slot2: Obj = rotate_z(slot, pi/2)
let cross: Obj = union(slot, slot2)

let final: Obj = diff(bolt, cross)
cast(final)

Schematics + Iteration

// Reusable peg schematic
sch Peg(r, h) {
    let shaft = cylinder(r, h)
    let head = translate(sphere(r * 1.5), 0, 0, h)
    union(shaft, head)
}

// Base plate with a ring of pegs
let plate: Obj = box(20, 20, 1)
let pegs: Obj = map(i, 0..8) {
    rotate_z(translate(Peg(0.5, 3), 8, 0, 1), i * pi/4)
}
let assembly: Obj = union(plate, pegs)
cast(assembly)