Refactor QuadTree DoSquaresOverlap() and add UnitTest
This commit is contained in:
@@ -146,30 +146,34 @@ public class QuadTree<T>
|
||||
|
||||
|
||||
// check if the testPos is within the X,Z boundary of the tree
|
||||
DhBlockPos2D blockCornerOfTree = this.centerBlockPos.add(new DhBlockPos2D(-this.widthInBlocks/2,-this.widthInBlocks/2));
|
||||
DhLodPos cornerOfTreePos = new DhLodPos((byte)0, blockCornerOfTree.x, blockCornerOfTree.z);
|
||||
DhBlockPos2D treeBlockCorner = this.centerBlockPos.add(new DhBlockPos2D(-this.widthInBlocks/2,-this.widthInBlocks/2));
|
||||
DhLodPos treeCornerPos = new DhLodPos((byte)0, treeBlockCorner.x, treeBlockCorner.z);
|
||||
|
||||
DhSectionPos sectionCornerOfInput = testPos.convertToDetailLevel((byte)0);
|
||||
DhLodPos cornerOfInputPos = new DhLodPos((byte)0, sectionCornerOfInput.sectionX, sectionCornerOfInput.sectionZ);
|
||||
int inputWidth = BitShiftUtil.powerOfTwo(testPos.sectionDetailLevel);
|
||||
DhSectionPos inputSectionCorner = testPos.convertToDetailLevel((byte)0);
|
||||
DhLodPos inputCornerPos = new DhLodPos((byte)0, inputSectionCorner.sectionX, inputSectionCorner.sectionZ);
|
||||
int inputBlockWidth = BitShiftUtil.powerOfTwo(testPos.sectionDetailLevel);
|
||||
|
||||
return DoSquaresOverlap(cornerOfTreePos, this.widthInBlocks, cornerOfInputPos, inputWidth);
|
||||
return DoSquaresOverlap(treeCornerPos, this.widthInBlocks, inputCornerPos, inputBlockWidth);
|
||||
}
|
||||
private static boolean DoSquaresOverlap(DhLodPos rect1Min, int rect1Width, DhLodPos rect2Min, int rect2Width)
|
||||
private static boolean DoSquaresOverlap(DhLodPos square1Min, int square1Width, DhLodPos square2Min, int square2Width)
|
||||
{
|
||||
// Determine the coordinates of the rectangles
|
||||
float rect1MinX = rect1Min.x;
|
||||
float rect1MaxX = rect1Min.x + rect1Width;
|
||||
float rect1MinZ = rect1Min.z;
|
||||
float rect1MaxZ = rect1Min.z + rect1Width;
|
||||
|
||||
float rect2MinX = rect2Min.x;
|
||||
float rect2MaxX = rect2Min.x + rect2Width;
|
||||
float rect2MinZ = rect2Min.z;
|
||||
float rect2MaxZ = rect2Min.z + rect2Width;
|
||||
|
||||
// Check if the rectangles overlap
|
||||
return rect1MinX < rect2MaxX && rect1MaxX > rect2MinX && rect1MinZ < rect2MaxZ && rect1MaxZ > rect2MinZ;
|
||||
// Determine the coordinates of the squares (the variables say rect[angle] because this logic would also work there and was simplified to work for squares)
|
||||
float rect1MinX = square1Min.x;
|
||||
float rect1MaxX = square1Min.x + square1Width;
|
||||
float rect1MinZ = square1Min.z;
|
||||
float rect1MaxZ = square1Min.z + square1Width;
|
||||
|
||||
float rect2MinX = square2Min.x;
|
||||
float rect2MaxX = square2Min.x + square2Width;
|
||||
float rect2MinZ = square2Min.z;
|
||||
float rect2MaxZ = square2Min.z + square2Width;
|
||||
|
||||
// Check if the squares overlap
|
||||
return
|
||||
rect1MinX < rect2MaxX &&
|
||||
rect1MaxX > rect2MinX &&
|
||||
rect1MinZ < rect2MaxZ &&
|
||||
rect1MaxZ > rect2MinZ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -165,6 +165,27 @@ public class QuadTreeTest
|
||||
Assert.assertEquals("incorrect leaf node count", 4, tree.leafNodeCount());
|
||||
|
||||
}
|
||||
@Test
|
||||
public void outOfBoundsInTreeTest()
|
||||
{
|
||||
// very specific tree parameters to match test results
|
||||
QuadTree<Integer> tree = new QuadTree<>(512, new DhBlockPos2D(125, -516), (byte)6);
|
||||
Assert.assertEquals("Test may need to be re-calculated for different max detail level.", 9, tree.treeMaxDetailLevel);
|
||||
|
||||
|
||||
DhSectionPos rootPos = new DhSectionPos((byte)9, 0, -1);
|
||||
testSet(tree, rootPos, 1);
|
||||
|
||||
// pos is in tree, but out of range
|
||||
DhSectionPos midPos = new DhSectionPos((byte)8, 0, -1);
|
||||
testSet(tree, midPos, 2, IndexOutOfBoundsException.class);
|
||||
|
||||
// pos is in tree, but out of range
|
||||
DhSectionPos leafPos = new DhSectionPos((byte)7, 0, -2);
|
||||
testSet(tree, leafPos, 3, IndexOutOfBoundsException.class);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void QuadTreeRootAlignedMovingTest()
|
||||
@@ -738,6 +759,66 @@ public class QuadTreeTest
|
||||
|
||||
}
|
||||
|
||||
// null node auto-deletion not yet implemented
|
||||
//@Test
|
||||
public void autoDeleteNullQuadNodeChildTest()
|
||||
{
|
||||
QuadNode<Integer> rootNode = new QuadNode<>(new DhSectionPos((byte)10, 0, 0), LodUtil.BLOCK_DETAIL_LEVEL);
|
||||
|
||||
|
||||
rootNode.setValue(new DhSectionPos((byte)10, 0, 0), 0);
|
||||
|
||||
DhSectionPos midNodePos = new DhSectionPos((byte)9, 0, 0);
|
||||
//rootNode.setValue(midNodePos, null); // holds detail 8
|
||||
rootNode.setValue(new DhSectionPos((byte)9, 1, 0), 1);
|
||||
rootNode.setValue(new DhSectionPos((byte)9, 0, 1), 1);
|
||||
rootNode.setValue(new DhSectionPos((byte)9, 1, 1), 1);
|
||||
|
||||
rootNode.setValue(new DhSectionPos((byte)8, 0, 0), 2);
|
||||
rootNode.setValue(new DhSectionPos((byte)8, 1, 0), 2);
|
||||
rootNode.setValue(new DhSectionPos((byte)8, 0, 1), 2);
|
||||
rootNode.setValue(new DhSectionPos((byte)8, 1, 1), 2);
|
||||
|
||||
|
||||
|
||||
// validate nodes were added
|
||||
Assert.assertEquals(4, rootNode.getChildValueCount());
|
||||
Assert.assertEquals(4, rootNode.getNode(midNodePos).getChildValueCount());
|
||||
|
||||
|
||||
|
||||
// test removing nodes //
|
||||
|
||||
// remove two leaf nodes from the root
|
||||
DhSectionPos leafPos = new DhSectionPos((byte)9, 1, 1);
|
||||
rootNode.setValue(leafPos, null);
|
||||
Assert.assertEquals(3, rootNode.getChildValueCount());
|
||||
Assert.assertNull("Node wasn't deleted", rootNode.getNode(leafPos));
|
||||
|
||||
leafPos = new DhSectionPos((byte)9, 0, 1);
|
||||
rootNode.setValue(leafPos, null);
|
||||
Assert.assertEquals(2, rootNode.getChildValueCount());
|
||||
Assert.assertNull("Node wasn't deleted", rootNode.getNode(leafPos));
|
||||
|
||||
|
||||
// remove
|
||||
|
||||
// remove all child nodes
|
||||
Assert.assertEquals(4, rootNode.getNode(midNodePos).getChildValueCount());
|
||||
|
||||
// remove all but one, mid-node should still be present
|
||||
rootNode.setValue(new DhSectionPos((byte)8, 0, 0), null);
|
||||
rootNode.setValue(new DhSectionPos((byte)8, 0, 1), null);
|
||||
rootNode.setValue(new DhSectionPos((byte)8, 1, 0), null);
|
||||
Assert.assertEquals(1, rootNode.getNode(midNodePos).getChildValueCount());
|
||||
|
||||
// remove last mid-node child, mid-node should now be removed
|
||||
rootNode.setValue(new DhSectionPos((byte)8, 1, 1), null);
|
||||
Assert.assertNull("Mid node not deleted.", rootNode.getNode(midNodePos));
|
||||
Assert.assertEquals(3, rootNode.getChildValueCount());
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user