@Override
  public double computeDistance(PointVectorNN pv) {
    n.set(pv.p.x - model.center.x, pv.p.y - model.center.y, pv.p.z - model.center.z);
    n.normalize();

    if (Math.abs(n.dot(pv.normal)) < tolAngleCosine) return Double.MAX_VALUE;

    return Math.abs(Distance3D_F64.distance(model, pv.p));
  }
  /**
   * Randomly generate points on a plane by randomly selecting two vectors on the plane using cross
   * products
   */
  private List<Point3D_F64> randPointOnPlane(PlaneNormal3D_F64 plane, int N) {
    Vector3D_F64 v = new Vector3D_F64(-2, 0, 1);
    Vector3D_F64 a = UtilTrig_F64.cross(plane.n, v);
    a.normalize();
    Vector3D_F64 b = UtilTrig_F64.cross(plane.n, a);
    b.normalize();

    List<Point3D_F64> ret = new ArrayList<Point3D_F64>();

    for (int i = 0; i < N; i++) {
      double v0 = rand.nextGaussian();
      double v1 = rand.nextGaussian();

      Point3D_F64 p = new Point3D_F64();
      p.x = plane.p.x + v0 * a.x + v1 * b.x;
      p.y = plane.p.y + v0 * a.y + v1 * b.y;
      p.z = plane.p.z + v0 * a.z + v1 * b.z;

      ret.add(p);
    }

    return ret;
  }