/*
   * Setup Processing applet
   */
  public void setup() {
    size(getSize().width, getSize().height, P2D);

    /* Build spatial index of vertices and edges */
    buildSpatialIndex();

    /* Set model bounds to encompass all vertices in the index, and then some */
    modelBounds = (Envelope) (vertexIndex.getRoot().getBounds());
    modelBounds.expandBy(0.02);
    matchAspect();
    /* save this zoom level to allow returning to default later */
    modelOuterBounds = new Envelope(modelBounds);

    /* find and set up the appropriate font */
    String[] fonts = PFont.list();
    String[] preferredFonts = {"Mono", "Courier"};
    PFont font = null;
    for (String preferredFontName : preferredFonts) {
      for (String fontName : fonts) {
        if (fontName.contains(preferredFontName)) {
          font = createFont(fontName, 16);
          break;
        }
      }
      if (font != null) {
        break;
      }
    }
    textFont(font);
    textMode(SCREEN);
    addMouseWheelListener(this);
    addMouseMotionListener(
        new MouseMotionAdapter() {
          @Override
          public void mouseMoved(MouseEvent e) {
            super.mouseMoved(e);
            Point p = e.getPoint();
            mouseModelX = toModelX(p.x);
            mouseModelY = toModelY(p.y);
          }
        });
    addComponentListener(
        new ComponentAdapter() {
          public void componentResized(ComponentEvent e) {
            matchAspect();
            drawLevel = DRAW_PARTIAL;
          }
        });
    frameRate(FRAME_RATE);
  }