DiskGenerator implements SupportBallGenerator<Euclidean2D, Vector2D> { public EnclosingBall<Euclidean2D, Vector2D> ballOnSupport(final List<Vector2D> support) { if (support.size() < 1) { return new EnclosingBall<Euclidean2D, Vector2D>(Vector2D.ZERO, Double.NEGATIVE_INFINITY); } else { final Vector2D vA = support.get(0); if (support.size() < 2) { return new EnclosingBall<Euclidean2D, Vector2D>(vA, 0, vA); } else { final Vector2D vB = support.get(1); if (support.size() < 3) { return new EnclosingBall<Euclidean2D, Vector2D>(new Vector2D(0.5, vA, 0.5, vB), 0.5 * vA.distance(vB), vA, vB); } else { final Vector2D vC = support.get(2); final BigFraction[] c2 = new BigFraction[] { new BigFraction(vA.getX()), new BigFraction(vB.getX()), new BigFraction(vC.getX()) }; final BigFraction[] c3 = new BigFraction[] { new BigFraction(vA.getY()), new BigFraction(vB.getY()), new BigFraction(vC.getY()) }; final BigFraction[] c1 = new BigFraction[] { c2[0].multiply(c2[0]).add(c3[0].multiply(c3[0])), c2[1].multiply(c2[1]).add(c3[1].multiply(c3[1])), c2[2].multiply(c2[2]).add(c3[2].multiply(c3[2])) }; final BigFraction twoM11 = minor(c2, c3).multiply(2); final BigFraction m12 = minor(c1, c3); final BigFraction m13 = minor(c1, c2); final BigFraction centerX = m12.divide(twoM11); final BigFraction centerY = m13.divide(twoM11).negate(); final BigFraction dx = c2[0].subtract(centerX); final BigFraction dy = c3[0].subtract(centerY); final BigFraction r2 = dx.multiply(dx).add(dy.multiply(dy)); return new EnclosingBall<Euclidean2D, Vector2D>(new Vector2D(centerX.doubleValue(), centerY.doubleValue()), FastMath.sqrt(r2.doubleValue()), vA, vB, vC); } } } }  EnclosingBall<Euclidean2D, Vector2D> ballOnSupport(final List<Vector2D> support);  }
@Test public void testSupport0Point() { List<Vector2D> support = Arrays.asList(new Vector2D[0]); EnclosingBall<Euclidean2D, Vector2D> disk = new DiskGenerator().ballOnSupport(support); Assert.assertTrue(disk.getRadius() < 0); Assert.assertEquals(0, disk.getSupportSize()); Assert.assertEquals(0, disk.getSupport().length); }
@Test public void testSupport1Point() { List<Vector2D> support = Arrays.asList(new Vector2D(1, 2)); EnclosingBall<Euclidean2D, Vector2D> disk = new DiskGenerator().ballOnSupport(support); Assert.assertEquals(0.0, disk.getRadius(), 1.0e-10); Assert.assertTrue(disk.contains(support.get(0))); Assert.assertTrue(disk.contains(support.get(0), 0.5)); Assert.assertFalse(disk.contains(new Vector2D(support.get(0).getX() + 0.1, support.get(0).getY() - 0.1), 0.001)); Assert.assertTrue(disk.contains(new Vector2D(support.get(0).getX() + 0.1, support.get(0).getY() - 0.1), 0.5)); Assert.assertEquals(0, support.get(0).distance(disk.getCenter()), 1.0e-10); Assert.assertEquals(1, disk.getSupportSize()); Assert.assertTrue(support.get(0) == disk.getSupport()[0]); }
@Test public void testSupport2Points() { List<Vector2D> support = Arrays.asList(new Vector2D(1, 0), new Vector2D(3, 0)); EnclosingBall<Euclidean2D, Vector2D> disk = new DiskGenerator().ballOnSupport(support); Assert.assertEquals(1.0, disk.getRadius(), 1.0e-10); int i = 0; for (Vector2D v : support) { Assert.assertTrue(disk.contains(v)); Assert.assertEquals(1.0, v.distance(disk.getCenter()), 1.0e-10); Assert.assertTrue(v == disk.getSupport()[i++]); } Assert.assertTrue(disk.contains(new Vector2D(2, 0.9))); Assert.assertFalse(disk.contains(Vector2D.ZERO)); Assert.assertEquals(0.0, new Vector2D(2, 0).distance(disk.getCenter()), 1.0e-10); Assert.assertEquals(2, disk.getSupportSize()); }
@Test public void testSupport3Points() { List<Vector2D> support = Arrays.asList(new Vector2D(1, 0), new Vector2D(3, 0), new Vector2D(2, 2)); EnclosingBall<Euclidean2D, Vector2D> disk = new DiskGenerator().ballOnSupport(support); Assert.assertEquals(5.0 / 4.0, disk.getRadius(), 1.0e-10); int i = 0; for (Vector2D v : support) { Assert.assertTrue(disk.contains(v)); Assert.assertEquals(5.0 / 4.0, v.distance(disk.getCenter()), 1.0e-10); Assert.assertTrue(v == disk.getSupport()[i++]); } Assert.assertTrue(disk.contains(new Vector2D(2, 0.9))); Assert.assertFalse(disk.contains(new Vector2D(0.9, 0))); Assert.assertFalse(disk.contains(new Vector2D(3.1, 0))); Assert.assertTrue(disk.contains(new Vector2D(2.0, -0.499))); Assert.assertFalse(disk.contains(new Vector2D(2.0, -0.501))); Assert.assertEquals(0.0, new Vector2D(2.0, 3.0 / 4.0).distance(disk.getCenter()), 1.0e-10); Assert.assertEquals(3, disk.getSupportSize()); }
@Test public void testRandom() { final RandomGenerator random = new Well1024a(0x12faa818373ffe90l); final UnitSphereRandomVectorGenerator sr = new UnitSphereRandomVectorGenerator(2, random); for (int i = 0; i < 500; ++i) { double d = 25 * random.nextDouble(); double refRadius = 10 * random.nextDouble(); Vector2D refCenter = new Vector2D(d, new Vector2D(sr.nextVector())); List<Vector2D> support = new ArrayList<Vector2D>(); for (int j = 0; j < 3; ++j) { support.add(new Vector2D(1.0, refCenter, refRadius, new Vector2D(sr.nextVector()))); } EnclosingBall<Euclidean2D, Vector2D> disk = new DiskGenerator().ballOnSupport(support); Assert.assertEquals(0.0, refCenter.distance(disk.getCenter()), 3e-9 * refRadius); Assert.assertEquals(refRadius, disk.getRadius(), 7e-10 * refRadius); } }