예제 #1
0
  /**
   * Cools down the movement on the node.
   *
   * @param current Node to cool
   * @param numOfIterations current state of layout process (heat)
   */
  private void calculateNodeCooling(Node current, double numOfIterations) {
    /* Check if cooling should start */
    if (COOLING_START_DELAY < numOfIterations) {
      double coolingFactor = 1 - ((numOfIterations - COOLING_START_DELAY) / COOLING_DIVIDER);
      // double coolingFactor = 1  / COOLING_DIVIDER;

      coolingFactor = Math.max(COOLING_FACTOR_MINIMUM, coolingFactor);

      /* Do some cooling, to stop the mad bouncing */
      double vx = current.getVX() * coolingFactor;
      double vy = current.getVY() * coolingFactor;
      /*  if(vx > MIN_VX) {
          current.setVX(vx);
      }
      else {
          current.setVX(0);
      }
      if(vy > MIN_VY) {
          current.setVY(vy);
      }
      else {
          current.setVY(0);
      }*/

      current.setVX(current.getVX() * coolingFactor);
      current.setVY(current.getVY() * coolingFactor);
    }
  }
예제 #2
0
 /**
  * This function slows down a node's velocity based on it's weight. So that the heavier the node
  * the less it moves.
  *
  * @param n node to apply friction for.
  */
 private void applyNodeFriction(Node n) {
   n.setVX(n.getVX() / n.getWeight());
   n.setVY(n.getVY() / n.getWeight());
 }
예제 #3
0
  /**
   * Layout core logic.
   *
   * <p>This iterates over all the nodes and determines their velocities based on a force directed
   * layout approach, performs collision detection/avoidance and then ultimately their new positions
   * as they move.
   */
  private void doLayout() {
    double maxVelocity = 100;
    double numOfIterations = 0;
    double step = 100;
    double skip = step;
    int counter = 1;
    boolean dividerChanged = false;

    // active = true;

    while (maxVelocity > 1 && active && (numOfIterations < MAX_NUM_OF_ITERATIONS)) {
      counter++;
      maxVelocity = 0;
      numOfIterations++;
      Iterator<Node> outer = controller.getNodeIterator();
      startTime = System.currentTimeMillis();

      double systemMovement = 0;

      double kineticEnergy = 0;

      /* Iterate over all nodes and calculate velocity */
      while (outer.hasNext()) {
        Node current = outer.next();
        current.resetVelocity();
        current.resetAcceleration();

        /*
         * If current node is not pinned or selected,
         * perform force directed layout calculations here.
         */
        if (!((current == controller.getGraphSelected()) || current.isPinned())) {
          calculateNodeAttractiveForce(current);
          calculateNodeRepulsiveForces(current);
          // applyNodeFriction(current);
          // if (IS_COOLING) {
          //    calculateNodeCooling(current, numOfIterations);
          // }

          // calculate velocities
          current.setVX(current.getVX() + current.accelx * TIMESTEP * DAMPING);
          current.setVY(current.getVY() + current.accely * TIMESTEP * DAMPING);

          double speedSquared =
              current.getVX() * current.getVX() + current.getVY() * current.getVY();
          kineticEnergy += 0.5 * current.weight * speedSquared;

          // cap the velocity
          if (current.getVX() >= 0) {
            current.setVX(Math.min(current.getVX(), MAX_DIST_PER_MOVE));
          } else {
            current.setVX(Math.max(current.getVX(), -MAX_DIST_PER_MOVE));
          }

          if (current.getVY() >= 0) {
            current.setVY(Math.min(current.getVY(), MAX_DIST_PER_MOVE));
          } else {
            current.setVY(Math.max(current.getVY(), -MAX_DIST_PER_MOVE));
          }

          // System.out.println("vy "+ current.getVY() + ", vx " + current.getVX());

        }
      }

      /* Iterate over all nodes move them after all the velocities are set */
      outer = controller.getNodeIterator();
      while (outer.hasNext()) {
        Node current = outer.next();
        int xStart = current.getX();
        int yStart = current.getY();

        /* update node position */
        int xEnd = current.getX() + (int) current.getVX();
        int yEnd = current.getY() + (int) current.getVY();
        int dX = Math.abs(xStart - xEnd);
        int dY = Math.abs(yStart - yEnd);

        // systemMovement += dX;
        // systemMovement += dY;

        // if(dX + dY > 6) {
        controller.moveNode(current, xEnd, yEnd);
        // }
        // controller.moveNode(current, Math.min(current.getX() + (int)
        // current.getVX(),MAX_DIST_PER_MOVE), Math.min(current.getY() + (int) current.getVY(),
        // MAX_DIST_PER_MOVE));

        /* compute maxVelocity for layout iteration */
        maxVelocity =
            Math.max(
                maxVelocity,
                Math.sqrt(Math.pow(current.getVX(), 2) + Math.pow(current.getVY(), 2)));
      }

      if (kineticEnergy < ENERGY_THRESHOLD) {
        numOfIterations = MAX_NUM_OF_ITERATIONS;
      }

      /* Make animation slower */
      try {
        Thread.sleep(sleepInterval);
      } catch (InterruptedException ex) {
      }

      /* Calculate how long the iteration took */
      stopTime = System.currentTimeMillis();
      long duration = stopTime - startTime;
      if ((duration > MAX_ITERATION_TIME) && (sleepInterval > 5)) {
        sleepInterval -= 5;
      } else if (duration < MIN_ITERATION_TIME) {
        sleepInterval += 5;
      }

      if (numOfIterations > skip) {
        skip += step;
        System.out.print('.');
      }
    }

    /* We've reached a stable layout, hold on for now */
    stable = true;
    // System.out.println("ran in " + numOfIterations + " iterations.");
  }