Skip to content

Commit 9555f2a

Browse files
Change the childrenNodeIdFlatten to directly return all index that are not NO_CHILDREN
Signed-off-by: Nathan Dissoubray <nathan.dissoubray@rte-france.com>
1 parent 8d8741d commit 9555f2a

3 files changed

Lines changed: 31 additions & 33 deletions

File tree

diagram-util/src/main/java/com/powsybl/diagram/util/layout/forces/RepulsionForceDegreeBasedLinearBarnesHut.java

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -105,15 +105,12 @@ private void generatePointInteractionList(
105105
} else {
106106
Quadtree.QuadtreeNode thisNode = quadtree.getNodes()[nodeIndex];
107107
double childNodeWidth = nodeWidth / 2;
108-
int numberOfChild = 0;
109-
for (int index : thisNode.getChildrenNodeIdFlatten()) {
110-
if (index != Quadtree.NO_CHILDREN) {
111-
++numberOfChild;
112-
generatePointInteractionList(index, point, childNodeWidth, pointsToInteractWith);
113-
}
108+
int[] realChildrenId = thisNode.getRealChildrenNodeIndex();
109+
for (int index : realChildrenId) {
110+
generatePointInteractionList(index, point, childNodeWidth, pointsToInteractWith);
114111
}
115112
// if the list is empty, it means we are a leaf node, need to add self to the list and return
116-
if (numberOfChild == 0) {
113+
if (realChildrenId.length == 0) {
117114
pointsToInteractWith.add(barycenter);
118115
}
119116
}

diagram-util/src/main/java/com/powsybl/diagram/util/layout/geometry/Quadtree.java

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import java.util.List;
1313
import java.util.function.Predicate;
1414
import java.util.function.ToDoubleFunction;
15+
import java.util.stream.Stream;
1516

1617
/**
1718
* A quadtree is a structure that recursively divides a space in 4 until only a given number of points reside in each subdivided area. In this case,
@@ -23,18 +24,23 @@
2324
public class Quadtree {
2425
public static class QuadtreeNode {
2526
// package private
26-
int[][] childrenNodeId = {
27+
int[][] childrenNodeIndex = {
2728
{NO_CHILDREN, NO_CHILDREN},
2829
{NO_CHILDREN, NO_CHILDREN}
2930
};
3031

31-
public int[] getChildrenNodeIdFlatten() {
32-
return new int[] {
33-
childrenNodeId[0][0],
34-
childrenNodeId[0][1],
35-
childrenNodeId[1][0],
36-
childrenNodeId[1][1]
37-
};
32+
/**
33+
* @return all the index of children that actually exists (ie all quadrants that have at least a point in them)
34+
*/
35+
public int[] getRealChildrenNodeIndex() {
36+
return Stream.of(
37+
childrenNodeIndex[0][0],
38+
childrenNodeIndex[0][1],
39+
childrenNodeIndex[1][0],
40+
childrenNodeIndex[1][1]
41+
).filter(id -> id != NO_CHILDREN)
42+
.mapToInt(Integer::intValue)
43+
.toArray();
3844
}
3945
}
4046

@@ -158,10 +164,10 @@ private int buildQuadtree(
158164
BoundingBox topLeftBb = new BoundingBox(boundingBox.left(), boundingBox.top(), boundingBoxCenter.getX(), boundingBoxCenter.getY());
159165
BoundingBox topRightBb = new BoundingBox(boundingBoxCenter.getX(), boundingBox.top(), boundingBox.right(), boundingBoxCenter.getY());
160166

161-
nodesList.get(newNodeIndex).childrenNodeId[0][0] = buildQuadtree(nodesList, barycentersList, points, bottomLeftBb, firstIndex, xLowerSplitIndex, massGetter, firstIndex, lastIndex, remainingDepth - 1);
162-
nodesList.get(newNodeIndex).childrenNodeId[0][1] = buildQuadtree(nodesList, barycentersList, points, bottomRightBb, xLowerSplitIndex, ySplitIndex, massGetter, firstIndex, lastIndex, remainingDepth - 1);
163-
nodesList.get(newNodeIndex).childrenNodeId[1][0] = buildQuadtree(nodesList, barycentersList, points, topLeftBb, ySplitIndex, xUpperSplitIndex, massGetter, firstIndex, lastIndex, remainingDepth - 1);
164-
nodesList.get(newNodeIndex).childrenNodeId[1][1] = buildQuadtree(nodesList, barycentersList, points, topRightBb, xUpperSplitIndex, lastIndex, massGetter, firstIndex, lastIndex, remainingDepth - 1);
167+
nodesList.get(newNodeIndex).childrenNodeIndex[0][0] = buildQuadtree(nodesList, barycentersList, points, bottomLeftBb, firstIndex, xLowerSplitIndex, massGetter, firstIndex, lastIndex, remainingDepth - 1);
168+
nodesList.get(newNodeIndex).childrenNodeIndex[0][1] = buildQuadtree(nodesList, barycentersList, points, bottomRightBb, xLowerSplitIndex, ySplitIndex, massGetter, firstIndex, lastIndex, remainingDepth - 1);
169+
nodesList.get(newNodeIndex).childrenNodeIndex[1][0] = buildQuadtree(nodesList, barycentersList, points, topLeftBb, ySplitIndex, xUpperSplitIndex, massGetter, firstIndex, lastIndex, remainingDepth - 1);
170+
nodesList.get(newNodeIndex).childrenNodeIndex[1][1] = buildQuadtree(nodesList, barycentersList, points, topRightBb, xUpperSplitIndex, lastIndex, massGetter, firstIndex, lastIndex, remainingDepth - 1);
165171
setNodeBarycenter(barycentersList, nodesList.get(newNodeIndex), nodeBarycenter);
166172

167173
return newNodeIndex;
@@ -234,19 +240,16 @@ private void setLeafBarycenter(Point[] points, Point nodeBarycenter, int startIn
234240
* @param nodeBarycenter the barycenter of the node, the one we are setting the mass and position of
235241
*/
236242
private void setNodeBarycenter(List<Point> barycentersList, QuadtreeNode node, Point nodeBarycenter) {
237-
int[] barycenterIndex = node.getChildrenNodeIdFlatten();
243+
int[] barycenterIndex = node.getRealChildrenNodeIndex();
238244
Vector2D barycenterPosition = new Vector2D();
239245
double totalBarycenterMass = 0;
240246
for (int index : barycenterIndex) {
241-
// index is only -1 in the case of nothing being there
242-
if (index != NO_CHILDREN) {
243-
// get the mass / position of each quadrant and do a weighted sum (quite literally)
244-
Point quadrantBarycenter = barycentersList.get(index);
245-
// do not use the massGetter, that's only for leaf nodes, quadrants contain leaf which already have their correct mass set
246-
double quadrantMass = quadrantBarycenter.getMass();
247-
barycenterPosition.addScaled(quadrantBarycenter.getPosition(), quadrantMass);
248-
totalBarycenterMass += quadrantMass;
249-
}
247+
// get the mass / position of each quadrant and do a weighted sum (quite literally)
248+
Point quadrantBarycenter = barycentersList.get(index);
249+
// do not use the massGetter, that's only for leaf nodes, quadrants contain leaf which already have their correct mass set
250+
double quadrantMass = quadrantBarycenter.getMass();
251+
barycenterPosition.addScaled(quadrantBarycenter.getPosition(), quadrantMass);
252+
totalBarycenterMass += quadrantMass;
250253
}
251254
barycenterPosition.divideBy(totalBarycenterMass);
252255
nodeBarycenter.setPosition(barycenterPosition);

diagram-util/src/test/java/com/powsybl/diagram/util/layout/geometry/QuadtreeTest.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,12 +102,10 @@ private void checkChildBarycenter(
102102
) {
103103
double delta = 1e-3;
104104
Quadtree.QuadtreeNode thisNode = nodes[parentNodeIndex];
105-
int[] subAreaIndexList = thisNode.getChildrenNodeIdFlatten();
105+
int[] subAreaIndexList = thisNode.getRealChildrenNodeIndex();
106106
// check all child areas
107107
for (int subAreaIndex : subAreaIndexList) {
108-
if (subAreaIndex != Quadtree.NO_CHILDREN) {
109-
checkChildBarycenter(subAreaIndex, nodes, barycenters, expectedBarycenters);
110-
}
108+
checkChildBarycenter(subAreaIndex, nodes, barycenters, expectedBarycenters);
111109
}
112110
// now check this node
113111
Point barycenter = barycenters[parentNodeIndex];

0 commit comments

Comments
 (0)