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.euclidean.twod;
    18
    19  import java.util.ArrayList;
    20  import java.util.Arrays;
    21  import java.util.Collections;
    22  import java.util.function.BiFunction;
    23  import java.util.function.ToDoubleFunction;
    24  import java.util.regex.Pattern;
    25
    26  import org.apache.commons.geometry.core.GeometryTestUtils;
    27  import org.apache.commons.geometry.core.precision.DoublePrecisionContext;
    28  import org.apache.commons.geometry.core.precision.EpsilonDoublePrecisionContext;
    29  import org.apache.commons.geometry.euclidean.EuclideanTestUtils;
    30  import org.apache.commons.geometry.euclidean.twod.shape.Parallelogram;
    31  import org.junit.Assert;
    32  import org.junit.Test;
    33
    34  public class Bounds2DTest {
    35
    36      private static final double TEST_EPS = 1e-10;
    37
    38      private static final DoublePrecisionContext TEST_PRECISION =
    39              new EpsilonDoublePrecisionContext(TEST_EPS);
    40
    41      private static final String NO_POINTS_MESSAGE = "Cannot construct bounds: no points given";
    42
    43      private static final Pattern INVALID_BOUNDS_PATTERN =
    44              Pattern.compile("^Invalid bounds: min= \\([^\\)]+\\), max= \\([^\\)]+\\)");
    45
    46      @Test
    47      public void testFrom_varargs_singlePoint() {
    48          // arrange
    49          final Vector2D p1 = Vector2D.of(-1, 2);
    50
    51          // act
    52          final Bounds2D b = Bounds2D.from(p1);
    53
    54          // assert
    55          EuclideanTestUtils.assertCoordinatesEqual(p1, b.getMin(), TEST_EPS);
    56          EuclideanTestUtils.assertCoordinatesEqual(p1, b.getMax(), TEST_EPS);
    57          EuclideanTestUtils.assertCoordinatesEqual(Vector2D.ZERO, b.getDiagonal(), TEST_EPS);
    58          EuclideanTestUtils.assertCoordinatesEqual(p1, b.getCentroid(), TEST_EPS);
    59      }
    60
    61      @Test
    62      public void testFrom_varargs_multiplePoints() {
    63          // arrange
    64          final Vector2D p1 = Vector2D.of(1, 6);
    65          final Vector2D p2 = Vector2D.of(0, 5);
    66          final Vector2D p3 = Vector2D.of(3, 6);
    67
    68          // act
    69          final Bounds2D b = Bounds2D.from(p1, p2, p3);
    70
    71          // assert
    72          EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(0, 5), b.getMin(), TEST_EPS);
    73          EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(3, 6), b.getMax(), TEST_EPS);
    74          EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(3, 1), b.getDiagonal(), TEST_EPS);
    75          EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(1.5, 5.5), b.getCentroid(), TEST_EPS);
    76      }
    77
    78      @Test
    79      public void testFrom_iterable_singlePoint() {
    80          // arrange
    81          final Vector2D p1 = Vector2D.of(-1, 2);
    82
    83          // act
    84          final Bounds2D b = Bounds2D.from(Collections.singletonList(p1));
    85
    86          // assert
    87          EuclideanTestUtils.assertCoordinatesEqual(p1, b.getMin(), TEST_EPS);
    88          EuclideanTestUtils.assertCoordinatesEqual(p1, b.getMax(), TEST_EPS);
    89          EuclideanTestUtils.assertCoordinatesEqual(Vector2D.ZERO, b.getDiagonal(), TEST_EPS);
    90          EuclideanTestUtils.assertCoordinatesEqual(p1, b.getCentroid(), TEST_EPS);
    91      }
    92
    93      @Test
    94      public void testFrom_iterable_multiplePoints() {
    95          // arrange
    96          final Vector2D p1 = Vector2D.of(1, 6);
    97          final Vector2D p2 = Vector2D.of(2, 5);
    98          final Vector2D p3 = Vector2D.of(3, 4);
    99
    100         // act
    101         final Bounds2D b = Bounds2D.from(Arrays.asList(p1, p2, p3));
    102
    103         // assert
    104         EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(1, 4), b.getMin(), TEST_EPS);
    105         EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(3, 6), b.getMax(), TEST_EPS);
    106         EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(2, 2), b.getDiagonal(), TEST_EPS);
    107         EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(2, 5), b.getCentroid(), TEST_EPS);
    108     }
    109
    110     @Test
    111     public void testFrom_iterable_noPoints() {
    112         // act/assert
    113         GeometryTestUtils.assertThrows(() -> {
    114             Bounds2D.from(new ArrayList<>());
    115         }, IllegalStateException.class, NO_POINTS_MESSAGE);
    116     }
    117
    118     @Test
    119     public void testFrom_invalidBounds() {
    120         // arrange
    121         final Vector2D good = Vector2D.of(1, 1);
    122
    123         final Vector2D nan = Vector2D.of(Double.NaN, 1);
    124         final Vector2D posInf = Vector2D.of(1, Double.POSITIVE_INFINITY);
    125         final Vector2D negInf = Vector2D.of(1, Double.NEGATIVE_INFINITY);
    126
    127         // act/assert
    128         GeometryTestUtils.assertThrows(() -> {
    129             Bounds2D.from(Vector2D.NaN);
    130         }, IllegalStateException.class, INVALID_BOUNDS_PATTERN);
    131
    132         GeometryTestUtils.assertThrows(() -> {
    133             Bounds2D.from(Vector2D.POSITIVE_INFINITY);
    134         }, IllegalStateException.class, INVALID_BOUNDS_PATTERN);
    135
    136         GeometryTestUtils.assertThrows(() -> {
    137             Bounds2D.from(Vector2D.NEGATIVE_INFINITY);
    138         }, IllegalStateException.class, INVALID_BOUNDS_PATTERN);
    139
    140         GeometryTestUtils.assertThrows(() -> {
    141             Bounds2D.from(good, nan);
    142         }, IllegalStateException.class, INVALID_BOUNDS_PATTERN);
    143
    144         GeometryTestUtils.assertThrows(() -> {
    145             Bounds2D.from(posInf, good);
    146         }, IllegalStateException.class, INVALID_BOUNDS_PATTERN);
    147
    148         GeometryTestUtils.assertThrows(() -> {
    149             Bounds2D.from(good, negInf, good);
    150         }, IllegalStateException.class, INVALID_BOUNDS_PATTERN);
    151     }
    152
    153     @Test
    154     public void testHasSize() {
    155         // arrange
    156         final DoublePrecisionContext low = new EpsilonDoublePrecisionContext(1e-2);
    157         final DoublePrecisionContext high = new EpsilonDoublePrecisionContext(1e-10);
    158
    159         final Vector2D p1 = Vector2D.ZERO;
    160
    161         final Vector2D p2 = Vector2D.of(1e-5, 1);
    162         final Vector2D p3 = Vector2D.of(1, 1e-5);
    163
    164         final Vector2D p4 = Vector2D.of(1, 1);
    165
    166         // act/assert
    167         Assert.assertFalse(Bounds2D.from(p1).hasSize(high));
    168         Assert.assertFalse(Bounds2D.from(p1).hasSize(low));
    169
    170         Assert.assertTrue(Bounds2D.from(p1, p2).hasSize(high));
    171         Assert.assertFalse(Bounds2D.from(p1, p2).hasSize(low));
    172
    173         Assert.assertTrue(Bounds2D.from(p1, p3).hasSize(high));
    174         Assert.assertFalse(Bounds2D.from(p1, p3).hasSize(low));
    175
    176         Assert.assertTrue(Bounds2D.from(p1, p4).hasSize(high));
    177         Assert.assertTrue(Bounds2D.from(p1, p4).hasSize(low));
    178     }
    179
    180     @Test
    181     public void testContains_strict() {
    182         // arrange
    183         final Bounds2D b = Bounds2D.from(
    184                 Vector2D.of(0, 4),
    185                 Vector2D.of(2, 6));
    186
    187         // act/assert
    188         assertContainsStrict(b, true,
    189                 b.getCentroid(),
    190                 Vector2D.of(0, 4), Vector2D.of(2, 6),
    191                 Vector2D.of(1, 5),
    192                 Vector2D.of(0, 5), Vector2D.of(2, 5),
    193                 Vector2D.of(1, 4), Vector2D.of(1, 6));
    194
    195         assertContainsStrict(b, false,
    196                 Vector2D.ZERO,
    197                 Vector2D.of(-1, 5), Vector2D.of(3, 5),
    198                 Vector2D.of(1, 3), Vector2D.of(1, 7),
    199                 Vector2D.of(-1e-15, 4), Vector2D.of(2, 6 + 1e-15));
    200     }
    201
    202     @Test
    203     public void testContains_precision() {
    204         // arrange
    205         final Bounds2D b = Bounds2D.from(
    206                 Vector2D.of(0, 4),
    207                 Vector2D.of(2, 6));
    208
    209         // act/assert
    210         assertContainsWithPrecision(b, true,
    211                 b.getCentroid(),
    212                 Vector2D.of(1, 5), Vector2D.of(0, 4), Vector2D.of(2, 6),
    213                 Vector2D.of(0, 5), Vector2D.of(2, 5),
    214                 Vector2D.of(1, 4), Vector2D.of(1, 6),
    215                 Vector2D.of(-1e-15, 4), Vector2D.of(2, 6 + 1e-15));
    216
    217         assertContainsWithPrecision(b, false,
    218                 Vector2D.ZERO,
    219                 Vector2D.of(-1, 5), Vector2D.of(3, 5),
    220                 Vector2D.of(1, 3), Vector2D.of(1, 7));
    221     }
    222
    223     @Test
    224     public void testIntersects() {
    225         // arrange
    226         final Bounds2D b = Bounds2D.from(Vector2D.ZERO, Vector2D.of(1, 1));
    227
    228         // act/assert
    229         checkIntersects(b, Vector2D::getX, (v, x) -> Vector2D.of(x, v.getY()));
    230         checkIntersects(b, Vector2D::getY, (v, y) -> Vector2D.of(v.getX(), y));
    231     }
    232
    233     private void checkIntersects(final Bounds2D b, final ToDoubleFunction<Vector2D> getter,
    234                                  final BiFunction<Vector2D, Double, Vector2D> setter) {
    235
    236         final Vector2D min = b.getMin();
    237         final Vector2D max = b.getMax();
    238
    239         final double minValue = getter.applyAsDouble(min);
    240         final double maxValue = getter.applyAsDouble(max);
    241         final double midValue = (0.5 * (maxValue - minValue)) + minValue;
    242
    243         // check all possible interval relationships
    244
    245         // start below minValue
    246         Assert.assertFalse(b.intersects(Bounds2D.from(
    247                 setter.apply(min, minValue - 2), setter.apply(max, minValue - 1))));
    248
    249         Assert.assertTrue(b.intersects(Bounds2D.from(
    250                 setter.apply(min, minValue - 2), setter.apply(max, minValue))));
    251         Assert.assertTrue(b.intersects(Bounds2D.from(
    252                 setter.apply(min, minValue - 2), setter.apply(max, midValue))));
    253         Assert.assertTrue(b.intersects(Bounds2D.from(
    254                 setter.apply(min, minValue - 2), setter.apply(max, maxValue))));
    255         Assert.assertTrue(b.intersects(Bounds2D.from(
    256                 setter.apply(min, minValue - 2), setter.apply(max, maxValue + 1))));
    257
    258         // start on minValue
    259         Assert.assertTrue(b.intersects(Bounds2D.from(
    260                 setter.apply(min, minValue), setter.apply(max, minValue))));
    261         Assert.assertTrue(b.intersects(Bounds2D.from(
    262                 setter.apply(min, minValue), setter.apply(max, midValue))));
    263         Assert.assertTrue(b.intersects(Bounds2D.from(
    264                 setter.apply(min, minValue), setter.apply(max, maxValue))));
    265         Assert.assertTrue(b.intersects(Bounds2D.from(
    266                 setter.apply(min, minValue), setter.apply(max, maxValue + 1))));
    267
    268         // start on midValue
    269         Assert.assertTrue(b.intersects(Bounds2D.from(
    270                 setter.apply(min, midValue), setter.apply(max, midValue))));
    271         Assert.assertTrue(b.intersects(Bounds2D.from(
    272                 setter.apply(min, midValue), setter.apply(max, maxValue))));
    273         Assert.assertTrue(b.intersects(Bounds2D.from(
    274                 setter.apply(min, midValue), setter.apply(max, maxValue + 1))));
    275
    276         // start on maxValue
    277         Assert.assertTrue(b.intersects(Bounds2D.from(
    278                 setter.apply(min, maxValue), setter.apply(max, maxValue))));
    279         Assert.assertTrue(b.intersects(Bounds2D.from(
    280                 setter.apply(min, maxValue), setter.apply(max, maxValue + 1))));
    281
    282         // start above maxValue
    283         Assert.assertFalse(b.intersects(Bounds2D.from(
    284                 setter.apply(min, maxValue + 1), setter.apply(max, maxValue + 2))));
    285     }
    286
    287     @Test
    288     public void testIntersection() {
    289         // -- arrange
    290         final Bounds2D b = Bounds2D.from(Vector2D.ZERO, Vector2D.of(1, 1));
    291
    292         // -- act/assert
    293
    294         // move along x-axis
    295         Assert.assertNull(b.intersection(Bounds2D.from(Vector2D.of(-2, 0), Vector2D.of(-1, 1))));
    296         checkIntersection(b, Vector2D.of(-1, 0), Vector2D.of(0, 1),
    297                 Vector2D.of(0, 0), Vector2D.of(0, 1));
    298         checkIntersection(b, Vector2D.of(-1, 0), Vector2D.of(0.5, 1),
    299                 Vector2D.of(0, 0), Vector2D.of(0.5, 1));
    300         checkIntersection(b, Vector2D.of(-1, 0), Vector2D.of(1, 1),
    301                 Vector2D.of(0, 0), Vector2D.of(1, 1));
    302         checkIntersection(b, Vector2D.of(-1, 0), Vector2D.of(2, 1),
    303                 Vector2D.of(0, 0), Vector2D.of(1, 1));
    304         checkIntersection(b, Vector2D.of(0, 0), Vector2D.of(2, 1),
    305                 Vector2D.of(0, 0), Vector2D.of(1, 1));
    306         checkIntersection(b, Vector2D.of(0.5, 0), Vector2D.of(2, 1),
    307                 Vector2D.of(0.5, 0), Vector2D.of(1, 1));
    308         checkIntersection(b, Vector2D.of(1, 0), Vector2D.of(2, 1),
    309                 Vector2D.of(1, 0), Vector2D.of(1, 1));
    310         Assert.assertNull(b.intersection(Bounds2D.from(Vector2D.of(2, 0), Vector2D.of(3, 1))));
    311
    312         // move along y-axis
    313         Assert.assertNull(b.intersection(Bounds2D.from(Vector2D.of(0, -2), Vector2D.of(1, -1))));
    314         checkIntersection(b, Vector2D.of(0, -1), Vector2D.of(1, 0),
    315                 Vector2D.of(0, 0), Vector2D.of(1, 0));
    316         checkIntersection(b, Vector2D.of(0, -1), Vector2D.of(1, 0.5),
    317                 Vector2D.of(0, 0), Vector2D.of(1, 0.5));
    318         checkIntersection(b, Vector2D.of(0, -1), Vector2D.of(1, 1),
    319                 Vector2D.of(0, 0), Vector2D.of(1, 1));
    320         checkIntersection(b, Vector2D.of(0, -1), Vector2D.of(1, 2),
    321                 Vector2D.of(0, 0), Vector2D.of(1, 1));
    322         checkIntersection(b, Vector2D.of(0, 0), Vector2D.of(1, 2),
    323                 Vector2D.of(0, 0), Vector2D.of(1, 1));
    324         checkIntersection(b, Vector2D.of(0, 0.5), Vector2D.of(1, 2),
    325                 Vector2D.of(0, 0.5), Vector2D.of(1, 1));
    326         checkIntersection(b, Vector2D.of(0, 1), Vector2D.of(1, 2),
    327                 Vector2D.of(0, 1), Vector2D.of(1, 1));
    328         Assert.assertNull(b.intersection(Bounds2D.from(Vector2D.of(0, 2), Vector2D.of(1, 3))));
    329     }
    330
    331     private void checkIntersection(final Bounds2D b, final Vector2D a1, final Vector2D a2, final Vector2D r1, final Vector2D r2) {
    332         final Bounds2D a = Bounds2D.from(a1, a2);
    333         final Bounds2D result = b.intersection(a);
    334
    335         checkBounds(result, r1, r2);
    336     }
    337
    338     @Test
    339     public void toRegion() {
    340         // arrange
    341         final Bounds2D b = Bounds2D.from(
    342                 Vector2D.of(0, 4),
    343                 Vector2D.of(2, 6));
    344
    345         // act
    346         final Parallelogram p = b.toRegion(TEST_PRECISION);
    347
    348         // assert
    349         Assert.assertEquals(4, p.getSize(), TEST_EPS);
    350         EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(1, 5), p.getCentroid(), TEST_EPS);
    351     }
    352
    353     @Test
    354     public void toRegion_boundingBoxTooSmall() {
    355         // act/assert
    356         GeometryTestUtils.assertThrows(() -> {
    357             Bounds2D.from(Vector2D.ZERO, Vector2D.of(1e-12, 1e-12))
    358                 .toRegion(TEST_PRECISION);
    359         }, IllegalArgumentException.class);
    360     }
    361
    362     @Test
    363     public void testEq() {
    364         // arrange
    365         final DoublePrecisionContext low = new EpsilonDoublePrecisionContext(1e-2);
    366         final DoublePrecisionContext high = new EpsilonDoublePrecisionContext(1e-10);
    367
    368         final Bounds2D b1 = Bounds2D.from(Vector2D.of(1, 1), Vector2D.of(2, 2));
    369
    370         final Bounds2D b2 = Bounds2D.from(Vector2D.of(1.1, 1), Vector2D.of(2, 2));
    371         final Bounds2D b3 = Bounds2D.from(Vector2D.of(1, 1), Vector2D.of(1.9, 2));
    372
    373         final Bounds2D b4 = Bounds2D.from(Vector2D.of(1.001, 1.001), Vector2D.of(2.001, 2.001));
    374
    375         // act/assert
    376         Assert.assertTrue(b1.eq(b1, low));
    377
    378         Assert.assertFalse(b1.eq(b2, low));
    379         Assert.assertFalse(b1.eq(b3, low));
    380
    381         Assert.assertTrue(b1.eq(b4, low));
    382         Assert.assertTrue(b4.eq(b1, low));
    383
    384         Assert.assertFalse(b1.eq(b4, high));
    385         Assert.assertFalse(b4.eq(b1, high));
    386     }
    387
    388     @Test
    389     public void testHashCode() {
    390         // arrange
    391         final Bounds2D b1 = Bounds2D.from(Vector2D.of(1, 1), Vector2D.of(2, 2));
    392
    393         final Bounds2D b2 = Bounds2D.from(Vector2D.of(-2, 1), Vector2D.of(2, 2));
    394         final Bounds2D b3 = Bounds2D.from(Vector2D.of(1, 1), Vector2D.of(3, 2));
    395         final Bounds2D b4 = Bounds2D.from(Vector2D.of(1 + 1e-15, 1), Vector2D.of(2, 2));
    396         final Bounds2D b5 = Bounds2D.from(Vector2D.of(1, 1), Vector2D.of(2 + 1e-15, 2));
    397
    398         final Bounds2D b6 = Bounds2D.from(Vector2D.of(1, 1), Vector2D.of(2, 2));
    399
    400         // act
    401         final int hash = b1.hashCode();
    402
    403         // assert
    404         Assert.assertEquals(hash, b1.hashCode());
    405
    406         Assert.assertNotEquals(hash, b2.hashCode());
    407         Assert.assertNotEquals(hash, b3.hashCode());
    408         Assert.assertNotEquals(hash, b4.hashCode());
    409         Assert.assertNotEquals(hash, b5.hashCode());
    410
    411         Assert.assertEquals(hash, b6.hashCode());
    412     }
    413
    414     @Test
    415     public void testEquals() {
    416         // arrange
    417         final Bounds2D b1 = Bounds2D.from(Vector2D.of(1, 1), Vector2D.of(2, 2));
    418
    419         final Bounds2D b2 = Bounds2D.from(Vector2D.of(-1, 1), Vector2D.of(2, 2));
    420         final Bounds2D b3 = Bounds2D.from(Vector2D.of(1, 1), Vector2D.of(3, 2));
    421         final Bounds2D b4 = Bounds2D.from(Vector2D.of(1 + 1e-15, 1), Vector2D.of(2, 2));
    422         final Bounds2D b5 = Bounds2D.from(Vector2D.of(1, 1), Vector2D.of(2 + 1e-15, 2));
    423
    424         final Bounds2D b6 = Bounds2D.from(Vector2D.of(1, 1), Vector2D.of(2, 2));
    425
    426         // act/assert
    427         Assert.assertEquals(b1, b1);
    428
    429         Assert.assertFalse(b1.equals(null));
    430         Assert.assertFalse(b1.equals(new Object()));
    431
    432         Assert.assertNotEquals(b1, b2);
    433         Assert.assertNotEquals(b1, b3);
    434         Assert.assertNotEquals(b1, b4);
    435         Assert.assertNotEquals(b1, b5);
    436
    437         Assert.assertEquals(b1, b6);
    438     }
    439
    440     @Test
    441     public void testToString() {
    442         // arrange
    443         final Bounds2D b = Bounds2D.from(Vector2D.of(1, 1), Vector2D.of(2, 2));
    444
    445         // act
    446         final String str = b.toString();
    447
    448         // assert
    449         GeometryTestUtils.assertContains("Bounds2D[min= (1", str);
    450         GeometryTestUtils.assertContains(", max= (2", str);
    451     }
    452
    453     @Test
    454     public void testBuilder_addMethods() {
    455         // arrange
    456         final Vector2D p1 = Vector2D.of(1, 10);
    457         final Vector2D p2 = Vector2D.of(2, 9);
    458         final Vector2D p3 = Vector2D.of(3, 8);
    459         final Vector2D p4 = Vector2D.of(4, 7);
    460         final Vector2D p5 = Vector2D.of(5, 6);
    461
    462         // act
    463         final Bounds2D b = Bounds2D.builder()
    464                 .add(p1)
    465                 .addAll(Arrays.asList(p2, p3))
    466                 .add(Bounds2D.from(p4, p5))
    467                 .build();
    468
    469         // assert
    470         EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(1, 6), b.getMin(), TEST_EPS);
    471         EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(5, 10), b.getMax(), TEST_EPS);
    472         EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(3, 8), b.getCentroid(), TEST_EPS);
    473     }
    474
    475     @Test
    476     public void testBuilder_hasBounds() {
    477         // act/assert
    478         Assert.assertFalse(Bounds2D.builder().hasBounds());
    479
    480         Assert.assertFalse(Bounds2D.builder().add(Vector2D.of(Double.NaN, 1)).hasBounds());
    481         Assert.assertFalse(Bounds2D.builder().add(Vector2D.of(1, Double.NaN)).hasBounds());
    482
    483         Assert.assertFalse(Bounds2D.builder().add(Vector2D.of(Double.POSITIVE_INFINITY, 1)).hasBounds());
    484         Assert.assertFalse(Bounds2D.builder().add(Vector2D.of(1, Double.POSITIVE_INFINITY)).hasBounds());
    485
    486         Assert.assertFalse(Bounds2D.builder().add(Vector2D.of(Double.NEGATIVE_INFINITY, 1)).hasBounds());
    487         Assert.assertFalse(Bounds2D.builder().add(Vector2D.of(1, Double.NEGATIVE_INFINITY)).hasBounds());
    488
    489         Assert.assertTrue(Bounds2D.builder().add(Vector2D.ZERO).hasBounds());
    490     }
    491
    492     private static void checkBounds(final Bounds2D b, final Vector2D min, final Vector2D max) {
    493         EuclideanTestUtils.assertCoordinatesEqual(min, b.getMin(), TEST_EPS);
    494         EuclideanTestUtils.assertCoordinatesEqual(max, b.getMax(), TEST_EPS);
    495     }
    496
    497     private static void assertContainsStrict(final Bounds2D bounds, final boolean contains, final Vector2D... pts) {
    498         for (final Vector2D pt : pts) {
    499             Assert.assertEquals("Unexpected location for point " + pt, contains, bounds.contains(pt));
    500         }
    501     }
    502
    503     private static void assertContainsWithPrecision(final Bounds2D bounds, final boolean contains, final Vector2D... pts) {
    504         for (final Vector2D pt : pts) {
    505             Assert.assertEquals("Unexpected location for point " + pt, contains, bounds.contains(pt, TEST_PRECISION));
    506         }
    507     }
    508 }