Sunday, January 14, 2018

Can Processing's Turtle Library Do Beetle Blocks?

The answer is...sort of! Beetle Blocks is a fascinating blocks based programming environment that allows you to program in three dimensions using a variation of Turtle Geometry.
The immediate 3D rendering is really fun and provides a great debugging experience for young learners, and student creations can even be downloaded as STL files for 3D printing. Leah Beuchley's Turtle library for Processing can do some of this as well, with some caveats and without the 3D printing, and I think provides a good environment for older students to grapple with Turtle Geometry in a 3D environment.
The first thing to do is display a turtle and provide a camera that allows you to change your perspective to see this 3D environment on a 2D window. See how the turtle—the triangle in the middle—changes shape as you move your point of view around:
 import Turtle.*;  
 Turtle t;  
 void setup() {  
  size(500, 500, P3D);  
  t = new Turtle(this);  
 }  
 void draw () {  
  background(255);  
  camera(mouseX, mouseY, 200, width/2.0, height/2.0, 0, 0, 1, 0);  
  t.goToPoint(0, 0);  
  translate(width/2, height/2, 0);  
  t.drawTurtle();  
 }  

You can read about the camera() function here to find out what all those arguments are doing. The business of moving the turtle to 0, 0 and translating it back to the center is needed to keep the turtle's rotation in 3D space in sync with the camera's rotation.
Now we can make the turtle draw a shape, say a hexagon, and move it around in space!
 void draw () {  
  background(255);  
  camera(mouseX, mouseY, 200, width/2.0, height/2.0, 0, 0, 1, 0);  
  t.goToPoint(0, 0);  
  translate(width/2, height/2, 0);  
  strokeWeight(5);  
  translate(-80,50);  
  for(int i = 0; i<6; i++) {  
   t.forward(100);  
   t.right(60);  
  }  
  t.drawTurtle();  
 }  

Notice the translate() function I used to have the turtle start drawing the hexagon off center. Any time you want the turtle to jump to another part of the window it's best to use translate() to shift in a direction instead of t.goToPoint(x,y). The reason is that translate() shifts any subsequent rotational center along with the turtle, whereas t.goToPoint() doesn't, which causes rotations to get thrown off.
To test this out we'll draw a second hexagon after rotating the turtle along the Y axis, which should make the second hexagon go straight back. After all, this is the exciting thing about Beetle Blocks, drawing in all 3 dimensions.
 void draw () {  
  background(255);  
  camera(mouseX, mouseY, 200, width/2.0, height/2.0, 0, 0, 1, 0);  
  t.goToPoint(0, 0);  
  translate(width/2, height/2, 0);  
  strokeWeight(5);  
  stroke(0);  
  translate(-80, 50);  
  for (int i = 0; i<6; i++) {  
   t.forward(100);  
   t.right(60);  
  }  
  stroke(0,255,0);  
  rotateY(radians(90));  
  for (int i = 0; i<6; i++) {  
   t.forward(100);  
   t.right(60);  
  }  
  t.drawTurtle();  
 }  

Rotating multiple times around one point can lead to some really interesting results.

 void draw () {  
  background(255);  
  camera(mouseX, mouseY, 200, width/2.0, height/2.0, 0, 0, 1, 0);  
  t.goToPoint(0, 0);  
  translate(width/2, height/2, 0);  
  strokeWeight(5);  
  stroke(0);  
  for (int j = 0; j<6; j++) {  
   for (int i = 0; i<6; i++) {  
    t.forward(100);  
    t.right(60);  
   }  
   rotateY(radians(60));  
  }  
  t.drawTurtle();  
 }  

There are some ways the Processing rotation algorithm does not allow you to do everything you can do in Beetle Blocks. Because Processing's rotation is separate from the turtle's relative position, things can get crazy very easily, since you can't keep translating every step of the turtle's movements, while in Beetle Blocks the beetle always keeps its center of rotation with it. For example, this common exploration in Beetle Blocks:

goes haywire in Processing. This is because it's being rotated from a center that gets farther and farther away from its location:
 for (int i = 0; i<10; i++) {  
   t.forward(30);  
   rotateX(10);  
  }  

If you are careful, though, some cool things can work! Here's a cube, rather than rotating around a center point, it translates away along the Z axis before making a rotated square to form each side. I think these exercises can make great spatial activities for older kids to grapple with.
 for (int j = 0; j<4; j++) {  
   for (int i = 0; i<4; i++) {  
    t.forward(100);  
    t.right(90);  
   }  
   translate(0,0,-100);  
   rotateY(radians(-90));  
  }  


No comments :