public static double minCosAngle(SpatialComparable v1,SpatialComparable v2){
  if (v1 instanceof NumberVector && v2 instanceof NumberVector) {
    return cosAngle((NumberVector)v1,(NumberVector)v2);
  }
  final int dim1=v1.getDimensionality(), dim2=v2.getDimensionality();
  final int mindim=(dim1 <= dim2) ? dim1 : dim2;
  double s1=0, s2=0, l1=0, l2=0;
  for (int k=0; k < mindim; k++) {
    final double min1=v1.getMin(k), max1=v1.getMax(k);
    final double min2=v2.getMin(k), max2=v2.getMax(k);
    final double p1=min1 * min2, p2=min1 * max2;
    final double p3=max1 * min2, p4=max1 * max2;
    s1+=Math.max(Math.max(p1,p2),Math.max(p3,p4));
    s2+=Math.min(Math.min(p1,p2),Math.min(p3,p4));
    if (max1 < 0) {
      l1+=max1 * max1;
    }
 else     if (min1 > 0) {
      l1+=min1 * min1;
    }
    if (max2 < 0) {
      l2+=max2 * max2;
    }
 else     if (min2 > 0) {
      l2+=min2 * min2;
    }
  }
  for (int k=mindim; k < dim1; k++) {
    final double min1=v1.getMin(k), max1=v1.getMax(k);
    if (max1 < 0.) {
      l1+=max1 * max1;
    }
 else     if (min1 > 0.) {
      l1+=min1 * min1;
    }
  }
  for (int k=mindim; k < dim2; k++) {
    final double min2=v2.getMin(k), max2=v2.getMax(k);
    if (max2 < 0.) {
      l2+=max2 * max2;
    }
 else     if (min2 > 0.) {
      l2+=min2 * min2;
    }
  }
  final double cross=Math.max(s1,Math.abs(s2));
  final double a=(cross == 0.) ? 0. : (l1 == 0. || l2 == 0.) ? 1. : Math.sqrt((cross / l1) * (cross / l2));
  return (a < 1.) ? a : 1.;
}

public static double minCosAngle ( SpatialComparable v1 , SpatialComparable v2 ) { if ( v1 instanceof NumberVector && v2 instanceof NumberVector ) { return cosAngle ( ( NumberVector ) v1 , ( NumberVector ) v2 ) ; } final int dim1 = v1 . getDimensionality ( ) , dim2 = v2 . getDimensionality ( ) ; final int mindim = ( dim1 <= dim2 ) ? dim1 : dim2 ; double s1 = 0 , s2 = 0 , l1 = 0 , l2 = 0 ; for ( int k = 0 ; k < mindim ; k ++ ) { final double min1 = v1 . getMin ( k ) , max1 = v1 . getMax ( k ) ; final double min2 = v2 . getMin ( k ) , max2 = v2 . getMax ( k ) ; final double p1 = min1 * min2 , p2 = min1 * max2 ; final double p3 = max1 * min2 , p4 = max1 * max2 ; s1 += Math . max ( Math . max ( p1 , p2 ) , Math . max ( p3 , p4 ) ) ; s2 += Math . min ( Math . min ( p1 , p2 ) , Math . min ( p3 , p4 ) ) ; if ( max1 < 0 ) { l1 += max1 * max1 ; } else if ( min1 > 0 ) { l1 += min1 * min1 ; } if ( max2 < 0 ) { l2 += max2 * max2 ; } else if ( min2 > 0 ) { l2 += min2 * min2 ; } } for ( int k = mindim ; k < dim1 ; k ++ ) { final double min1 = v1 . getMin ( k ) , max1 = v1 . getMax ( k ) ; if ( max1 < 0. ) { l1 += max1 * max1 ; } else if ( min1 > 0. ) { l1 += min1 * min1 ; } } for ( int k = mindim ; k < dim2 ; k ++ ) { final double min2 = v2 . getMin ( k ) , max2 = v2 . getMax ( k ) ; if ( max2 < 0. ) { l2 += max2 * max2 ; } else if ( min2 > 0. ) { l2 += min2 * min2 ; } } final double cross = Math . max ( s1 , Math . abs ( s2 ) ) ; final double a = ( cross == 0. ) ? 0. : ( l1 == 0. || l2 == 0. ) ? 1. : Math . sqrt ( ( cross / l1 ) * ( cross / l2 ) ) ; return ( a < 1. ) ? a : 1. ; }
compute the minimum angle between two rectangles .
