View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.geometry.core.partitioning.test;
18  
19  import java.util.Arrays;
20  import java.util.List;
21  
22  import org.apache.commons.geometry.core.Point;
23  import org.apache.commons.geometry.core.Region;
24  import org.apache.commons.geometry.core.RegionLocation;
25  import org.apache.commons.geometry.core.partitioning.bsp.BSPTree;
26  import org.apache.commons.geometry.core.partitioning.bsp.BSPTree.Node;
27  import org.apache.commons.numbers.core.Precision;
28  import org.junit.jupiter.api.Assertions;
29  
30  /** Class containing utility methods for tests related to the
31   * partition package.
32   */
33  public final class PartitionTestUtils {
34  
35      public static final double EPS = 1e-6;
36  
37      public static final Precision.DoubleEquivalence PRECISION =
38              Precision.doubleEquivalenceOfEpsilon(EPS);
39  
40  
41      private PartitionTestUtils() {}
42  
43      /**
44       * Asserts that corresponding values in the given points are equal.
45       * @param expected
46       * @param actual
47       */
48      public static void assertPointsEqual(final TestPoint2D expected, final TestPoint2D actual) {
49          final String msg = "Expected points to equal " + expected + " but was " + actual + ";";
50          Assertions.assertEquals(expected.getX(), actual.getX(), EPS, msg);
51          Assertions.assertEquals(expected.getY(), actual.getY(), EPS, msg);
52      }
53  
54      /** Assert that two line segments are equal using the default test epsilon.
55       * @param expected
56       * @param actual
57       */
58      public static void assertSegmentsEqual(final TestLineSegment expected, final TestLineSegment actual) {
59          final String msg = "Expected line segment to equal " + expected + " but was " + actual;
60  
61          Assertions.assertEquals(expected.getStartPoint().getX(),
62                  actual.getStartPoint().getX(), EPS, msg);
63          Assertions.assertEquals(expected.getStartPoint().getY(),
64                  actual.getStartPoint().getY(), EPS, msg);
65  
66          Assertions.assertEquals(expected.getEndPoint().getX(),
67                  actual.getEndPoint().getX(), EPS, msg);
68          Assertions.assertEquals(expected.getEndPoint().getY(),
69                  actual.getEndPoint().getY(), EPS, msg);
70      }
71  
72      /** Assert that all given points lie in the expected location of the region.
73       * @param region region to test
74       * @param location expected location of all points
75       * @param points points to test
76       */
77      public static void assertPointLocations(final Region<TestPoint2D> region, final RegionLocation location,
78              final TestPoint2D... points) {
79          assertPointLocations(region, location, Arrays.asList(points));
80      }
81  
82      /** Assert that all given points lie in the expected location of the region.
83       * @param region region to test
84       * @param location expected location of all points
85       * @param points points to test
86       */
87      public static void assertPointLocations(final Region<TestPoint2D> region, final RegionLocation location,
88              final List<TestPoint2D> points) {
89  
90          for (final TestPoint2D p : points) {
91              Assertions.assertEquals(location, region.classify(p), "Unexpected location for point " + p);
92          }
93      }
94  
95      /** Assert that the given node is a consistent internal node.
96       * @param node
97       */
98      public static void assertIsInternalNode(final Node<?, ?> node) {
99          Assertions.assertNotNull(node.getCut());
100         Assertions.assertNotNull(node.getMinus());
101         Assertions.assertNotNull(node.getPlus());
102 
103         Assertions.assertTrue(node.isInternal());
104         Assertions.assertFalse(node.isLeaf());
105     }
106 
107     /** Assert that the given node is a consistent leaf node.
108      * @param node
109      */
110     public static void assertIsLeafNode(final Node<?, ?> node) {
111         Assertions.assertNull(node.getCut());
112         Assertions.assertNull(node.getMinus());
113         Assertions.assertNull(node.getPlus());
114 
115         Assertions.assertFalse(node.isInternal());
116         Assertions.assertTrue(node.isLeaf());
117     }
118 
119     /** Assert that the given tree for has a valid, consistent internal structure. This checks that all nodes
120      * in the tree are owned by the tree, that the node depth values are correct, and the cut nodes have children
121      * and non-cut nodes do not.
122      * @param tree tree to check
123      */
124     public static <P extends Point<P>, N extends BSPTree.Node<P, N>> void assertTreeStructure(final BSPTree<P, N> tree) {
125         assertTreeStructureRecursive(tree, tree.getRoot(), 0);
126     }
127 
128     /** Recursive method to assert that a tree has a valid internal structure.
129      * @param tree tree to check
130      * @param node node to check
131      * @param expectedDepth the expected depth of the node in the tree
132      */
133     private static <P extends Point<P>, N extends BSPTree.Node<P, N>> void assertTreeStructureRecursive(
134             final BSPTree<P, N> tree, final BSPTree.Node<P, N> node, final int expectedDepth) {
135 
136         Assertions.assertSame(tree, node.getTree(), "Node has an incorrect owning tree");
137         Assertions.assertEquals(node.depth(), expectedDepth, "Node has an incorrect depth property");
138 
139         if (node.getCut() == null) {
140             final String msg = "Node without cut cannot have children";
141 
142             Assertions.assertNull(node.getMinus(), msg);
143             Assertions.assertNull(node.getPlus(), msg);
144         } else {
145             final String msg = "Node with cut must have children";
146 
147             Assertions.assertNotNull(node.getMinus(), msg);
148             Assertions.assertNotNull(node.getPlus(), msg);
149 
150             assertTreeStructureRecursive(tree, node.getPlus(), expectedDepth + 1);
151             assertTreeStructureRecursive(tree, node.getMinus(), expectedDepth + 1);
152         }
153     }
154 }