예제 #1
0
  protected void attraction(Vector3 delta) {
    for (EdgeSpring edge : neighbours) {
      if (!edge.ignored) {
        NodeParticle other = edge.getOpposite(this);

        delta.set(other.pos.x - pos.x, other.pos.y - pos.y, box.is3D ? other.pos.z - pos.z : 0);

        double len = delta.normalize();
        double k = box.k * edge.weight;

        double factor = box.K1 * (len - k);

        // delta.scalarMult( factor );
        delta.scalarMult(factor * (1f / (neighbours.size() * 0.1f))); // XXX
        // NEW
        // inertia
        // based
        // on
        // the
        // node
        // degree.
        disp.add(delta);
        attE += factor;

        box.energies.accumulateEnergy(factor);
      }
    }
  }
예제 #2
0
  /**
   * Compute the repulsion for each other node. This is the most precise way, but the algorithm is a
   * time hog : complexity is O(n^2).
   *
   * @param delta The computed displacement vector.
   */
  protected void repulsionN2(Vector3 delta) {
    Iterator<Object> i = box.nodes.getParticleIdIterator();

    while (i.hasNext()) {
      NodeParticle node = (NodeParticle) box.nodes.getParticle(i.next());

      if (node != this) {
        delta.set(node.pos.x - pos.x, node.pos.y - pos.y, box.is3D ? node.pos.z - pos.z : 0);

        double len = delta.normalize();
        double factor = len != 0 ? ((box.K2 / (len * len)) * node.weight) : 0.00001f;

        delta.scalarMult(-factor);
        disp.add(delta);
        box.energies.accumulateEnergy(factor); // TODO check this
      }
    }
  }
예제 #3
0
  @Override
  public void move(int time) {
    if (!frozen) {
      disp.fill(0);

      Vector3 delta = new Vector3();

      repE = 0;
      attE = 0;

      if (box.viewZone < 0) repulsionN2(delta);
      else repulsionNLogN(delta);

      attraction(delta);

      // int N = neighbours.size();
      // if( N > 40 )
      // System.err.printf( "* BIG ** [%05d] rep=%05.5f att=%05.5f%n", N,
      // repE, attE );
      // else System.err.printf(
      // "  Small  [%05d] rep=%05.5f att=%05.5f%n", N, repE, attE );

      disp.scalarMult(box.force);

      len = disp.length();

      if (len > (box.area / 2)) {
        disp.scalarMult((box.area / 2) / len);
        len = box.area / 2;
      }

      box.avgLength += len;

      if (len > box.maxMoveLength) box.maxMoveLength = len;
    }
  }
예제 #4
0
  protected void recurseRepulsion(Cell cell, Vector3 delta) {
    if (intersection(cell)) {
      if (cell.isLeaf()) {
        Iterator<? extends Particle> i = cell.getParticles();

        while (i.hasNext()) {
          NodeParticle node = (NodeParticle) i.next();

          if (node != this) {
            delta.set(node.pos.x - pos.x, node.pos.y - pos.y, box.is3D ? node.pos.z - pos.z : 0);

            double len = delta.normalize();

            if (len > 0) // && len < ( box.k * box.viewZone ) )
            {
              if (len < box.k) len = box.k; // XXX NEW To prevent infinite
              // repulsion.
              double factor = len != 0 ? ((box.K2 / (len * len)) * node.weight) : 0.00001;
              box.energies.accumulateEnergy(factor); // TODO check
              // this
              repE += factor;
              delta.scalarMult(-factor);

              disp.add(delta);
            }
          }
        }
      } else {
        int div = cell.getSpace().getDivisions();

        for (int i = 0; i < div; i++) recurseRepulsion(cell.getSub(i), delta);
      }
    } else {
      if (cell != this.cell) {
        BarycenterCellData bary = (BarycenterCellData) cell.getData();

        double dist = bary.distanceFrom(pos);
        double size = cell.getSpace().getSize();

        if ((!cell.isLeaf()) && ((size / dist) > box.theta)) {
          int div = cell.getSpace().getDivisions();

          for (int i = 0; i < div; i++) recurseRepulsion(cell.getSub(i), delta);
        } else {
          if (bary.weight != 0) {
            // System.err.printf(
            // "applying bary %s [depth=%d weight=%d]%n",
            // cell.getId(), cell.getDepth(), (int)bary.weight );
            delta.set(
                bary.center.x - pos.x, bary.center.y - pos.y, box.is3D ? bary.center.z - pos.z : 0);

            double len = delta.normalize();

            if (len > 0) {
              if (len < box.k) len = box.k; // XXX NEW To prevent infinite
              // repulsion.
              double factor = len != 0 ? ((box.K2 / (len * len)) * (bary.weight)) : 0.00001f;
              box.energies.accumulateEnergy(factor);
              delta.scalarMult(-factor);
              repE += factor;

              disp.add(delta);
            }
          }
        }
      }
    }
  }