anchor.diff:  part of physics;
   
   /**
  - * Keeps the particle inside the given 3D box 
  + * Keeps the particle inside the given box shape
    */
   class Box extends Constraint<Particle3> 
   {
  
positive.code: 
  
  /**
   * Wraps the particle inside the given 3D box 
   */
  class BoxWrap extends Constraint<Particle3> 
  {
  
negative.code:   }
  }
  
  
  /**
   * Keeps the particle inside the given sphere
   */
  class Sphere extends Constraint<Particle3>
  {
    // settings
    Vector3 position = new Vector3.zero();
    double radius;
    bool isBouncy;
  
    // internal
    double _radiusSq;
  
    Sphere([this.radius = 100.0, this.isBouncy = true]);
  
    prepare() => _radiusSq = radius * radius;
  
    apply(Particle3 particle) {
      Vector3 delta = particle.position - position;
      double distSq = delta.length2;
  
      if(distSq >= _radiusSq) {
        Vector3 constrained = position + delta.normalize().scale(radius);
        if(isBouncy) {
          particle.position.setFrom(constrained); // bouncy
        } else { 
          particle.setPosition(constrained); // no-bounce
        }
      }
    }
  }
  