CS111 Lab 6 Solutions -- EiffelWorld

Understanding the pattern

How is the pattern drawn?

We build an Eiffel Tower with the specified number of levels spaced offset distance apart. The inner angle of each level is also constant. The side length size of the base level is specified. Each higher level has it's side length shrunk by a specified shrink factor.

What is the base case?

If the number of levels is less than 1, do nothing.

How are consecutive calls to the pattern different?

eiffelTower(2) = eiffelBase + eiffelTower(1, shrunk by shrink factor)
eiffelTower(3) = eiffelBase + eiffelTower(2, shrunk by shrink factor)
eiffelTower(4) = eiffelBase + eiffelTower(3, shrunk by shrink factor)
where eiffelBase is a method that will draw one level of the Eiffel Tower.

How do we move into position to draw the next pattern call?

We move offset distance forward (assuming that we start facing the top).

How do we meet the invariant, if any?

Invariant: We need to start and end the pattern in the same place.
We need to move offset distance backward after drawing the additional pattern.

Writing code

Writing the main recursive pattern method: eiffelTower()

We assume we have methods (defined below) which answer each of the questions above.
public void eiffelTower (double size, double shrinkFactor, double angle,
			             int levels, double offset) {
  System.out.println("eiffelTower("+size+", "+shrinkFactor+
		             ", "+angle+", "+levels+", "+offset+");");
  if (levels>0) {                          // base case
    eiffelBase(size, angle);               // draw the base story of the Eiffel Tower
    moveToNextStory(offset);               // move in position to draw next pattern
    eiffelTower(size*shrinkFactor, shrinkFactor, angle, levels-1, offset); //draw next pattern
    returnToStart(offset);                 // meet invariant: start and end in same place
  }
}

Writing a support method (extra design for each level): eiffelBase()

// draws one story of an Eiffel Tower with the specified inner angle and side length of size
public void eiffelBase (double size, double angle) {
  System.out.println("eiffelBase size "+size);
  rt(((180-angle)/2)+90);
  fd(size);
  bd(size);
  rt(angle);
  fd(size);
  bd(size);
  rt(((180-angle)/2)+90);
}

Writing a support method (move to position for next level): moveToNextStory()

public void moveToNextStory (double offset) {
  System.out.println("moveToNextStory");
  pu();
  fd(offset);
  pd();
}

Writing a support method (meet invariant): returnToStart()

public void returnToStart (double offset) {
  System.out.println("returnToStart");
  pu();
  bd(offset);
  pd();
}