Madeup Briefing
Introduction
Madeup is a language for making things up–literally. It is a platform for thinking about shapes in an imperative, algorithmic way. Its speakers trace out an object’s skeleton or cross section and then use a Madeup command to generate a solid 3D model that can be printed on a 3D printer. Here we briefly describe the language and geometry-generating commands.
Language
Every fun thing that has ever happened started with some rules (gravitational law, oldest player rolls first, etc.), and Madeup is no exception. Let’s describe the grammar of the Madeup language. Our discussion will get more exciting later on.
Comments
Code is mixture of executable instructions and notes for the humans working with the code. The notes are called comments and they start with --
:
-- This program generates a rocket ship.
-- It will fly.
-- Someday.
Comments can appear on their own line or at the end of lines containing instructions.
Expressions
Expressions in the Madeup language describe integers, real numbers, logical, or textual values. Here are few literal expressions of various types:
6.7 -- real
2 -- integer
"i: " -- string
true -- boolean
false -- boolean
Almost every construct in the Madeup language is an expression: loops, conditionals, and all function calls.
Builtin Operators
Expressions can be combined together using various operators. In the following examples, the value of each expression is shown in a comment:
1 + 2 -- 3
100 - 30 -- 70
2 ^ 5 -- 32
13.1 * 2 -- 26.2
360 / 7 -- 51
360 // 7 -- 51.42587
14 % 10 -- 4
5 <= 6 -- true
58 < 10 -- false
60 >= 60 -- true
100 > 200 -- false
80 == 79 + 1 -- true
5 != 10 -- true
not true -- false
Builtin Functions
Values can also be generated using a variety of builtin functions:
sin 90 -- 1
cos 45 -- 0.707
tan 45 -- 1
atan2 2 1.5 -- 53.13 degrees
random 0 100 -- 17 or 63 or 37...
User-defined Variables
An expression can be bound to a meaningful name using the assignment operator:
n = 5
height = cos 360 // 9
y = x ^ 3
Variables are dynamically typed, are not declared, and can be reassigned at any time. Variables are visible any point after they have been defined, including within function definitions.
User-defined Functions
Functions facilitate reuse, parameterization, and encapsulation of complex algorithms. In Madeup, one defines a function using the to
keyword, as shown in the following absolute value function:
to abs x =
if x < 0
-x
else
x
end
end
Formal parameters are enumerated after the function name. Use as many as you need:
to max a b =
if a > b
a
else
b
end
end
Call user-defined functions the same way you call the builtin functions:
abs -5 -- 5
max 10, 20 -- 20
Note the lack of parentheses.
If you nest a multiparameter call to a function inside another call, you will need to parenthesize it:
print max -1, 1 -- error: interpreted as print (max -1), 1 print (max -1, 1) -- prints 1
The comma has very low-precedence.
Conditional Statements
Within an algorithm, one can respond in different ways to data using a conditional statement:
flip = random 0 99
if flip < 50
print "heads"
else
print "tails"
end
The condition expression must yield a true/false value.
Loops
Sequences may be repeated using several kinds of loops. The simplest is the repeat
loop, which executes for a specified number iterations:
repeat 10
-- do stuff
end
The more general while
loop allows arbitrary expression of the repeat condition:
flag = ...
while not flag
-- do stuff
-- update flag
end
For
loops are like repeat loops, but they provide access to the loop counter and offer more options for controlling how the number range is traversed:
-- Prints 0, 1, 2.
for i to 3
print i
end
-- Prints 0, 1, 2, 3.
for i through 3
print i
end
-- Prints 10, 11, 12, 13, 14.
for i in 10..14
print i
end
-- Prints 10, 12, 14, 16.
for i in 10,12..17
print i
end
Geometry
Movement Commands
The fundamental mechanic of building models with Madeup is tracing out paths using movement commands. You can jump to absolute locations using moveto
or move in relative ways using move
and the various commands.
moveto x, y, z -- jump directly to the given location
move length -- jump length units along the current heading
yaw degrees -- turn left (degrees < 0) or right (degrees > 0)
pitch degrees -- turn down (degrees < 0) or up (degrees > 0)
roll degrees -- turn over
The Cartesian and differential approaches can be mixed together.
Sometimes one needs to alter the current location or heading but then return to the previous location to draw more (e.g., a branching structure). You can push your current location and heading onto a transformation stack and recall it later using these commands:
push -- save current location and heading
pop -- restore most recently saved location and heading
Post-processing Commands
Several commands affect how geometry is generated from the locations one visits in a Madeup program:
center -- shift current path to origin
scale x, y, z -- scale emitted geometry about the origin
rotate x, y, z, degrees -- rotate emitted geometry about an axis
translate x, y, z -- shift emitted geometry
Dot
The dot
command emits a sphere at each location visited by a previous move
or moveto
command. The radius of the sphere is determined by the value of the builtin radius
variable at the time of the move. The number of facets on the spheres is determined by the value value of the builtin nsides
variable at the time of the dot
command.
Here we randomly visit 100 locations in [0, 10] and emit spheres with radii in [0, 2]:
Box
The box
command is like dot
, but it places a cube at each visited location. nsides
has no effect, but the cube’s span is 2 * radius
.
Here we use a function to generate individual layers of a pyramid structure:
Tube
The tube
command considers the walked path as the skeleton of the model, surrounding it with solid geometry. The radius of the tube at each vertex is drawn from the radius
variable, and the number of facets is drawn from nsides
.
Here we generate a star pattern. We have a better algorithm for generating joints that is on the TODO list:
Revolve
The revolve
command interprets the walked path as a cross section of a solid spun around some axis. It revolves the path around the axis, stopping nsides
times.
Here we walk a path along the underside of a bowl, up its outer wall, across its rim, down in its inner wall, and along its inside until we reach the y-axis again. Then we spin it around four times:
Extrude
The extrude command interprets the walked path as the foundation of a solid object, and extends it out along some axis.
Here we generate a rupee by tracing out its stretched hexagonal shape and pulling it out along the negative z-axis (and scaling it as we do):
Surface
The surface command connects the visited locations into a 2D surface of a given width and height. We can use it to generate terrain, spheres, cylinders, cones, Moebius strips, and pretty much any parametric surface.
Here we create an undulating wave: