1 /* 2 * Copyright 2005 Google Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.google.common.geometry; 17 18 19 public strictfp class S1IntervalTest extends GeometryTestCase { 20 testIntervalOps(S1Interval x, S1Interval y, String expectedRelation, S1Interval expectedUnion, S1Interval expectedIntersection)21 private void testIntervalOps(S1Interval x, S1Interval y, String expectedRelation, 22 S1Interval expectedUnion, S1Interval expectedIntersection) { 23 // Test all of the interval operations on the given pair of intervals. 24 // "expected_relation" is a sequence of "T" and "F" characters corresponding 25 // to the expected results of Contains(), InteriorContains(), Intersects(), 26 // and InteriorIntersects() respectively. 27 28 assertEquals(x.contains(y), expectedRelation.charAt(0) == 'T'); 29 assertEquals(x.interiorContains(y), expectedRelation.charAt(1) == 'T'); 30 assertEquals(x.intersects(y), expectedRelation.charAt(2) == 'T'); 31 assertEquals(x.interiorIntersects(y), expectedRelation.charAt(3) == 'T'); 32 33 // bounds() returns a const reference to a member variable, so we need to 34 // make a copy when invoking it on a temporary object. 35 assertEquals(expectedUnion, x.union(y)); 36 assertEquals(expectedIntersection, x.intersection(y)); 37 38 assertEquals(x.contains(y), x.union(y) == x); 39 assertEquals(x.intersects(y), !x.intersection(y).isEmpty()); 40 41 if (y.lo() == y.hi()) { 42 S1Interval r = x.addPoint(y.lo()); 43 assertEquals(expectedUnion, r); 44 } 45 } 46 testBasic()47 public void testBasic() { 48 // "Quadrants" are numbered as follows: 49 // quad1 == [0, Pi/2] 50 // quad2 == [Pi/2, Pi] 51 // quad3 == [-Pi, -Pi/2] 52 // quad4 == [-Pi/2, 0] 53 54 // Constructors and accessors. 55 S1Interval quad12 = new S1Interval(0, -S2.M_PI); 56 assertEquals(quad12.lo(), 0.0); 57 assertEquals(quad12.hi(), S2.M_PI); 58 S1Interval quad34 = new S1Interval(-S2.M_PI, 0); 59 assertEquals(quad34.lo(), S2.M_PI); 60 assertEquals(quad34.hi(), 0.0); 61 S1Interval pi = new S1Interval(S2.M_PI, S2.M_PI); 62 assertEquals(pi.lo(), S2.M_PI); 63 assertEquals(pi.hi(), S2.M_PI); 64 S1Interval mipi = new S1Interval(-S2.M_PI, -S2.M_PI); 65 assertEquals(mipi.lo(), S2.M_PI); 66 assertEquals(mipi.hi(), S2.M_PI); 67 S1Interval quad23 = new S1Interval(S2.M_PI_2, -S2.M_PI_2); // inverted 68 assertEquals(quad23.lo(), S2.M_PI_2); 69 assertEquals(quad23.hi(), -S2.M_PI_2); 70 S1Interval quad1 = new S1Interval(0, S2.M_PI_2); 71 72 // is_valid(), is_empty(), is_inverted() 73 S1Interval zero = new S1Interval(0, 0); 74 assertTrue(zero.isValid() && !zero.isEmpty() && !zero.isFull()); 75 S1Interval empty = S1Interval.empty(); 76 assertTrue(empty.isValid() && empty.isEmpty() && !empty.isFull()); 77 assertTrue(empty.isInverted()); 78 S1Interval full = S1Interval.full(); 79 assertTrue(full.isValid() && !full.isEmpty() && full.isFull()); 80 assertTrue(!quad12.isEmpty() && !quad12.isFull() && !quad12.isInverted()); 81 assertTrue(!quad23.isEmpty() && !quad23.isFull() && quad23.isInverted()); 82 assertTrue(pi.isValid() && !pi.isEmpty() && !pi.isInverted()); 83 assertTrue(mipi.isValid() && !mipi.isEmpty() && !mipi.isInverted()); 84 85 // GetCenter(), GetLength() 86 assertEquals(quad12.getCenter(), S2.M_PI_2); 87 assertEquals(quad12.getLength(), S2.M_PI); 88 assertDoubleNear(new S1Interval(3.1, 2.9).getCenter(), 3.0 - S2.M_PI); 89 assertDoubleNear(new S1Interval(-2.9, -3.1).getCenter(), S2.M_PI - 3.0); 90 assertDoubleNear(new S1Interval(2.1, -2.1).getCenter(), S2.M_PI); 91 assertEquals(pi.getCenter(), S2.M_PI); 92 assertEquals(pi.getLength(), 0.0); 93 assertEquals(mipi.getCenter(), S2.M_PI); 94 assertEquals(mipi.getLength(), 0.0); 95 assertEquals(Math.abs(quad23.getCenter()), S2.M_PI); 96 assertEquals(Math.abs(quad23.getLength()), S2.M_PI); 97 S1Interval quad123 = new S1Interval(0, -S2.M_PI_2); 98 assertDoubleNear(quad123.getCenter(), 0.75 * S2.M_PI); 99 assertDoubleNear(quad123.getLength(), 1.5 * S2.M_PI); 100 assertTrue(empty.getLength() < 0); 101 assertEquals(full.getLength(), 2 * S2.M_PI); 102 103 // Complement() 104 assertTrue(empty.complement().isFull()); 105 assertTrue(full.complement().isEmpty()); 106 assertTrue(pi.complement().isFull()); 107 assertTrue(mipi.complement().isFull()); 108 assertTrue(zero.complement().isFull()); 109 assertTrue(quad12.complement().approxEquals(quad34)); 110 assertTrue(quad34.complement().approxEquals(quad12)); 111 S1Interval quad4 = new S1Interval(-S2.M_PI_2, 0); 112 assertTrue(quad123.complement().approxEquals(quad4)); 113 S1Interval quad234 = new S1Interval(S2.M_PI_2, 0); 114 115 // Contains(double), InteriorContains(double) 116 assertTrue(!empty.contains(0) && !empty.contains(S2.M_PI) && !empty.contains(-S2.M_PI)); 117 assertTrue(!empty.interiorContains(S2.M_PI) && !empty.interiorContains(-S2.M_PI)); 118 assertTrue(full.contains(0) && full.contains(S2.M_PI) && full.contains(-S2.M_PI)); 119 assertTrue(full.interiorContains(S2.M_PI) && full.interiorContains(-S2.M_PI)); 120 assertTrue(quad12.contains(0) && quad12.contains(S2.M_PI) && quad12.contains(-S2.M_PI)); 121 assertTrue(quad12.interiorContains(S2.M_PI_2) && !quad12.interiorContains(0)); 122 assertTrue(!quad12.interiorContains(S2.M_PI) && !quad12.interiorContains(-S2.M_PI)); 123 assertTrue(quad23.contains(S2.M_PI_2) && quad23.contains(-S2.M_PI_2)); 124 assertTrue(quad23.contains(S2.M_PI) && quad23.contains(-S2.M_PI)); 125 assertTrue(!quad23.contains(0)); 126 assertTrue(!quad23.interiorContains(S2.M_PI_2) && !quad23.interiorContains(-S2.M_PI_2)); 127 assertTrue(quad23.interiorContains(S2.M_PI) && quad23.interiorContains(-S2.M_PI)); 128 assertTrue(!quad23.interiorContains(0)); 129 assertTrue(pi.contains(S2.M_PI) && pi.contains(-S2.M_PI) && !pi.contains(0)); 130 assertTrue(!pi.interiorContains(S2.M_PI) && !pi.interiorContains(-S2.M_PI)); 131 assertTrue(mipi.contains(S2.M_PI) && mipi.contains(-S2.M_PI) && !mipi.contains(0)); 132 assertTrue(!mipi.interiorContains(S2.M_PI) && !mipi.interiorContains(-S2.M_PI)); 133 assertTrue(zero.contains(0) && !zero.interiorContains(0)); 134 135 // Contains(S1Interval), InteriorContains(S1Interval), 136 // Intersects(), InteriorIntersects(), Union(), Intersection() 137 S1Interval quad2 = new S1Interval(S2.M_PI_2, -S2.M_PI); 138 S1Interval quad3 = new S1Interval(S2.M_PI, -S2.M_PI_2); 139 S1Interval pi2 = new S1Interval(S2.M_PI_2, S2.M_PI_2); 140 S1Interval mipi2 = new S1Interval(-S2.M_PI_2, -S2.M_PI_2); 141 142 testIntervalOps(empty, empty, "TTFF", empty, empty); 143 testIntervalOps(empty, full, "FFFF", full, empty); 144 testIntervalOps(empty, zero, "FFFF", zero, empty); 145 testIntervalOps(empty, pi, "FFFF", pi, empty); 146 testIntervalOps(empty, mipi, "FFFF", mipi, empty); 147 148 testIntervalOps(full, empty, "TTFF", full, empty); 149 testIntervalOps(full, full, "TTTT", full, full); 150 testIntervalOps(full, zero, "TTTT", full, zero); 151 testIntervalOps(full, pi, "TTTT", full, pi); 152 testIntervalOps(full, mipi, "TTTT", full, mipi); 153 testIntervalOps(full, quad12, "TTTT", full, quad12); 154 testIntervalOps(full, quad23, "TTTT", full, quad23); 155 156 testIntervalOps(zero, empty, "TTFF", zero, empty); 157 testIntervalOps(zero, full, "FFTF", full, zero); 158 testIntervalOps(zero, zero, "TFTF", zero, zero); 159 testIntervalOps(zero, pi, "FFFF", new S1Interval(0, S2.M_PI), empty); 160 testIntervalOps(zero, pi2, "FFFF", quad1, empty); 161 testIntervalOps(zero, mipi, "FFFF", quad12, empty); 162 testIntervalOps(zero, mipi2, "FFFF", quad4, empty); 163 testIntervalOps(zero, quad12, "FFTF", quad12, zero); 164 testIntervalOps(zero, quad23, "FFFF", quad123, empty); 165 166 testIntervalOps(pi2, empty, "TTFF", pi2, empty); 167 testIntervalOps(pi2, full, "FFTF", full, pi2); 168 testIntervalOps(pi2, zero, "FFFF", quad1, empty); 169 testIntervalOps(pi2, pi, "FFFF", new S1Interval(S2.M_PI_2, S2.M_PI), empty); 170 testIntervalOps(pi2, pi2, "TFTF", pi2, pi2); 171 testIntervalOps(pi2, mipi, "FFFF", quad2, empty); 172 testIntervalOps(pi2, mipi2, "FFFF", quad23, empty); 173 testIntervalOps(pi2, quad12, "FFTF", quad12, pi2); 174 testIntervalOps(pi2, quad23, "FFTF", quad23, pi2); 175 176 testIntervalOps(pi, empty, "TTFF", pi, empty); 177 testIntervalOps(pi, full, "FFTF", full, pi); 178 testIntervalOps(pi, zero, "FFFF", new S1Interval(S2.M_PI, 0), empty); 179 testIntervalOps(pi, pi, "TFTF", pi, pi); 180 testIntervalOps(pi, pi2, "FFFF", new S1Interval(S2.M_PI_2, S2.M_PI), empty); 181 testIntervalOps(pi, mipi, "TFTF", pi, pi); 182 testIntervalOps(pi, mipi2, "FFFF", quad3, empty); 183 testIntervalOps(pi, quad12, "FFTF", new S1Interval(0, S2.M_PI), pi); 184 testIntervalOps(pi, quad23, "FFTF", quad23, pi); 185 186 testIntervalOps(mipi, empty, "TTFF", mipi, empty); 187 testIntervalOps(mipi, full, "FFTF", full, mipi); 188 testIntervalOps(mipi, zero, "FFFF", quad34, empty); 189 testIntervalOps(mipi, pi, "TFTF", mipi, mipi); 190 testIntervalOps(mipi, pi2, "FFFF", quad2, empty); 191 testIntervalOps(mipi, mipi, "TFTF", mipi, mipi); 192 testIntervalOps(mipi, mipi2, "FFFF", new S1Interval(-S2.M_PI, -S2.M_PI_2), empty); 193 testIntervalOps(mipi, quad12, "FFTF", quad12, mipi); 194 testIntervalOps(mipi, quad23, "FFTF", quad23, mipi); 195 196 testIntervalOps(quad12, empty, "TTFF", quad12, empty); 197 testIntervalOps(quad12, full, "FFTT", full, quad12); 198 testIntervalOps(quad12, zero, "TFTF", quad12, zero); 199 testIntervalOps(quad12, pi, "TFTF", quad12, pi); 200 testIntervalOps(quad12, mipi, "TFTF", quad12, mipi); 201 testIntervalOps(quad12, quad12, "TFTT", quad12, quad12); 202 testIntervalOps(quad12, quad23, "FFTT", quad123, quad2); 203 testIntervalOps(quad12, quad34, "FFTF", full, quad12); 204 205 testIntervalOps(quad23, empty, "TTFF", quad23, empty); 206 testIntervalOps(quad23, full, "FFTT", full, quad23); 207 testIntervalOps(quad23, zero, "FFFF", quad234, empty); 208 testIntervalOps(quad23, pi, "TTTT", quad23, pi); 209 testIntervalOps(quad23, mipi, "TTTT", quad23, mipi); 210 testIntervalOps(quad23, quad12, "FFTT", quad123, quad2); 211 testIntervalOps(quad23, quad23, "TFTT", quad23, quad23); 212 testIntervalOps(quad23, quad34, "FFTT", quad234, new S1Interval(-S2.M_PI, -S2.M_PI_2)); 213 214 testIntervalOps(quad1, quad23, "FFTF", quad123, new S1Interval(S2.M_PI_2, S2.M_PI_2)); 215 testIntervalOps(quad2, quad3, "FFTF", quad23, mipi); 216 testIntervalOps(quad3, quad2, "FFTF", quad23, pi); 217 testIntervalOps(quad2, pi, "TFTF", quad2, pi); 218 testIntervalOps(quad2, mipi, "TFTF", quad2, mipi); 219 testIntervalOps(quad3, pi, "TFTF", quad3, pi); 220 testIntervalOps(quad3, mipi, "TFTF", quad3, mipi); 221 222 S1Interval mid12 = new S1Interval(S2.M_PI_2 - 0.02, S2.M_PI_2 + 0.01); 223 S1Interval mid23 = new S1Interval(S2.M_PI - 0.01, -S2.M_PI + 0.02); 224 S1Interval mid34 = new S1Interval(-S2.M_PI_2 - 0.02, -S2.M_PI_2 + 0.01); 225 S1Interval mid41 = new S1Interval(-0.01, 0.02); 226 227 S1Interval quad2hi = new S1Interval(mid23.lo(), quad12.hi()); 228 S1Interval quad1lo = new S1Interval(quad12.lo(), mid41.hi()); 229 S1Interval quad12eps = new S1Interval(quad12.lo(), mid23.hi()); 230 S1Interval quadeps12 = new S1Interval(mid41.lo(), quad12.hi()); 231 S1Interval quad123eps = new S1Interval(quad12.lo(), mid34.hi()); 232 testIntervalOps(quad12, mid12, "TTTT", quad12, mid12); 233 testIntervalOps(mid12, quad12, "FFTT", quad12, mid12); 234 testIntervalOps(quad12, mid23, "FFTT", quad12eps, quad2hi); 235 testIntervalOps(mid23, quad12, "FFTT", quad12eps, quad2hi); 236 testIntervalOps(quad12, mid34, "FFFF", quad123eps, empty); 237 testIntervalOps(mid34, quad12, "FFFF", quad123eps, empty); 238 testIntervalOps(quad12, mid41, "FFTT", quadeps12, quad1lo); 239 testIntervalOps(mid41, quad12, "FFTT", quadeps12, quad1lo); 240 241 S1Interval quad2lo = new S1Interval(quad23.lo(), mid12.hi()); 242 S1Interval quad3hi = new S1Interval(mid34.lo(), quad23.hi()); 243 S1Interval quadeps23 = new S1Interval(mid12.lo(), quad23.hi()); 244 S1Interval quad23eps = new S1Interval(quad23.lo(), mid34.hi()); 245 S1Interval quadeps123 = new S1Interval(mid41.lo(), quad23.hi()); 246 testIntervalOps(quad23, mid12, "FFTT", quadeps23, quad2lo); 247 testIntervalOps(mid12, quad23, "FFTT", quadeps23, quad2lo); 248 testIntervalOps(quad23, mid23, "TTTT", quad23, mid23); 249 testIntervalOps(mid23, quad23, "FFTT", quad23, mid23); 250 testIntervalOps(quad23, mid34, "FFTT", quad23eps, quad3hi); 251 testIntervalOps(mid34, quad23, "FFTT", quad23eps, quad3hi); 252 testIntervalOps(quad23, mid41, "FFFF", quadeps123, empty); 253 testIntervalOps(mid41, quad23, "FFFF", quadeps123, empty); 254 255 // AddPoint() 256 S1Interval r = S1Interval.empty(); 257 S1Interval res; 258 res = r.addPoint(0); 259 assertEquals(res, zero); 260 261 res = r.addPoint(S2.M_PI); 262 assertEquals(res, pi); 263 264 res = r.addPoint(-S2.M_PI); 265 assertEquals(res, mipi); 266 267 res = r.addPoint(S2.M_PI); 268 res = res.addPoint(-S2.M_PI); 269 assertEquals(res, pi); 270 271 res = res.addPoint(-S2.M_PI); 272 res.addPoint(S2.M_PI); 273 assertEquals(res, mipi); 274 275 res = r.addPoint(mid12.lo()); 276 res = res.addPoint(mid12.hi()); 277 assertEquals(res, mid12); 278 279 res = r.addPoint(mid23.lo()); 280 res = res.addPoint(mid23.hi()); 281 assertEquals(res, mid23); 282 283 res = quad1.addPoint(-0.9 * S2.M_PI); 284 res = res.addPoint(-S2.M_PI_2); 285 assertEquals(res, quad123); 286 287 r = S1Interval.full(); 288 res = r.addPoint(0); 289 assertTrue(res.isFull()); 290 291 res = r.addPoint(S2.M_PI); 292 assertTrue(res.isFull()); 293 294 res = r.addPoint(-S2.M_PI); 295 assertTrue(res.isFull()); 296 297 // FromPointPair() 298 assertEquals(S1Interval.fromPointPair(-S2.M_PI, S2.M_PI), pi); 299 assertEquals(S1Interval.fromPointPair(S2.M_PI, -S2.M_PI), pi); 300 assertEquals(S1Interval.fromPointPair(mid34.hi(), mid34.lo()), mid34); 301 assertEquals(S1Interval.fromPointPair(mid23.lo(), mid23.hi()), mid23); 302 303 // Expanded() 304 assertEquals(empty.expanded(1), empty); 305 assertEquals(full.expanded(1), full); 306 assertEquals(zero.expanded(1), new S1Interval(-1, 1)); 307 assertEquals(mipi.expanded(0.01), new S1Interval(S2.M_PI - 0.01, -S2.M_PI + 0.01)); 308 assertEquals(pi.expanded(27), full); 309 assertEquals(pi.expanded(S2.M_PI_2), quad23); 310 assertEquals(pi2.expanded(S2.M_PI_2), quad12); 311 assertEquals(mipi2.expanded(S2.M_PI_2), quad34); 312 313 // ApproxEquals() 314 assertTrue(empty.approxEquals(empty)); 315 assertTrue(zero.approxEquals(empty) && empty.approxEquals(zero)); 316 assertTrue(pi.approxEquals(empty) && empty.approxEquals(pi)); 317 assertTrue(mipi.approxEquals(empty) && empty.approxEquals(mipi)); 318 assertTrue(pi.approxEquals(mipi) && mipi.approxEquals(pi)); 319 assertTrue(pi.union(mipi).approxEquals(pi)); 320 assertTrue(mipi.union(pi).approxEquals(pi)); 321 assertTrue(pi.union(mid12).union(zero).approxEquals(quad12)); 322 assertTrue(quad2.intersection(quad3).approxEquals(pi)); 323 assertTrue(quad3.intersection(quad2).approxEquals(pi)); 324 } 325 } 326