Search code examples
javaprocessing

Building HTree in Processing using Java


I need to build an HTree for an exercise. I am so lost because my teacher's teaching ways is questionable. Anyway what we have to do is make an HTree using recursive methods. I had no idea how to start so I found a method online but when I pasted it, it had some errors. So I managed to remove all the errors (at least the underlined ones). When I run the code, it's just a blank block.

void drawH(double x, double y, double size) {

        // compute the coordinates of the 4 tips of the H
        double x0 = x - size/2;
        double x1 = x + size/2;
        double y0 = y - size/2;
        double y1 = y + size/2;

        // draw the 3 line segments of the H
        draw(x0, y0, x0, y1);    
        draw(x1, y0, x1, y1);    
        draw(x0,  y, x1,  y);   
    }

void draw(int n, double x, double y, double size) {
        if (n == 0) return;
        drawH(x, y, size);

        // compute x- and y-coordinates of the 4 half-size H-trees
        double x0 = x - size/2;
        double x1 = x + size/2;
        double y0 = y - size/2;
        double y1 = y + size/2;

        // recursively draw 4 half-size H-trees of order n-1
        draw(n-1, x0, y0, size/2);    // lower left  H-tree
        draw(n-1, x0, y1, size/2);    // upper left  H-tree
        draw(n-1, x1, y0, size/2);    // lower right H-tree
        draw(n-1, x1, y1, size/2);    // upper right H-tree
    }

    // reads an integer command-line argument n and plots an order n H-tree
void main() {
        int n = Integer.parseInt(args[0]);

        double x = 0.5, y = 0.5;   // center of H-tree
        double size = 0.5;         // side length of H-tree
        draw(n, x, y, size);
    }

Solution

  • There's nothing wrong with using other people code in my view as long as you:

    1. credit the people
    2. understand the code you're trying to use
    3. optional: have fun hacking/tweaking the code and remixing it with something of your own

    There are several issues with your code and unfortunately I won't have the time to review each one in detail, but I will mention a few:

    • main() isn't called, perhaps you meant to call it from Processing's setup() ?
    • it's a good idea to check if args is not null and its length is at least 1 to be able to parse a value for n.
    • You're accidentally creating infinite recursion loops (which will stackoverflow): main() calls draw(), draw() calls drawH(), drawH() calls draw() several times (which will call drawH() which will call draw(), and so on).

    I'm asuming you're using the Princeton H-Tree example by Robert Sedgewick and Kevin Wayne. If this is the case I'd simply swap double to float types for easier drawing in Processing:

    /*
     * Based on Htree.java demo by Robert Sedgewick and Kevin Wayne
     * original URL: https://introcs.cs.princeton.edu/java/23recursion/Htree.java.html
    */
    void setup() {
      size(600, 600);
      background(255);
      main();
    }
    
    void drawH(float x, float y, float size) {
    
      // compute the coordinates of the 4 tips of the H
      float x0 = x - size/2;
      float x1 = x + size/2;
      float y0 = y - size/2;
      float y1 = y + size/2;
    
      // draw the 3 line segments of the H
      line(x0, y0, x0, y1);
      line(x1, y0, x1, y1);
      line(x0, y, x1, y);
    }
    
    void draw(int n, float x, float y, float size) {
      if (n == 0) return;
      drawH(x, y, size);
    
      // compute x- and y-coordinates of the 4 half-size H-trees
      float x0 = x - size/2;
      float x1 = x + size/2;
      float y0 = y - size/2;
      float y1 = y + size/2;
    
      // recursively draw 4 half-size H-trees of order n-1
      draw(n-1, x0, y0, size/2);    // lower left  H-tree
      draw(n-1, x0, y1, size/2);    // upper left  H-tree
      draw(n-1, x1, y0, size/2);    // lower right H-tree
      draw(n-1, x1, y1, size/2);    // upper right H-tree
    }
    
    // reads an integer command-line argument n and plots an order n H-tree
    void main() {
      // start with a default value
      int n = 6;
      // override that value with args if they exisst (e.g. sketch is launched via command line)
      if(args != null && args.length > 0){
        n = Integer.parseInt(args[0]);
        println("parsed n=", n);
      }
      float x = width * 0.5, y = height * 0.5;   // center of H-tree
      int size = 600;         // side length of H-tree
      draw(n, x, y, size);
    }
    

    If you want to test the command line arguments you would need to:

    • add the folder containing processing-java (it's in the same folder the Processing executable lives) to the PATH environment-variable (or alternatively cd into that directory as a temporary option)
    • run your sketch passing the integer argument: e.g. processing-java --sketch=path/to/yourHTreeSketch --run 3 (where 3 is the example recursion level)

    (Alternatively you can export an application (via File > Export Application (Ctrl+Shift+E / CMD+Shift+E) and run that from command line passing the int argument)

    I wish I had the time to explain recursion: it's such a fun topic!

    There are really good resources out there. Check out Daniel Shiffman's:

    Good luck and have fun!