a port of the Processing Visualization Language

Neighborhood

By Ira Greenberg Draw a neighborhood of houses using Door, Window, Roof and House classes. Good example of class composition, with component Door, Window, Roof class references encapsulated within House class. This arrangement allows House class to handle placement and sizing of its components, while still allowing user customization of the individual components.

Original Processing.org Example: Neighborhood

// All Examples Written by Casey Reas and Ben Fry

// unless otherwise stated.

void setup(){

  size(200, 200);

  background(190);

  smooth();

  // Ground plane

  int groundHeight = 10;

  fill(0);

  rect(0, height-groundHeight, width, groundHeight);

  fill(255);

  

  // Center the houses

  translate(12, 0);



  // Houses

  Door door1 = new Door(20, 40);

  Window window1 = new Window(50, 62, false, Window.DOUBLE);

  Roof roof1 = new Roof(Roof.DOME);

  House house1 = new House(75, 75, door1, window1, roof1, House.MIDDLE_DOOR);

  house1.drawHouse(0, height-groundHeight-house1.h, true);



  Door door2 = new Door(20, 40);

  Window window2 = new Window(50, 62, true, Window.QUAD);

  Roof roof2 = new Roof(Roof.GAMBREL);

  House house2 = new House(100, 60, door2, window2, roof2, House.LEFT_DOOR);

  house2.drawHouse(house1.x + house1.w, height-groundHeight-house2.h, true);

}



class Door{

  //door properties

  int x;

  int y;

  int w;

  int h;



  // for knob

  int knobLoc = 1;

  //constants

  final static int RT = 0;

  final static int LFT = 1;



  // constructor

  Door(int w, int h){

    this.w = w;

    this.h = h;

  }



  // draw the door

  void drawDoor(int x, int y) {

    rect(x, y, w, h);

    int knobsize = w/10;

    if (knobLoc == 0){

      //right side

      ellipse(x+w-knobsize, y+h/2, knobsize, knobsize);

    }

    else {

      //left side

      ellipse(x+knobsize, y+h/2, knobsize, knobsize);

    }

  }



  // set knob position

  void setKnob(int knobLoc){

    this. knobLoc = knobLoc;

  }

}



class Window{

  //window properties

  int x;

  int y;

  int w;

  int h;



  // customized features

  boolean hasSash = false;



  // single, double, quad pane

  int style = 0;

  //constants

  final static int SINGLE = 0;

  final static int DOUBLE = 1;

  final static int QUAD = 2;



  // constructor 1

  Window(int w, int h){

    this.w = w;

    this.h = h;

  }

  // constructor 2

  Window(int w, int h, int style){

    this.w = w;

    this.h = h;

    this.style = style;

  }

  // constructor 3

  Window(int w, int h, boolean hasSash, int style){

    this.w = w;

    this.h = h;

    this.hasSash = hasSash;

    this.style = style;

  }



  // draw the window

  void drawWindow(int x, int y) {

    //local variables

    int margin = 0;

    int winHt = 0;

    int winWdth = 0;



    if (hasSash){

      margin = w/15;

    }



    switch(style){

    case 0:

      //outer window (sash)

      rect(x, y, w, h);

      //inner window

      rect(x+margin, y+margin, w-margin*2, h-margin*2);

      break;

    case 1:

      winHt = (h-margin*3)/2;

      //outer window (sash)

      rect(x, y, w, h);

      //inner window (top)

      rect(x+margin, y+margin, w-margin*2, winHt);

      //inner windows (bottom)

      rect(x+margin, y+winHt+margin*2, w-margin*2, winHt);

      break;

    case 2:

      winWdth = (w-margin*3)/2;

      winHt = (h-margin*3)/2;

      //outer window (sash)

      rect(x, y, w, h);

      //inner window (top-left)

      rect(x+margin, y+margin, winWdth, winHt);

      //inner window (top-right)

      rect(x+winWdth+margin*2,  y+margin, winWdth, winHt);

      //inner windows (bottom-left)

      rect(x+margin, y+winHt+margin*2, winWdth, winHt);

      //inner windows (bottom-right)

      rect(x+winWdth+margin*2,  y+winHt+margin*2, winWdth, winHt);

      break;

    }

  }



  // set window style (number of panes)

  void setStyle(int style){

    this.style = style;

  }

}



class Roof{

  //roof properties

  int x;

  int y;

  int w;

  int h;



  // roof style

  int style = 0;

  //constants  

  final static int CATHEDRAL = 0;

  final static int GAMBREL = 1;

  final static int DOME = 2;



  // default constructor

  Roof(){

  }

   

   // constructor 2

   Roof(int style){

    this.style = style;

  }



  // draw the roof

  void drawRoof(int x, int y, int w, int h) {

    switch(style){

    case 0:

      beginShape();

      vertex(x, y);

      vertex(x+w/2, y-h/3);

      vertex(x+w, y);

      endShape(CLOSE);

      break;

    case 1:

     beginShape();

      vertex(x, y);

      vertex(x+w/7, y-h/4);

      vertex(x+w/2, y-h/2);

      vertex(x+(w-w/7), y-h/4);

      vertex(x+w, y);

      endShape(CLOSE);

      break;

    case 2:

      ellipseMode(CORNER);

      arc(x, y-h/2, w, h, PI, TWO_PI);

      line(x, y, x+w, y);

      break;

    }



  }



  // set roof style

  void setStyle(int style){

    this.style = style;

  }

}



class House{

  //house properties

  int x;

  int y;

  int w;

  int h;



  //component reference variables

  Door door;

  Window window;

  Roof roof;



  //optional autosize variable

  boolean AutoSizeComponents = false;



  //door placement

  int doorLoc = 0;

  //constants

  final static int MIDDLE_DOOR = 0;

  final static int LEFT_DOOR = 1;

  final static int RIGHT_DOOR = 2;



  //constructor

  House(int w, int h, Door door, Window window, Roof roof, int doorLoc) {

    this.w = w;

    this.h = h;

    this.door = door;

    this.window = window;

    this.roof = roof;

    this.doorLoc = doorLoc;

  }



  void drawHouse(int x, int y, boolean AutoSizeComponents) {

    this.x = x;

    this.y =y;

    this.AutoSizeComponents = AutoSizeComponents;



    //automatically sizes doors and windows

    if(AutoSizeComponents){

      //autosize door

      door.h = h/4;

      door.w = door.h/2;



      //autosize windows

      window.h = h/3;

      window.w = window.h/2;



    }

    // draw bldg block

    rect(x, y, w, h);



    // draw door

    switch(doorLoc){

    case 0:

      door.drawDoor(x+w/2-door.w/2, y+h-door.h);

      break;

    case 1:

      door.drawDoor(x+w/8, y+h-door.h);

      break;

    case 2:

      door.drawDoor(x+w-w/8-door.w,  y+h-door.h);

      break;

    }



    // draw windows

    int windowMargin = (w-window.w*2)/3;

    window.drawWindow(x+windowMargin, y+h/6);

    window.drawWindow(x+windowMargin*2+window.w, y+h/6);



    // draw roof

    roof.drawRoof(x, y, w, h);

  }



  // catch drawHouse method without boolean argument

  void drawHouse(int x, int y){

    // recall with required 3rd argument

    drawHouse(x, y, false);

  }

}
Fork me on GitHub