@Override public <A> int choose( A options, ArrayAdapter<? extends SpatialComparable, A> getter, SpatialComparable obj, int height, int depth) { final int size = getter.size(options); assert (size > 0) : "Choose from empty set?"; // R*-Tree: overlap increase for leaves. int best = -1; double least_overlap = Double.POSITIVE_INFINITY; double least_areainc = Double.POSITIVE_INFINITY; double least_area = Double.POSITIVE_INFINITY; // least overlap increase, on reduced candidate set: for (int i = 0; i < size; i++) { // Existing object and extended rectangle: SpatialComparable entry = getter.get(options, i); HyperBoundingBox mbr = SpatialUtil.union(entry, obj); // Compute relative overlap increase. double overlap_wout = 0.0; double overlap_with = 0.0; for (int k = 0; k < size; k++) { if (i != k) { SpatialComparable other = getter.get(options, k); overlap_wout += SpatialUtil.relativeOverlap(entry, other); overlap_with += SpatialUtil.relativeOverlap(mbr, other); } } double inc_overlap = overlap_with - overlap_wout; if (inc_overlap < least_overlap) { final double area = SpatialUtil.volume(entry); final double inc_area = SpatialUtil.volume(mbr) - area; // Volume increase and overlap increase: least_overlap = inc_overlap; least_areainc = inc_area; least_area = area; best = i; } else if (inc_overlap == least_overlap) { final double area = SpatialUtil.volume(entry); final double inc_area = SpatialUtil.volume(mbr) - area; if (inc_area < least_areainc || (inc_area == least_areainc && area < least_area)) { least_overlap = inc_overlap; least_areainc = inc_area; least_area = area; best = i; } } } assert (best > -1) : "No split found? Volume outside of double precision?"; return best; }
/** * Compute the union of a number of objects as a flat MBR (low-level, for index structures). * * @param data Object * @param getter Array adapter * @param <E> object type * @param <A> data value type * @return Flat MBR */ public static <E extends SpatialComparable, A> double[] unionFlatMBR( A data, ArrayAdapter<E, ? super A> getter) { final int num = getter.size(data); assert (num > 0) : "Cannot compute MBR of empty set."; final int dim; final double[] mbr; { // First entry final E first = getter.get(data, 0); dim = first.getDimensionality(); mbr = new double[2 * dim]; for (int d = 0; d < dim; d++) { mbr[d] = first.getMin(d); mbr[dim + d] = first.getMax(d); } } // Remaining entries for (int i = 1; i < num; i++) { E next = getter.get(data, i); for (int d = 0; d < dim; d++) { mbr[d] = Math.min(mbr[d], next.getMin(d)); mbr[dim + d] = Math.max(mbr[dim + d], next.getMax(d)); } } return mbr; }