public static List<double[]> getCorners(SpatialComparable box) { ArrayList<double[]> corners = new ArrayList<double[]>(); if (SpatialUtil.perimeter(box) == 0) { corners.add(SpatialUtil.getMin(box)); return corners; } boolean[] current = new boolean[box.getDimensionality()]; int dim = box.getDimensionality(); for (int i = 0; i < Math.pow(2, dim); i++) { double[] newCorner = new double[dim]; for (int j = 0; j < dim; j++) { if (current[j]) newCorner[j] = box.getMin(j); else newCorner[j] = box.getMax(j); } addOne(current); corners.add(newCorner); } return corners; }
@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; }