Package hermes.physics

Source Code of hermes.physics.InverseSquareInteractor

package hermes.physics;

import static hermes.HermesMath.reverse;
import hermes.*;
import processing.core.PVector;

/**
* <p>
* A general inverse square-law force interactor.
* Each being in the interaction will receive an equal and opposite force <b>F = k * q1 * q2 / r^2</b>
* where <b>k</b> is a factor set in the constructor, <b>q1</b> and <b>q2</b> are determined by <code>beingFactor</code>
* for the first and second beings respectively, and <b>r</b> is the distance between the beings. It can also be given a maximum range.
*
*/
public abstract class InverseSquareInteractor extends Interactor<MassedBeing, MassedBeing> {

  private float _maxRangeSquared;  // the maximum interaction range
  private float _k;         // the gravity constant
 
  /**
   * Sets up a <code>ColoumbInteractor</code> with a range limit.
   * @param factor  the force constant factor (k in the Coloumb equation)
   * @param maxRange  the maximum range of the interaction. Beings separated by a distance greater than this range will not interact.
   */
  public InverseSquareInteractor(float factor, float maxRange) {
    _k = factor;
    _maxRangeSquared = maxRange * maxRange;
  }
 
  /**
  * Sets up a <code>ColoumbInteractor</code> with no range limit.
   * @param factor  the force constant factor (k in the Coloumb equation)
   */
  public InverseSquareInteractor(float factor) {
    _k = factor;
    _maxRangeSquared = Float.POSITIVE_INFINITY;
  }
 
  public boolean detect(MassedBeing being1, MassedBeing being2) {
    if(being1 == being2) // no self-interaction
      return false;
    PVector r = PVector.sub(being1.getPosition(), being2.getPosition());
    float d_squared = r.dot(r);
    // check if the distance is within the maximum range
    return d_squared <= _maxRangeSquared && d_squared != 0;
  }

  public void handle(MassedBeing being1, MassedBeing being2) {
    // F = k * q1 * q2 / r^2
    PVector r = PVector.sub(being2.getPosition(), being1.getPosition());
    double d_squared = (double)r.dot(r);
    double F = _k * beingFactor(being1) * beingFactor(being2) / d_squared;
    r.normalize();
    PVector force = PVector.mult(r, (float)F);
    being2.addForce(force);
    being1.addForce(reverse(force));
  }
 
  /**
   * The factor from each being used in the numerator of the Coloumb equation
   * for example, charge for an electric force or mass for gravity.
   * @param being    a being
   * @return      the being's factor
   */
  abstract protected float beingFactor(MassedBeing being);
 
}
TOP

Related Classes of hermes.physics.InverseSquareInteractor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.