private static Object[] iter(List<VBox> lh, double target, int[] histo, int nColors, int niters) { VBox vbox; while (niters < MAX_ITERATIONS) { vbox = lh.get(lh.size() - 1); lh.remove(lh.size() - 1); if (vbox.count(false) == 0) { lh.add(vbox); niters++; continue; } VBox[] vboxes = medianCutApply(histo, vbox); VBox vbox1 = vboxes[0]; VBox vbox2 = vboxes[1]; if (vbox1 == null) return new Object[] {lh, nColors, niters}; lh.add(vbox1); if (vbox2 != null) { lh.add(vbox2); nColors++; } if (nColors >= target) return new Object[] {lh, nColors, niters}; if (niters++ > MAX_ITERATIONS) { return new Object[] {lh, nColors, niters}; } Collections.sort(lh); } return new Object[] {lh, nColors, niters}; }
@Override public int compareTo(Object o) { VBox anotherVBox = (VBox) o; return count(false) * getVolume(false) - anotherVBox.count(false) * anotherVBox.getVolume(false); }
private static VBox[] medianCutApply(int[] histo, VBox vbox) { if (vbox.count(false) == 0) return null; if (vbox.count(false) == 1) { return new VBox[] {vbox.copy()}; } int rw = vbox.r2 - vbox.r1 + 1, gw = vbox.g2 - vbox.g1 + 1, bw = vbox.b2 - vbox.b1 + 1, maxw = Math.max(Math.max(rw, gw), bw); int total = 0; List<Integer> partialsum = new ArrayList<>(); List<Integer> lookaheadsum = new ArrayList<>(); if (maxw == rw) { for (int i = vbox.r1; i <= vbox.r2; i++) { int sum = 0; for (int j = vbox.g1; j <= vbox.g2; j++) { for (int k = vbox.b1; k <= vbox.b2; k++) { sum += histo[getColorIndex(i, j, k)]; } } total += sum; if (partialsum.size() < i) { int toAdd = i - partialsum.size(); for (int l = partialsum.size(); l < toAdd; l++) { partialsum.add(0); } } partialsum.add(i, total); } } else if (maxw == gw) { for (int i = vbox.g1; i <= vbox.g2; i++) { int sum = 0; for (int j = vbox.r1; j <= vbox.r2; j++) { for (int k = vbox.b1; k <= vbox.b2; k++) { sum += histo[getColorIndex(j, i, k)]; } } total += sum; if (partialsum.size() < i) { int toAdd = i - partialsum.size(); for (int l = partialsum.size(); l < toAdd; l++) { partialsum.add(0); } } partialsum.add(i, total); } } else { for (int i = vbox.b1; i <= vbox.b2; i++) { int sum = 0; for (int j = vbox.r1; j <= vbox.r2; j++) { for (int k = vbox.g1; k <= vbox.g2; k++) { sum += histo[getColorIndex(j, k, i)]; } } total += sum; if (partialsum.size() < i) { int toAdd = i - partialsum.size(); for (int l = partialsum.size(); l < toAdd; l++) { partialsum.add(0); } } partialsum.add(i, total); } } for (int i = 0; i < partialsum.size(); i++) { lookaheadsum.add(i, total - partialsum.get(i)); } return maxw == rw ? doCut(RED, vbox, partialsum, lookaheadsum, total) : maxw == gw ? doCut(GREEN, vbox, partialsum, lookaheadsum, total) : doCut(BLUE, vbox, partialsum, lookaheadsum, total); }