teaching machines

Madeup Briefing

May 5, 2015 by . Filed under madeup, public.

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]:

Screen Shot 2015-05-05 at 7.38.00 AM

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:

Screen Shot 2015-05-05 at 7.51.43 AM

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:

Screen Shot 2015-05-05 at 8.34.21 AM

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:

Screen Shot 2015-05-05 at 8.47.24 AM

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):

Screen Shot 2015-05-05 at 8.51.38 AM

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:

Screen Shot 2015-05-05 at 9.05.44 AM