Loops - jackbackrack/cons-beginners-course GitHub Wiki

loops

Loop allow you to execute code repeatedly. The while form executes a code block while its condition evaluates to true:

  • while -- while (condition) { statement; ... }

For example, you can collect n cubes using a while loop as follows:

var i = 0;
const cubes = [];
while (i < n) {
  cubes.push(cube({ center: true }));
  i = i + 1;
}
return union(cubes);

where you have a variable i that is checked to see if it is less than n and if so the code block is executed along with incrementing i. This style of loop can be abbreviated with a for loop as follows:

var i = 0;
const cubes = [];
if (i < n) {
  cubes.push(cube({ center: true });
  i = i + 1;
  if (i < n) {
    cubes.push(cube({ center: true });
    i = i + 1;
    ...
  }
}

We can write this type of while loop more succinctly using a for loop:

const cubes = [];
for (var i = 0; i < n; i = i + 1) { 
  cubes.push(cube({ center: true });
}
return union(cubes);

where in the body i is bound to its value 0, 1, ..., n - 1

Say we want to place holes at -1 and 1:

const hole = cylinder({ r: 1, h: 4, center: true });
const a = hole.translate([-1, 0, 0]);
const b = hole.translate([ 1, 0, 0]);

we could do this with the following for loop:

const hole = cylinder({ r: 1, h: 4, center: true });
const holes = [];
for (var x = -1; x <= 1; x = x + 2) {
  holes.push(hole.translate([x, 0, 0]));
}

in order to screw in the corners:

const h00 = hole.translate([-1, -1, 0]);
const h01 = hole.translate([-1,  1, 0]);
const h10 = hole.translate([ 1, -1, 0]);
const h11 = hole.translate([ 1,  1, 0]);

we need a nested loop for x and y:

const hole = cylinder({ r: 1, h: 4, center: true });
const holes = [];
for (var x = -1; x <= 1; x = x + 2) {
  for (var y = -1; y <= 1; y = y + 2) {
    holes.push(hole.translate([x, y, 0]));
  }
}

which is like doing all combinations of x and y as follows:

[-1,1] x [-1,1]

Loop Variables

We can use the loop variable to drive the construction of shapes:

var hole = cylinder({ center: true });
var holes = [];
for (var x = -1; x <= 1; x = x + 2) {
  holes.push(hole.translate([x,0,0]));
}
return union(holes);

We can use the loop variable i to specify the size and x translation of the shape as follows:

const n = 3;
const shapes = [];
const c = cube({ center: true });
for (var i = 0; i < n; i = i + 1) {
  shapes.push(c.scale(i + 1).translate([i * 2,0,0])); 
}
return union(shapes);

We can split out the computation for x as and use a more descriptive name for n:

const numShapes = 3;
const shapes = [];
const c = cube({ center: true });
for (var i = 0; i < numShapes; i = i + 1) {
  var x = i * 2;
  shapes.push(c.scale(i + 1).translate([x,0,0])); 
}
return union(shapes);

We can put an if statement inside loop to drive conditional execution of the loop body:

const numShapes = 3;
const shapes = [];
const c = cube({ center: true });
for (var i = 0; i < numShapes; i = i + 1) {
  var x;
  if (i == 1) { x = i * 2; } else { x = i; }
  shapes.push(c.scale(i + 1).translate([x,0,0]));
}
return union(shapes);

homework

  • write a loop to create multiple shapes using for loop and array
  • write a conditional to do something different for the even indices in loop
    • you can test for even using the remainder function -- (i % 2) == 0
  • redo holes with nested for loop and array
  • make your own fun art with loops