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 ; // Essentially, we want to compute this: // absmax(v1.transposeTimes(v2))/(min(v1.euclideanLength())*min(v2.euclideanLength())); // We can just compute all three in parallel. 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 ; } // else: 0 if ( max2 < 0 ) { l2 += max2 * max2 ; } else if ( min2 > 0 ) { l2 += min2 * min2 ; } // else: 0 } 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 ; } // else: 0 } 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 ; } // else: 0 } final double cross = Math . max ( Math . abs ( s1 ) , Math . abs ( s2 ) ) ; final double a = ( cross == 0. ) ? 0. : // ( l1 == 0. || l2 == 0. ) ? 1. : // FastMath . sqrt ( ( cross / l1 ) * ( cross / l2 ) ) ; return ( a < 1. ) ? a : 1. ; }
Compute the minimum angle between two rectangles .