/** * Set the partition bit to true for segments on the border and where the direction is 0 * * @param sl */ private void setPartitionBitForCertainSegments(ArrayList<Seg> sl) { for (int i = 0; i != sl.size(); i++) { Seg se = sl.get(i); if (((se.x == 0 || se.x == width) && se.dx == 0) || ((se.y == 0 || se.y == height) && se.dy == 0)) se.partition = true; } }
/** * It generates the nodes. In every node, it has two section, left and right. It chooses the * segment which has the minimum grade value and then split this node into two nodes through this * segment. If all the segments in one node are partitioned, it will stop to split. * * @param sl * @return root node for BSP tree */ private BSPNode genNodes(ArrayList<Seg> sl) { // if there is no segment with a partition bit set to false, there is nothing else to do and we // are at a leaf node if (countNonPartitions(sl) == 0) return new BSPLeaf(sl); // from the ones that have a partition bit set to false, pick a candidate with a low grade Seg pe = findPartitionCandidate(sl); // work on segment pe // mark pe as partitioned pe.partition = true; final int x = pe.x; final int y = pe.y; final int dx = pe.dx; final int dy = pe.dy; final ArrayList<Seg> lsl = new ArrayList<Seg>(); final ArrayList<Seg> rsl = new ArrayList<Seg>(); for (int i = 0; i != sl.size(); i++) { Seg se = (Seg) sl.get(i); int df1x = se.x - x; int df1y = se.y - y; int sendx = se.x + se.dx; int sendy = se.y + se.dy; int df2x = sendx - x; int df2y = sendy - y; int nx = dy; int ny = -dx; int dot1 = df1x * nx + df1y * ny; int dot2 = df2x * nx + df2y * ny; if (getSign(dot1) != getSign(dot2)) { if (dot1 == 0) dot1 = dot2; else if (dot2 != 0) { // we need to split this int spx = se.x; int spy = se.y; if (dx == 0) spx = x; else spy = y; Seg sps1 = new Seg(se.x, se.y, spx - se.x, spy - se.y, se.dist, colchange); Seg sps2 = new Seg(spx, spy, sendx - spx, sendy - spy, se.dist, colchange); if (dot1 > 0) { rsl.add(sps1); lsl.add(sps2); } else { rsl.add(sps2); lsl.add(sps1); } sps1.partition = sps2.partition = se.partition; continue; } } if (dot1 > 0 || (dot1 == 0 && se.getDir() == pe.getDir())) { rsl.add(se); if (dot1 == 0) se.partition = true; } else if (dot1 < 0 || (dot1 == 0 && se.getDir() == -pe.getDir())) { lsl.add(se); if (dot1 == 0) se.partition = true; } else { dbg("error xx 1 " + dot1); } } if (lsl.size() == 0) return new BSPLeaf(rsl); if (rsl.size() == 0) return new BSPLeaf(lsl); return new BSPBranch(x, y, dx, dy, genNodes(lsl), genNodes(rsl)); // recursion on both branches }