Example #1
0
  /**
   * \brief Mutual shoving : The movement by shoving of an agent is calculated based on the cell
   * overlap and added to the agents movement vector.
   *
   * <p>Mutual shoving : The movement by shoving of an agent is calculated based on the cell overlap
   * and added to the agents movement vector. Both agents are moved of half the overlapping distance
   * in opposite directions.
   *
   * @param aNeighbour Reference to the potentially shoving neighbour
   * @param isMutual Whether movement is shared between two agents or applied only to this one
   * @param gain Double noting change in position
   * @return Boolean stating whether shoving is detected (true) or not (false)
   */
  public boolean addPushMovement(LocatedAgent aNeighbour, boolean isMutual, double gain) {
    double d, distance;

    if (aNeighbour == this) return false;

    // Build the escape vector and find the distance between you and your
    // neighbourhood
    d = computeDifferenceVector(_location, aNeighbour._location);

    _diff.normalizeVector();

    // Compute effective cell-cell distance
    distance = getShoveRadius() + aNeighbour.getShoveRadius();
    distance += getSpeciesParam().shoveLimit;
    distance = d - distance;

    /* Apply shoving _________________________________________________ */

    // Compute shoving distance for the current agent
    if (distance <= 0) {
      if (isMutual) {
        _diff.times(gain * 0.5 * Math.abs(distance));
        this._movement.add(_diff);
        aNeighbour._movement.subtract(_diff);
      } else {
        _diff.times(Math.abs(gain * distance));
        this._movement.add(_diff);
      }
      return true;
    } else {
      return false;
    }
  }
Example #2
0
  /**
   * \brief Set the movement vector that states where to put a newly-created particle
   *
   * <p>Set the movement vector that states where to put a newly-created particle
   *
   * @param distance Distance between the this agent and the new agent
   */
  public void setDivisionDirection(double distance) {
    double phi, theta;

    phi = 2 * Math.PI * ExtraMath.getUniRandDbl();
    theta = 2 * Math.PI * ExtraMath.getUniRandDbl();

    _divisionDirection.x = distance * Math.sin(phi) * Math.cos(theta);
    _divisionDirection.y = distance * Math.sin(phi) * Math.sin(theta);
    _divisionDirection.z = (_agentGrid.is3D ? distance * Math.cos(phi) : 0);
  }
Example #3
0
  /**
   * \brief Pulling : The movement of agents by a shrinking biofilm. Move calculated and added to
   * the agents movement vector.
   *
   * <p>The movement of agents by a shrinking biofilm. Move calculated and added to the agents
   * movement vector.
   *
   * @param aNeighbor Reference to the potentially shoving neighbour
   * @param isMutual Whether movement is shared between two agents or applied only to this one
   * @param gain Double noting change in position
   * @return Boolean stating whether pulling is detected (true) or not (false)
   */
  public boolean addSpringMovement(LocatedAgent aNeighbor, boolean isMutual, double gain) {
    double d, distance, delta;

    if (aNeighbor == this) return false;

    // Build the escape vector and find the distance between you and your
    // neighbourhood
    d = computeDifferenceVector(_location, aNeighbor._location);

    _diff.normalizeVector();

    distance = getShoveRadius() + aNeighbor.getShoveRadius();
    distance += getSpeciesParam().shoveLimit;

    delta = d - distance;
    double lMax = _totalRadius;

    if (delta > 0) gain *= Math.exp(-delta * 5 / (lMax));
    if (delta > lMax) gain = 0;

    /* Apply shoving _________________________________________________ */

    if (isMutual) {
      _diff.times(-0.5 * delta * gain);
      this._movement.add(_diff);
      aNeighbor._movement.subtract(_diff);
    } else {
      _diff.times(-delta * gain);
      this._movement.add(_diff);
    }

    return (_movement.norm() > _radius * gain);
  }
Example #4
0
  /**
   * \brief Computes the shortest distance between this agent and another, stored as
   * ContinuousVectors. This may be around the cyclic boundary
   *
   * <p>Computes the distance between this agent and another, stored as ContinuousVectors. This may
   * be around the cyclic boundary
   *
   * @param me ContinuousVector stating first agent location
   * @param him ContinuousVector stating other agent location
   * @return the shortest movement vector to go from a to b, take into account the cyclic boundary
   * @see addOverlapMovement
   * @see addPullMovement works in 2 and 3D
   */
  public double computeDifferenceVector(ContinuousVector me, ContinuousVector him) {
    double gridLength;

    _diff.x = me.x - him.x;
    // check periodicity in X
    gridLength = _species.domain.length_X;
    if (Math.abs(_diff.x) > .5 * gridLength) _diff.x -= Math.signum(_diff.x) * gridLength;

    _diff.y = me.y - him.y;
    // check periodicity in Y
    gridLength = _species.domain.length_Y;

    if (Math.abs(_diff.y) > .5 * gridLength) _diff.y -= Math.signum(_diff.y) * gridLength;

    if (_agentGrid.is3D) {
      _diff.z = me.z - him.z;
      // check periodicity in Z
      gridLength = _species.domain.length_Z;
      if (Math.abs(_diff.z) > .5 * gridLength) _diff.z -= Math.signum(_diff.z) * gridLength;

    } else {
      _diff.z = 0;
    }
    double d = Math.sqrt(_diff.x * _diff.x + _diff.y * _diff.y + _diff.z * _diff.z);

    if (d == 0) {
      d = 1e-2 * _radius;
      _diff.alea(_agentGrid.is3D);
    }

    return d;
  }