Пример #1
0
  /**
   * Updates the particle view. This should be called on each draw cycle in order to update the
   * positions of all nodes and edges in the viewer. If you need to update the positions of
   * particles without drawing it (e.g. to speed up movement, call updateParticles() instead.
   */
  public void draw() {
    parent.pushStyle();
    parent.pushMatrix();
    zoomer.transform();
    updateCentroid();
    centroid.tick();

    parent.translate(width / 2, height / 2);
    parent.scale(centroid.getZ());
    parent.translate(-centroid.getX(), -centroid.getY());

    if (!isPaused) {
      updateParticles();
    }

    // Ensure that any selected element is positioned at the mouse location.
    if (selectedNode != null) {
      Particle p = nodes.get(selectedNode);
      p.makeFixed();
      float mX = (zoomer.getMouseCoord().x - (width / 2)) / centroid.getZ() + centroid.getX();
      float mY = (zoomer.getMouseCoord().y - (height / 2)) / centroid.getZ() + centroid.getY();
      p.position().set(mX, mY, 0);
    }

    // Draw edges if we have positive stroke weight.
    if (parent.g.strokeWeight > 0) {
      parent.stroke(0, 180);
      parent.noFill();

      for (Map.Entry<E, Spring> row : edges.entrySet()) {
        E edge = row.getKey();
        Spring spring = row.getValue();
        Vector3D p1 = spring.getOneEnd().position();
        Vector3D p2 = spring.getTheOtherEnd().position();
        edge.draw(parent, p1.x(), p1.y(), p2.x(), p2.y());
      }
    }

    // Draw nodes.
    parent.noStroke();
    parent.fill(120, 50, 50, 180);

    for (Map.Entry<N, Particle> row : nodes.entrySet()) {
      N node = row.getKey();
      Vector3D p = row.getValue().position();
      node.draw(parent, p.x(), p.y());
    }

    parent.popMatrix();
    parent.popStyle();
  }
Пример #2
0
  /**
   * Creates a spring between the two given nodes with the given strength. If the two nodes not
   * directly connected by an edge already have a spring between them, it will be replaced by this
   * one.
   *
   * @param node1 First of the two nodes to have a spring between them.
   * @param node2 Second of the two nodes to have a spring between them.
   * @param length The length of this spring (natural rest distance at which the two nodes would
   *     sit).
   * @param strength The strength of this new spring.
   * @return True if the viewer contains the two nodes and a spring between them has been created.
   */
  public boolean addSpring(N node1, N node2, float length, float strength) {
    Particle p1 = nodes.get(node1);
    if (p1 == null) {
      return false;
    }
    Particle p2 = nodes.get(node2);
    if (p2 == null) {
      return false;
    }

    // We may have to remove existing spring if it exists between these two nodes.
    for (int i = 0; i < physics.getNumSprings(); i++) {
      Spring spring = physics.getSpring(i);
      if ((((spring.getOneEnd() == p1) && (spring.getTheOtherEnd() == p2))
              || ((spring.getOneEnd() == p2) && (spring.getTheOtherEnd() == p1)))
          && (spring.strength() != EDGE_STRENGTH)) {
        physics.removeSpring(spring);
        break;
      }
    }

    // Add the new force.
    physics.makeSpring(p1, p2, strength, DAMPING, length);
    return false;
  }
Пример #3
0
  /**
   * Attempts to space out non-connected nodes from one another. This is achieved by adding a strong
   * repulsive force between non-connected nodes. Note that this produces n-squared forces so can be
   * slow for large networks where many nodes are not connected to each other.
   */
  public void spaceNodes() {
    ArrayList<Particle> pList = new ArrayList<Particle>(nodes.values());
    for (int i = 0; i < pList.size(); i++) {
      for (int j = 0; j < pList.size(); j++) {
        if (i > j) {
          Particle p1 = pList.get(i);
          Particle p2 = pList.get(j);

          // See if we have a connection between nodes
          for (Spring spring : edges.values()) {
            if (((spring.getOneEnd() == p1) && (spring.getTheOtherEnd() == p2))
                || ((spring.getOneEnd() == p2) && (spring.getTheOtherEnd() == p1))) {
              // Do nothing as we already have an edge connecting these two particles
            } else {
              // Add a small repulsive force
              physics.makeAttraction(p1, p2, -1000, 0.1f);
            }
          }
        }
      }
    }
  }
Пример #4
0
  /**
   * Tethers the given node to its location with the given strength.
   *
   * @param node The node to be tethered.
   * @param strength Strength of the tether.
   * @return True if the viewer contains the given node and it was tethered successfully.
   */
  public boolean tether(N node, float strength) {
    Particle p1 = nodes.get(node);
    if (p1 == null) {
      return false;
    }

    // Grab the tethering stake if it has already been created, otherwise create a new one.
    Particle stake = stakes.get(node);
    if (stake == null) {
      stake = physics.makeParticle(1, node.getLocation().x, node.getLocation().y, 0);
      stake.makeFixed();
      stakes.put(node, stake);
    }

    // Grab the tether if it has already been created, otherwise create a new one.
    Spring tether = tethers.get(stake);
    if (tether == null) {
      tether = physics.makeSpring(stake, p1, strength, DAMPING, Float.MIN_VALUE);
      tethers.put(stake, tether);
    } else {
      tether.setStrength(strength);
    }
    return true;
  }