/**
   * Adds the given edge to those to be displayed in the viewer. Note that the edge must connect
   * nodes that have already been added to the viewer. This version will use the locations of the
   * two nodes to calculate their distance of separation.
   *
   * @param edge Edge to add to the display.
   * @return True if edge was added successfully. False if edge contains nodes that have not been
   *     added to the viewer.
   */
  public boolean addEdge(E edge) {
    Particle p1 = nodes.get(edge.getNode1());
    if (p1 == null) {
      System.err.println("Warning: Node1 not found when creating edge.");
      return false;
    }
    Particle p2 = nodes.get(edge.getNode2());
    if (p2 == null) {
      System.err.println("Warning: Node2 not found when creating edge.");
      return false;
    }

    // Only add edge if it does not already exist in the collection
    if (!edges.containsKey(edge)) {
      float x1 = p1.position().x();
      float y1 = p1.position().y();
      float x2 = p2.position().x();
      float y2 = p2.position().y();
      // Strength, damping, reset length
      edges.put(
          edge,
          physics.makeSpring(
              p1,
              p2,
              EDGE_STRENGTH,
              DAMPING,
              (float) Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2))));
    }
    return true;
  }
  /** Centres the particle view on the currently visible nodes. */
  private void updateCentroid() {
    float xMax = Float.NEGATIVE_INFINITY,
        xMin = Float.POSITIVE_INFINITY,
        yMin = Float.POSITIVE_INFINITY,
        yMax = Float.NEGATIVE_INFINITY;

    for (int i = 0; i < physics.getNumParticles(); ++i) {
      Particle p = physics.getParticle(i);
      xMax = Math.max(xMax, p.position().x());
      xMin = Math.min(xMin, p.position().x());
      yMin = Math.min(yMin, p.position().y());
      yMax = Math.max(yMax, p.position().y());
    }

    float xRange = xMax - xMin;
    float yRange = yMax - yMin;

    if ((xRange == 0) && (yRange == 0)) {
      xRange = Math.max(1, xMax);
      yRange = Math.max(1, yMax);
    }
    float zScale = (float) Math.min(height / (yRange * 1.2), width / (xRange * 1.2));
    centroid.setTarget(xMin + 0.5f * xRange, yMin + 0.5f * yRange, zScale);
  }