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.geometry.core.precision.DoublePrecisionContext;
28  import org.apache.commons.geometry.core.precision.EpsilonDoublePrecisionContext;
29  import org.junit.Assert;
30  
31  /** Class containing utility methods for tests related to the
32   * partition package.
33   */
34  public final class PartitionTestUtils {
35  
36      public static final double EPS = 1e-6;
37  
38      public static final DoublePrecisionContext PRECISION =
39              new EpsilonDoublePrecisionContext(EPS);
40  
41  
42      private PartitionTestUtils() {}
43  
44      /**
45       * Asserts that corresponding values in the given points are equal.
46       * @param expected
47       * @param actual
48       */
49      public static void assertPointsEqual(final TestPoint2D expected, final TestPoint2D actual) {
50          final String msg = "Expected points to equal " + expected + " but was " + actual + ";";
51          Assert.assertEquals(msg, expected.getX(), actual.getX(), EPS);
52          Assert.assertEquals(msg, expected.getY(), actual.getY(), EPS);
53      }
54  
55      /** Assert that two line segments are equal using the default test epsilon.
56       * @param expected
57       * @param actual
58       */
59      public static void assertSegmentsEqual(final TestLineSegment expected, final TestLineSegment actual) {
60          final String msg = "Expected line segment to equal " + expected + " but was " + actual;
61  
62          Assert.assertEquals(msg, expected.getStartPoint().getX(),
63                  actual.getStartPoint().getX(), EPS);
64          Assert.assertEquals(msg, expected.getStartPoint().getY(),
65                  actual.getStartPoint().getY(), EPS);
66  
67          Assert.assertEquals(msg, expected.getEndPoint().getX(),
68                  actual.getEndPoint().getX(), EPS);
69          Assert.assertEquals(msg, expected.getEndPoint().getY(),
70                  actual.getEndPoint().getY(), EPS);
71      }
72  
73      /** Assert that all given points lie in the expected location of the region.
74       * @param region region to test
75       * @param location expected location of all points
76       * @param points points to test
77       */
78      public static void assertPointLocations(final Region<TestPoint2D> region, final RegionLocation location,
79              final TestPoint2D... points) {
80          assertPointLocations(region, location, Arrays.asList(points));
81      }
82  
83      /** Assert that all given points lie in the expected location of the region.
84       * @param region region to test
85       * @param location expected location of all points
86       * @param points points to test
87       */
88      public static void assertPointLocations(final Region<TestPoint2D> region, final RegionLocation location,
89              final List<TestPoint2D> points) {
90  
91          for (final TestPoint2D p : points) {
92              Assert.assertEquals("Unexpected location for point " + p, location, region.classify(p));
93          }
94      }
95  
96      /** Assert that the given node is a consistent internal node.
97       * @param node
98       */
99      public static void assertIsInternalNode(final Node<?, ?> node) {
100         Assert.assertNotNull(node.getCut());
101         Assert.assertNotNull(node.getMinus());
102         Assert.assertNotNull(node.getPlus());
103 
104         Assert.assertTrue(node.isInternal());
105         Assert.assertFalse(node.isLeaf());
106     }
107 
108     /** Assert that the given node is a consistent leaf node.
109      * @param node
110      */
111     public static void assertIsLeafNode(final Node<?, ?> node) {
112         Assert.assertNull(node.getCut());
113         Assert.assertNull(node.getMinus());
114         Assert.assertNull(node.getPlus());
115 
116         Assert.assertFalse(node.isInternal());
117         Assert.assertTrue(node.isLeaf());
118     }
119 
120     /** Assert that the given tree for has a valid, consistent internal structure. This checks that all nodes
121      * in the tree are owned by the tree, that the node depth values are correct, and the cut nodes have children
122      * and non-cut nodes do not.
123      * @param tree tree to check
124      */
125     public static <P extends Point<P>, N extends BSPTree.Node<P, N>> void assertTreeStructure(final BSPTree<P, N> tree) {
126         assertTreeStructureRecursive(tree, tree.getRoot(), 0);
127     }
128 
129     /** Recursive method to assert that a tree has a valid internal structure.
130      * @param tree tree to check
131      * @param node node to check
132      * @param expectedDepth the expected depth of the node in the tree
133      */
134     private static <P extends Point<P>, N extends BSPTree.Node<P, N>> void assertTreeStructureRecursive(
135             final BSPTree<P, N> tree, final BSPTree.Node<P, N> node, final int expectedDepth) {
136 
137         Assert.assertSame("Node has an incorrect owning tree", tree, node.getTree());
138         Assert.assertEquals("Node has an incorrect depth property", node.depth(), expectedDepth);
139 
140         if (node.getCut() == null) {
141             final String msg = "Node without cut cannot have children";
142 
143             Assert.assertNull(msg, node.getMinus());
144             Assert.assertNull(msg, node.getPlus());
145         } else {
146             final String msg = "Node with cut must have children";
147 
148             Assert.assertNotNull(msg, node.getMinus());
149             Assert.assertNotNull(msg, node.getPlus());
150 
151             assertTreeStructureRecursive(tree, node.getPlus(), expectedDepth + 1);
152             assertTreeStructureRecursive(tree, node.getMinus(), expectedDepth + 1);
153         }
154     }
155 }