/** * \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; }
/** * \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; } }