From 7bb2e62b202810915b55c7800a1d2f24476ce5a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Galland?= Date: Mon, 6 Jun 2016 23:31:23 +0200 Subject: [PATCH] [math] Finializing getClosestPoint for Shape2afp. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit see #24 Signed-off-by: Stéphane Galland --- .../AbstractOrientedRectangle2afpTest.java | 310 +- .../d2/afp/AbstractParallelogram2afpTest.java | 3922 +++++++++-------- .../math/geometry/d2/d/orientedrectangle.ggb | Bin 9940 -> 11020 bytes .../afc/math/geometry/d2/d/parallelogram.ggb | Bin 11297 -> 14640 bytes 4 files changed, 2188 insertions(+), 2044 deletions(-) diff --git a/core/math/src/test/java/org/arakhne/afc/math/geometry/d2/afp/AbstractOrientedRectangle2afpTest.java b/core/math/src/test/java/org/arakhne/afc/math/geometry/d2/afp/AbstractOrientedRectangle2afpTest.java index 13e7a87ba..66b7a4840 100644 --- a/core/math/src/test/java/org/arakhne/afc/math/geometry/d2/afp/AbstractOrientedRectangle2afpTest.java +++ b/core/math/src/test/java/org/arakhne/afc/math/geometry/d2/afp/AbstractOrientedRectangle2afpTest.java @@ -1550,124 +1550,196 @@ public void isCCW() { -0.9863939238321437, 0.1643989873053573, 1, 2).isCCW()); } - @Test - @Ignore - public void getDistanceSquaredRectangle2afp() { - throw new RuntimeException(); - } - - @Test - @Ignore - public void getDistanceSquaredCircle2afp() { - throw new RuntimeException(); - } - - @Test - @Ignore - public void getDistanceSquaredTriangle2afp() { - throw new RuntimeException(); - } - - @Test - @Ignore - public void getDistanceSquaredEllipse2afp() { - throw new RuntimeException(); - } - - @Test - @Ignore - public void getDistanceSquaredSegment2afp() { - throw new RuntimeException(); - } - - @Test - @Ignore - public void getDistanceSquaredPath2afp() { - throw new RuntimeException(); - } - - @Test - @Ignore - public void getDistanceSquaredOrientedRectangle2afp() { - throw new RuntimeException(); - } - - @Test - @Ignore - public void getDistanceSquaredMultiShape2afp() { - throw new RuntimeException(); - } - - @Test - @Ignore - public void getDistanceSquaredParallelogram2afp() { - throw new RuntimeException(); - } - - @Test - @Ignore - public void getDistanceSquaredRoundRectangle2afp() { - throw new RuntimeException(); - } - - @Test - @Ignore - public void getClosestPointToEllipse2afp() { - throw new RuntimeException(); - } - - @Test - @Ignore - public void getClosestPointToCircle2afp() { - throw new RuntimeException(); - } - - @Test - @Ignore - public void getClosestPointToRectangle2afp() { - throw new RuntimeException(); - } - - @Test - @Ignore - public void getClosestPointToSegment2afp() { - throw new RuntimeException(); - } - - @Test - @Ignore - public void getClosestPointToTriangle2afp() { - throw new RuntimeException(); - } - - @Test - @Ignore - public void getClosestPointToPath2afp() { - throw new RuntimeException(); - } - - @Test - @Ignore - public void getClosestPointToOrientedRectangle2afp() { - throw new RuntimeException(); - } - - @Test - @Ignore - public void getClosestPointToParallelogram2afp() { - throw new RuntimeException(); - } - - @Test - @Ignore - public void getClosestPointToRoundRectangle2afp() { - throw new RuntimeException(); - } - - @Test - @Ignore - public void getClosestPointToMultiShape2afp() { - throw new RuntimeException(); - } + @Test + public void getClosestPointToCircle2afp() { + assertFpPointEquals(-3.01377, -1.02754, this.shape.getClosestPointTo(createCircle(-5, -5, 1))); + assertFpPointEquals(-12.33574, 3.63344, this.shape.getClosestPointTo(createCircle(-30, 8, 1))); + assertClosestPointInBothShapes(this.shape, createCircle(20, 5, 1)); + assertClosestPointInBothShapes(this.shape, createCircle(12, 10, 1)); + } + + @Test + public void getDistanceSquaredCircle2afp() { + assertEpsilonEquals(11.84282, this.shape.getDistanceSquared(createCircle(-5, -5, 1))); + assertEpsilonEquals(295.70086, this.shape.getDistanceSquared(createCircle(-30, 8, 1))); + assertEpsilonEquals(0, this.shape.getDistanceSquared(createCircle(20, 5, 1))); + assertEpsilonEquals(0, this.shape.getDistanceSquared(createCircle(12, 10, 1))); + } + + @Test + public void getClosestPointToSegment2afp() { + assertFpPointEquals(-1.81377, -1.62754, this.shape.getClosestPointTo(createSegment(-5, -5, -3, -4))); + assertFpPointEquals(-12.33574, 3.63344, this.shape.getClosestPointTo(createSegment(-30, 8, -28, 9))); + assertClosestPointInBothShapes(this.shape, createSegment(19, 5, 21, 6)); + assertClosestPointInBothShapes(this.shape, createSegment(12, 10, 14, 11)); + } + + @Test + public void getDistanceSquaredSegment2afp() { + assertEpsilonEquals(7.03568, this.shape.getDistanceSquared(createSegment(-5, -5, -3, -4))); + assertEpsilonEquals(274.16887, this.shape.getDistanceSquared(createSegment(-30, 8, -28, 9))); + assertEpsilonEquals(0, this.shape.getDistanceSquared(createSegment(19, 5, 21, 6))); + assertEpsilonEquals(0, this.shape.getDistanceSquared(createSegment(12, 10, 14, 11))); + } + + protected Triangle2afp createTestTriangle(double dx, double dy) { + return createTriangle(dx, dy, dx + 6, dy + 3, dx - 1, dy + 2.5); + } + + @Test + public void getClosestPointToTriangle2afp() { + assertFpPointEquals(-0.21377, -2.42754, this.shape.getClosestPointTo(createTestTriangle(-7, -7))); + assertFpPointEquals(-12.33574, 3.63344, this.shape.getClosestPointTo(createTestTriangle(-60, 0))); + assertClosestPointInBothShapes(this.shape, createTestTriangle(19, 5)); + assertClosestPointInBothShapes(this.shape, createTestTriangle(5, 5)); + } + + @Test + public void getDistanceSquaredTriangle2afp() { + assertEpsilonEquals(3.09077, this.shape.getDistanceSquared(createTestTriangle(-7, -7))); + assertEpsilonEquals(1736.31148, this.shape.getDistanceSquared(createTestTriangle(-60, 0))); + assertEpsilonEquals(0, this.shape.getDistanceSquared(createTestTriangle(19, 5))); + assertEpsilonEquals(0, this.shape.getDistanceSquared(createTestTriangle(5, 5))); + } + + @Test + public void getClosestPointToRectangle2afp() { + assertFpPointEquals(-1.81377, -1.62754, this.shape.getClosestPointTo(createRectangle(-5, -5, 2, 1))); + assertFpPointEquals(-12.33574, 3.63344, this.shape.getClosestPointTo(createRectangle(-30, 5, 2, 1))); + assertClosestPointInBothShapes(this.shape, createRectangle(17, 2, 2, 1)); + assertClosestPointInBothShapes(this.shape, createRectangle(5, 5, 2, 1)); + } + + @Test + public void getDistanceSquaredRectangle2afp() { + assertEpsilonEquals(7.03568, this.shape.getDistanceSquared(createRectangle(-5, -5, 2, 1))); + assertEpsilonEquals(247.2364, this.shape.getDistanceSquared(createRectangle(-30, 5, 2, 1))); + assertEpsilonEquals(0, this.shape.getDistanceSquared(createRectangle(17, 2, 2, 1))); + assertEpsilonEquals(0, this.shape.getDistanceSquared(createRectangle(5, 5, 2, 1))); + } + + @Test + public void getClosestPointToEllipse2afp() { + assertFpPointEquals(-1.98951, -1.53968, this.shape.getClosestPointTo(createEllipse(-5, -5, 2, 1))); + assertFpPointEquals(-12.33574, 3.63344, this.shape.getClosestPointTo(createEllipse(-30, 5, 2, 1))); + assertClosestPointInBothShapes(this.shape, createEllipse(17, 2, 2, 1)); + assertClosestPointInBothShapes(this.shape, createEllipse(5, 5, 2, 1)); + } + + @Test + public void getDistanceSquaredEllipse2afp() { + assertEpsilonEquals(8.49406, this.shape.getDistanceSquared(createEllipse(-5, -5, 2, 1))); + assertEpsilonEquals(248.79828, this.shape.getDistanceSquared(createEllipse(-30, 5, 2, 1))); + assertEpsilonEquals(0, this.shape.getDistanceSquared(createEllipse(17, 2, 2, 1))); + assertEpsilonEquals(0, this.shape.getDistanceSquared(createEllipse(5, 5, 2, 1))); + } + + @Test + public void getClosestPointToRoundRectangle2afp() { + assertFpPointEquals(-1.84892, -1.60997, this.shape.getClosestPointTo(createRoundRectangle(-5, -5, 2, 1, .2, .1))); + assertFpPointEquals(-12.33574, 3.63344, this.shape.getClosestPointTo(createRoundRectangle(-30, 5, 2, 1, .2, .1))); + assertClosestPointInBothShapes(this.shape, createRoundRectangle(17, 2, 2, 1, .2, .1)); + assertClosestPointInBothShapes(this.shape, createRoundRectangle(5, 5, 2, 1, .2, .1)); + } + + @Test + public void getDistanceSquaredRoundRectangle2afp() { + assertEpsilonEquals(7.31638, this.shape.getDistanceSquared(createRoundRectangle(-5, -5, 2, 1, .2, .1))); + assertEpsilonEquals(247.51287, this.shape.getDistanceSquared(createRoundRectangle(-30, 5, 2, 1, .2, .1))); + assertEpsilonEquals(0, this.shape.getDistanceSquared(createRoundRectangle(17, 2, 2, 1, .2, .1))); + assertEpsilonEquals(0, this.shape.getDistanceSquared(createRoundRectangle(5, 5, 2, 1, .2, .1))); + } + + protected MultiShape2afp createTestMultiShape(double dx, double dy) { + Circle2afp circle = createCircle(dx - 3, dy + 2, 2); + Triangle2afp triangle = createTestTriangle(dx +1, dy - 1); + MultiShape2afp multishape = createMultiShape(); + multishape.add(circle); + multishape.add(triangle); + return multishape; + } + + @Test + public void getClosestPointToMultiShape2afp() { + assertFpPointEquals(0.98623, -3.02754, this.shape.getClosestPointTo(createTestMultiShape(-7, -7))); + assertFpPointEquals(-12.33574, 3.63344, this.shape.getClosestPointTo(createTestMultiShape(-30, 0))); + assertClosestPointInBothShapes(this.shape, createTestMultiShape(15, 2)); + assertClosestPointInBothShapes(this.shape, createTestMultiShape(5, 5)); + } + + @Test + public void getDistanceSquaredMultiShape2afp() { + assertEpsilonEquals(4.86323, this.shape.getDistanceSquared(createTestMultiShape(-7, -7))); + assertEpsilonEquals(116.39449, this.shape.getDistanceSquared(createTestMultiShape(-30, 0))); + assertEpsilonEquals(0, this.shape.getDistanceSquared(createTestMultiShape(15, 2))); + assertEpsilonEquals(0, this.shape.getDistanceSquared(createTestMultiShape(5, 5))); + } + + protected Path2afp createNonEmptyPath(double x, double y) { + Path2afp path = createPath(); + path.moveTo(x, y); + path.lineTo(x + 1, y + .5); + path.lineTo(x, y + 1); + return path; + } + + @Test + public void getClosestPointToPath2afp() { + assertFpPointEquals(-2.41377, -1.32754, this.shape.getClosestPointTo(createNonEmptyPath(-5, -5))); + assertFpPointEquals(-12.33574, 3.63344, this.shape.getClosestPointTo(createNonEmptyPath(-30, 5))); + assertClosestPointInBothShapes(this.shape, createNonEmptyPath(15, 2)); + assertClosestPointInBothShapes(this.shape, createNonEmptyPath(5, 5)); + } + + @Test + public void getDistanceSquaredPath2afp() { + assertEpsilonEquals(12.58059, this.shape.getDistanceSquared(createNonEmptyPath(-5, -5))); + assertEpsilonEquals(281.18147, this.shape.getDistanceSquared(createNonEmptyPath(-30, 5))); + assertEpsilonEquals(0, this.shape.getDistanceSquared(createNonEmptyPath(15, 2))); + assertEpsilonEquals(0, this.shape.getDistanceSquared(createNonEmptyPath(5, 5))); + } + + protected Parallelogram2afp createTestParallelogram(double dx, double dy) { + Vector2D r = createVector(4, 1).toUnitVector(); + Vector2D s = createVector(-1, -1).toUnitVector(); + return createParallelogram(dx, dy, r.getX(), r.getY(), 2, s.getX(), s.getY(), 1); + } + + @Test + public void getClosestPointToParallelogram2afp() { + assertFpPointEquals(-1.37273, -1.84807, this.shape.getClosestPointTo(createTestParallelogram(-5, -5))); + assertFpPointEquals(-12.33574, 3.63344, this.shape.getClosestPointTo(createTestParallelogram(-30, 5))); + assertClosestPointInBothShapes(this.shape, createTestParallelogram(18, 2)); + assertClosestPointInBothShapes(this.shape, createTestParallelogram(5, 5)); + } + + @Test + public void getDistanceSquaredParallelogram2afp() { + assertEpsilonEquals(4.80081, this.shape.getDistanceSquared(createTestParallelogram(-5, -5))); + assertEpsilonEquals(232.05334, this.shape.getDistanceSquared(createTestParallelogram(-30, 5))); + assertEpsilonEquals(0, this.shape.getDistanceSquared(createTestParallelogram(18, 2))); + assertEpsilonEquals(0, this.shape.getDistanceSquared(createTestParallelogram(5, 5))); + } + + protected OrientedRectangle2afp createTestOrientedRectangle(double dx, double dy) { + Vector2D r = createVector(4, 1).toUnitVector(); + return createOrientedRectangle(dx, dy, r.getX(), r.getY(), 2, 1); + } + + @Test + public void getClosestPointToOrientedRectangle2afp() { + assertFpPointEquals(-2.23766, -1.4156, this.shape.getClosestPointTo(createTestOrientedRectangle(-5, -5))); + assertFpPointEquals(-12.33574, 3.63344, this.shape.getClosestPointTo(createTestOrientedRectangle(-30, 5))); + assertClosestPointInBothShapes(this.shape, createTestOrientedRectangle(18, 2)); + assertClosestPointInBothShapes(this.shape, createTestOrientedRectangle(5, 5)); + } + + @Test + public void getDistanceSquaredOrientedRectangle2afp() { + assertEpsilonEquals(5.66678, this.shape.getDistanceSquared(createTestOrientedRectangle(-5, -5))); + assertEpsilonEquals(240.45186, this.shape.getDistanceSquared(createTestOrientedRectangle(-30, 5))); + assertEpsilonEquals(0, this.shape.getDistanceSquared(createTestOrientedRectangle(18, 2))); + assertEpsilonEquals(0, this.shape.getDistanceSquared(createTestOrientedRectangle(5, 5))); + } } \ No newline at end of file diff --git a/core/math/src/test/java/org/arakhne/afc/math/geometry/d2/afp/AbstractParallelogram2afpTest.java b/core/math/src/test/java/org/arakhne/afc/math/geometry/d2/afp/AbstractParallelogram2afpTest.java index 8b623af4e..9899e0c2d 100644 --- a/core/math/src/test/java/org/arakhne/afc/math/geometry/d2/afp/AbstractParallelogram2afpTest.java +++ b/core/math/src/test/java/org/arakhne/afc/math/geometry/d2/afp/AbstractParallelogram2afpTest.java @@ -44,1929 +44,2001 @@ public abstract class AbstractParallelogram2afpTest, B extends Rectangle2afp> extends AbstractShape2afpTest { - protected final double cx = 6; - protected final double cy = 9; - protected final double ux = 2.425356250363330e-01; - protected final double uy = 9.701425001453320e-01; - protected final double e1 = 9.219544457292887; - protected final double vx = -7.071067811865475e-01; - protected final double vy = 7.071067811865475e-01; - protected final double e2 = 1.264911064067352e+01; - - // Points' names are in the ggb diagram - protected final double pEx = 12.7082; - protected final double pEy = -8.88854; - protected final double pFx = 17.18034; - protected final double pFy = 9; - protected final double pGx = -0.7082; - protected final double pGy = 26.88854; - protected final double pHx = -5.18034; - protected final double pHy = 9; - - @Override - protected final T createShape() { - return (T) createParallelogram(cx, cy, ux, uy, e1, vx, vy, e2); - } - - @Test - public void staticComputeOrthogonalAxis() { - double obrux = 0.8944271909999159; - double obruy = -0.4472135954999579; - double obre1 = 13.99999; - double obrvx = 0.4472135954999579; - double obrvy = 0.8944271909999159; - double obre2 = 12.99999; - List points = Arrays.asList( - createPoint(11.7082, -0.94427), createPoint(16.18034, 8), - createPoint(-1.7082, 16.94427), createPoint(-6.18034, 8)); - Vector2D R, S; - R = createVector(Double.NaN, Double.NaN); - S = createVector(Double.NaN, Double.NaN); - Parallelogram2afp.computeOrthogonalAxes(points, R, S); - assertEpsilonEquals(obrux, R.getX()); - assertEpsilonEquals(obruy, R.getY()); - assertEpsilonEquals(obrvx, S.getX()); - assertEpsilonEquals(obrvy, S.getY()); - } - - @Test - public void staticProjectVectorOnParallelogramRAxis() { - assertEpsilonEquals(-e1, Parallelogram2afp.projectVectorOnParallelogramRAxis(ux, uy, vx, vy, pEx - cx, pEy - cy)); - assertEpsilonEquals(e1, Parallelogram2afp.projectVectorOnParallelogramRAxis(ux, uy, vx, vy, pFx - cx, pFy - cy)); - assertEpsilonEquals(e1, Parallelogram2afp.projectVectorOnParallelogramRAxis(ux, uy, vx, vy, pGx - cx, pGy - cy)); - assertEpsilonEquals(-e1, Parallelogram2afp.projectVectorOnParallelogramRAxis(ux, uy, vx, vy, pHx - cx, pHy - cy)); - assertEpsilonEquals(-12.36932, Parallelogram2afp.projectVectorOnParallelogramRAxis(ux, uy, vx, vy, -cx, -cy)); - } - - @Test - public void staticProjectVectorOnParallelogramSAxis() { - assertEpsilonEquals(-e2, Parallelogram2afp.projectVectorOnParallelogramSAxis(ux, uy, vx, vy, pEx - cx, pEy - cy)); - assertEpsilonEquals(-e2, Parallelogram2afp.projectVectorOnParallelogramSAxis(ux, uy, vx, vy, pFx - cx, pFy - cy)); - assertEpsilonEquals(e2, Parallelogram2afp.projectVectorOnParallelogramSAxis(ux, uy, vx, vy, pGx - cx, pGy - cy)); - assertEpsilonEquals(e2, Parallelogram2afp.projectVectorOnParallelogramSAxis(ux, uy, vx, vy, pHx - cx, pHy - cy)); - assertEpsilonEquals(4.24264, Parallelogram2afp.projectVectorOnParallelogramSAxis(ux, uy, vx, vy, -cx, -cy)); - } - - @Test - public void staticComputeCenterExtents() { - List points = Arrays.asList( - createPoint(pEx, pEy), createPoint(pGx, pGy), - createPoint(pFx, pFy), createPoint(pEx, pEy)); - Vector2D R, S; - Point2D center; - Tuple2D extents; - R = createVector(ux, uy); - S = createVector(vx, vy); - center = createPoint(Double.NaN, Double.NaN); - extents = createVector(Double.NaN, Double.NaN); - Parallelogram2afp.computeCenterExtents(points, R, S, center, extents); - assertEpsilonEquals(cx, center.getX()); - assertEpsilonEquals(cy, center.getY()); - assertEpsilonEquals(e1, extents.getX()); - assertEpsilonEquals(e2, extents.getY()); - } - - @Test - public void staticComputeClosestPoint() { - Point2D closest; - - closest = createPoint(Double.NaN, Double.NaN); - Parallelogram2afp.computeClosestPoint( - -20, 9, - cx, cy, ux, uy, e1, vx, vy, e2, - closest); - assertFpPointEquals(pHx, pHy, closest); - - closest = createPoint(Double.NaN, Double.NaN); - Parallelogram2afp.computeClosestPoint( - 0, 0, - cx, cy, ux, uy, e1, vx, vy, e2, - closest); - assertFpPointEquals(1.90983, 1.90983, closest); - - closest = createPoint(Double.NaN, Double.NaN); - Parallelogram2afp.computeClosestPoint( - 5, -10, - cx, cy, ux, uy, e1, vx, vy, e2, - closest); - assertFpPointEquals(9.40983, -5.59017, closest); - - closest = createPoint(Double.NaN, Double.NaN); - Parallelogram2afp.computeClosestPoint( - 14, -20, - cx, cy, ux, uy, e1, vx, vy, e2, - closest); - assertFpPointEquals(pEx, pEy, closest); - - closest = createPoint(Double.NaN, Double.NaN); - Parallelogram2afp.computeClosestPoint( - -6, 15, - cx, cy, ux, uy, e1, vx, vy, e2, - closest); - assertFpPointEquals(-3.81679, 14.4542, closest); - - closest = createPoint(Double.NaN, Double.NaN); - Parallelogram2afp.computeClosestPoint( - 0, 10, - cx, cy, ux, uy, e1, vx, vy, e2, - closest); - assertFpPointEquals(0, 10, closest); - - closest = createPoint(Double.NaN, Double.NaN); - Parallelogram2afp.computeClosestPoint( - 10, 0, - cx, cy, ux, uy, e1, vx, vy, e2, - closest); - assertFpPointEquals(10, 0, closest); - - closest = createPoint(Double.NaN, Double.NaN); - Parallelogram2afp.computeClosestPoint( - 15, -4, - cx, cy, ux, uy, e1, vx, vy, e2, - closest); - assertFpPointEquals(13.99326, -3.74832, closest); - - closest = createPoint(Double.NaN, Double.NaN); - Parallelogram2afp.computeClosestPoint( - -5, 25, - cx, cy, ux, uy, e1, vx, vy, e2, - closest); - assertFpPointEquals(-1.40503, 24.10126, closest); - - closest = createPoint(Double.NaN, Double.NaN); - Parallelogram2afp.computeClosestPoint( - 0, 20, - cx, cy, ux, uy, e1, vx, vy, e2, - closest); - assertFpPointEquals(0, 20, closest); - - closest = createPoint(Double.NaN, Double.NaN); - Parallelogram2afp.computeClosestPoint( - 10, 10, - cx, cy, ux, uy, e1, vx, vy, e2, - closest); - assertFpPointEquals(10, 10, closest); - - closest = createPoint(Double.NaN, Double.NaN); - Parallelogram2afp.computeClosestPoint( - 20, 0, - cx, cy, ux, uy, e1, vx, vy, e2, - closest); - assertFpPointEquals(15.22856, 1.19286, closest); - - closest = createPoint(Double.NaN, Double.NaN); - Parallelogram2afp.computeClosestPoint( - -3, 35, - cx, cy, ux, uy, e1, vx, vy, e2, - closest); - assertFpPointEquals(pGx, pGy, closest); - - closest = createPoint(Double.NaN, Double.NaN); - Parallelogram2afp.computeClosestPoint( - 5, 35, - cx, cy, ux, uy, e1, vx, vy, e2, - closest); - assertFpPointEquals(pGx, pGy, closest); - - closest = createPoint(Double.NaN, Double.NaN); - Parallelogram2afp.computeClosestPoint( - 20, 15, - cx, cy, ux, uy, e1, vx, vy, e2, - closest); - assertFpPointEquals(15.59017, 10.59017, closest); - - closest = createPoint(Double.NaN, Double.NaN); - Parallelogram2afp.computeClosestPoint( - 35, 10, - cx, cy, ux, uy, e1, vx, vy, e2, - closest); - assertFpPointEquals(pFx, pFy, closest); - - closest = createPoint(Double.NaN, Double.NaN); - Parallelogram2afp.computeClosestPoint( - -8, 29, - cx, cy, ux, uy, e1, vx, vy, e2, - closest); - assertFpPointEquals(pGx, pGy, closest); - - closest = createPoint(Double.NaN, Double.NaN); - Parallelogram2afp.computeClosestPoint(0, 0, - 4.7, 15, - 0.12403, 0.99228, - 18.02776, - -0.44721, 0.89443, - 20, - closest); - assertFpPointEquals(0.81573, 0.40786, closest); - - // In triangle.ggb - closest = createPoint(Double.NaN, Double.NaN); - Parallelogram2afp.computeClosestPoint(-5.2964, 3.19501, - -10, 7, - -0.9863939238321437, 0.1643989873053573, - 1, - 0.9998000599800071, 0.01999600119960014, - 2, - closest); - assertFpPointEquals(-7.01401, 6.87559, closest); - - // In triangle.ggb - closest = createPoint(Double.NaN, Double.NaN); - Parallelogram2afp.computeClosestPoint(-1, -2, - 0, -6, - -0.9863939238321437, 0.1643989873053573, - 1, - 0.9998000599800071, 0.01999600119960014, - 2, - closest); - assertFpPointEquals(-0.92331, -5.83434, closest); - - // In segment.ggb - closest = createPoint(Double.NaN, Double.NaN); - Parallelogram2afp.computeClosestPoint(0, 0, - -10, -3, - -.8944271909999159, .4472135954999579, - 2, - .5547001962252290, -.8320502943378436, - 1, - closest); - assertFpPointEquals(-7.65645, -4.72648, closest); - } - - @Test - public void staticComputeFarthestPoint() { - Point2D farthest; - - farthest = createPoint(Double.NaN, Double.NaN); - Parallelogram2afp.computeFarthestPoint( - -20, 9, - cx, cy, ux, uy, e1, vx, vy, e2, - farthest); - assertFpPointEquals(pEx, pEy, farthest); - - farthest = createPoint(Double.NaN, Double.NaN); - Parallelogram2afp.computeFarthestPoint( - 0, 0, - cx, cy, ux, uy, e1, vx, vy, e2, - farthest); - assertFpPointEquals(pGx, pGy, farthest); - - farthest = createPoint(Double.NaN, Double.NaN); - Parallelogram2afp.computeFarthestPoint( - 5, -10, - cx, cy, ux, uy, e1, vx, vy, e2, - farthest); - assertFpPointEquals(pGx, pGy, farthest); - - farthest = createPoint(Double.NaN, Double.NaN); - Parallelogram2afp.computeFarthestPoint( - 14, -20, - cx, cy, ux, uy, e1, vx, vy, e2, - farthest); - assertFpPointEquals(pGx, pGy, farthest); - - farthest = createPoint(Double.NaN, Double.NaN); - Parallelogram2afp.computeFarthestPoint( - -6, 15, - cx, cy, ux, uy, e1, vx, vy, e2, - farthest); - assertFpPointEquals(pEx, pEy, farthest); - - farthest = createPoint(Double.NaN, Double.NaN); - Parallelogram2afp.computeFarthestPoint( - 0, 10, - cx, cy, ux, uy, e1, vx, vy, e2, - farthest); - assertFpPointEquals(pEx, pEy, farthest); - - farthest = createPoint(Double.NaN, Double.NaN); - Parallelogram2afp.computeFarthestPoint( - 10, 0, - cx, cy, ux, uy, e1, vx, vy, e2, - farthest); - assertFpPointEquals(pGx, pGy, farthest); - - farthest = createPoint(Double.NaN, Double.NaN); - Parallelogram2afp.computeFarthestPoint( - 15, -4, - cx, cy, ux, uy, e1, vx, vy, e2, - farthest); - assertFpPointEquals(pGx, pGy, farthest); - - farthest = createPoint(Double.NaN, Double.NaN); - Parallelogram2afp.computeFarthestPoint( - -5, 25, - cx, cy, ux, uy, e1, vx, vy, e2, - farthest); - assertFpPointEquals(pEx, pEy, farthest); - - farthest = createPoint(Double.NaN, Double.NaN); - Parallelogram2afp.computeFarthestPoint( - 0, 20, - cx, cy, ux, uy, e1, vx, vy, e2, - farthest); - assertFpPointEquals(pEx, pEy, farthest); - - farthest = createPoint(Double.NaN, Double.NaN); - Parallelogram2afp.computeFarthestPoint( - 10, 10, - cx, cy, ux, uy, e1, vx, vy, e2, - farthest); - assertFpPointEquals(pGx, pGy, farthest); - - farthest = createPoint(Double.NaN, Double.NaN); - Parallelogram2afp.computeFarthestPoint( - 20, 0, - cx, cy, ux, uy, e1, vx, vy, e2, - farthest); - assertFpPointEquals(pGx, pGy, farthest); - - farthest = createPoint(Double.NaN, Double.NaN); - Parallelogram2afp.computeFarthestPoint( - -3, 35, - cx, cy, ux, uy, e1, vx, vy, e2, - farthest); - assertFpPointEquals(pEx, pEy, farthest); - - farthest = createPoint(Double.NaN, Double.NaN); - Parallelogram2afp.computeFarthestPoint( - 5, 35, - cx, cy, ux, uy, e1, vx, vy, e2, - farthest); - assertFpPointEquals(pEx, pEy, farthest); - - farthest = createPoint(Double.NaN, Double.NaN); - Parallelogram2afp.computeFarthestPoint( - 20, 15, - cx, cy, ux, uy, e1, vx, vy, e2, - farthest); - assertFpPointEquals(pHx, pHy, farthest); - - farthest = createPoint(Double.NaN, Double.NaN); - Parallelogram2afp.computeFarthestPoint( - 35, 10, - cx, cy, ux, uy, e1, vx, vy, e2, - farthest); - assertFpPointEquals(pHx, pHy, farthest); - - farthest = createPoint(Double.NaN, Double.NaN); - Parallelogram2afp.computeFarthestPoint( - -8, 29, - cx, cy, ux, uy, e1, vx, vy, e2, - farthest); - assertFpPointEquals(pEx, pEy, farthest); - - farthest = createPoint(Double.NaN, Double.NaN); - Parallelogram2afp.computeFarthestPoint(0, 0, - 4.7, 15, - 0.12403, 0.99228, - 18.02776, - -0.44721, 0.89443, - 20, - farthest); - assertFpPointEquals(-2.0082, 50.77719, farthest); - } - - @Test - public void staticContainsParallelogramPoint() { - assertFalse(Parallelogram2afp.containsParallelogramPoint(cx, cy, ux, uy, e1, vx, vy, e2, - 0, 0)); - assertFalse(Parallelogram2afp.containsParallelogramPoint(cx, cy, ux, uy, e1, vx, vy, e2, - -20, 0)); - assertTrue(Parallelogram2afp.containsParallelogramPoint(cx, cy, ux, uy, e1, vx, vy, e2, - 12, -4)); - assertTrue(Parallelogram2afp.containsParallelogramPoint(cx, cy, ux, uy, e1, vx, vy, e2, - 14, 0)); - assertFalse(Parallelogram2afp.containsParallelogramPoint(cx, cy, ux, uy, e1, vx, vy, e2, - 15, 0)); - assertFalse(Parallelogram2afp.containsParallelogramPoint(cx, cy, ux, uy, e1, vx, vy, e2, - 20, 8)); - assertTrue(Parallelogram2afp.containsParallelogramPoint(cx, cy, ux, uy, e1, vx, vy, e2, - 8, 16)); - assertFalse(Parallelogram2afp.containsParallelogramPoint(cx, cy, ux, uy, e1, vx, vy, e2, - -4, 20)); - assertFalse(Parallelogram2afp.containsParallelogramPoint(cx, cy, ux, uy, e1, vx, vy, e2, - -5, 12)); - - assertTrue(Parallelogram2afp.containsParallelogramPoint(cx, cy, ux, uy, e1, vx, vy, e2, - 0, 6)); - assertTrue(Parallelogram2afp.containsParallelogramPoint(cx, cy, ux, uy, e1, vx, vy, e2, - 0, 7)); - assertTrue(Parallelogram2afp.containsParallelogramPoint(cx, cy, ux, uy, e1, vx, vy, e2, - 0, 8)); - assertTrue(Parallelogram2afp.containsParallelogramPoint(cx, cy, ux, uy, e1, vx, vy, e2, - 0, 9)); - assertTrue(Parallelogram2afp.containsParallelogramPoint(cx, cy, ux, uy, e1, vx, vy, e2, - 0, 10)); - assertFalse(Parallelogram2afp.containsParallelogramPoint(cx, cy, ux, uy, e1, vx, vy, e2, - 0, 27)); - - assertTrue(Parallelogram2afp.containsParallelogramPoint(cx, cy, ux, uy, e1, vx, vy, e2, - cx, cy)); - - assertTrue(Parallelogram2afp.containsParallelogramPoint(cx, cy, ux, uy, e1, vx, vy, e2, - 16, 8)); - } - - @Test - public void staticContainsParallelogramRectangle() { - assertFalse(Parallelogram2afp.containsParallelogramRectangle(cx, cy, ux, uy, e1, vx, vy, e2, - 0, 0, 1, 1)); - assertFalse(Parallelogram2afp.containsParallelogramRectangle(cx, cy, ux, uy, e1, vx, vy, e2, - 0, 1, 1, 1)); - assertFalse(Parallelogram2afp.containsParallelogramRectangle(cx, cy, ux, uy, e1, vx, vy, e2, - 0, 2, 1, 1)); - assertFalse(Parallelogram2afp.containsParallelogramRectangle(cx, cy, ux, uy, e1, vx, vy, e2, - 0, 3, 1, 1)); - assertTrue(Parallelogram2afp.containsParallelogramRectangle(cx, cy, ux, uy, e1, vx, vy, e2, - 0, 4, 1, 1)); - assertTrue(Parallelogram2afp.containsParallelogramRectangle(cx, cy, ux, uy, e1, vx, vy, e2, - 0, 5, 1, 1)); - assertTrue(Parallelogram2afp.containsParallelogramRectangle(cx, cy, ux, uy, e1, vx, vy, e2, - 0, 6, 1, 1)); - } - - @Test - public void staticIntersectsParallelogramSegment() { - assertFalse(Parallelogram2afp.intersectsParallelogramSegment(cx, cy, ux, uy, e1, vx, vy, e2, - 0, 0, 1, 1)); - assertTrue(Parallelogram2afp.intersectsParallelogramSegment(cx, cy, ux, uy, e1, vx, vy, e2, - 5, 5, 4, 6)); - assertTrue(Parallelogram2afp.intersectsParallelogramSegment(cx, cy, ux, uy, e1, vx, vy, e2, - 2, -2, 5, 0)); - assertFalse(Parallelogram2afp.intersectsParallelogramSegment(cx, cy, ux, uy, e1, vx, vy, e2, - -20, -5, -10, 6)); - assertFalse(Parallelogram2afp.intersectsParallelogramSegment(cx, cy, ux, uy, e1, vx, vy, e2, - -5, 0, -10, 16)); - assertTrue(Parallelogram2afp.intersectsParallelogramSegment(cx, cy, ux, uy, e1, vx, vy, e2, - -10, 1, 10, 20)); - } - - @Test - public void staticIntersectsParallelogramCircle() { - assertFalse(Parallelogram2afp.intersectsParallelogramCircle(cx, cy, ux, uy, e1, vx, vy, e2, - .5, .5, .5)); - assertFalse(Parallelogram2afp.intersectsParallelogramCircle(cx, cy, ux, uy, e1, vx, vy, e2, - .5, 1.5, .5)); - assertFalse(Parallelogram2afp.intersectsParallelogramCircle(cx, cy, ux, uy, e1, vx, vy, e2, - .5, 2.5, .5)); - assertTrue(Parallelogram2afp.intersectsParallelogramCircle(cx, cy, ux, uy, e1, vx, vy, e2, - .5, 3.5, .5)); - assertTrue(Parallelogram2afp.intersectsParallelogramCircle(cx, cy, ux, uy, e1, vx, vy, e2, - 4.5, 3.5, .5)); - - assertFalse(Parallelogram2afp.intersectsParallelogramCircle(cx, cy, ux, uy, e1, vx, vy, e2, - 10, -7, .5)); - assertFalse(Parallelogram2afp.intersectsParallelogramCircle(cx, cy, ux, uy, e1, vx, vy, e2, - 10.1, -7, .5)); - assertTrue(Parallelogram2afp.intersectsParallelogramCircle(cx, cy, ux, uy, e1, vx, vy, e2, - 10.2, -7, .5)); - - assertTrue(Parallelogram2afp.intersectsParallelogramCircle(cx, cy, ux, uy, e1, vx, vy, e2, - 10, -1, 5)); - } - - @Test - public void staticIntersectsParallelogramEllipse() { - assertFalse(Parallelogram2afp.intersectsParallelogramEllipse(cx, cy, ux, uy, e1, vx, vy, e2, - 0, 0, 2, 1)); - assertFalse(Parallelogram2afp.intersectsParallelogramEllipse(cx, cy, ux, uy, e1, vx, vy, e2, - 0, 1, 2, 1)); - assertTrue(Parallelogram2afp.intersectsParallelogramEllipse(cx, cy, ux, uy, e1, vx, vy, e2, - 0, 2, 2, 1)); - assertTrue(Parallelogram2afp.intersectsParallelogramEllipse(cx, cy, ux, uy, e1, vx, vy, e2, - 0, 3, 2, 1)); - assertTrue(Parallelogram2afp.intersectsParallelogramEllipse(cx, cy, ux, uy, e1, vx, vy, e2, - 0, 4, 2, 1)); - assertTrue(Parallelogram2afp.intersectsParallelogramEllipse(cx, cy, ux, uy, e1, vx, vy, e2, - 1, 3, 2, 1)); - - assertTrue(Parallelogram2afp.intersectsParallelogramEllipse(cx, cy, ux, uy, e1, vx, vy, e2, - 5, 5, 2, 1)); - - assertFalse(Parallelogram2afp.intersectsParallelogramEllipse(cx, cy, ux, uy, e1, vx, vy, e2, - 0.1, 1, 2, 1)); - assertFalse(Parallelogram2afp.intersectsParallelogramEllipse(cx, cy, ux, uy, e1, vx, vy, e2, - 0.2, 1, 2, 1)); - assertTrue(Parallelogram2afp.intersectsParallelogramEllipse(cx, cy, ux, uy, e1, vx, vy, e2, - 0.3, 1, 2, 1)); - assertTrue(Parallelogram2afp.intersectsParallelogramEllipse(cx, cy, ux, uy, e1, vx, vy, e2, - 0.4, 1, 2, 1)); - - assertFalse(Parallelogram2afp.intersectsParallelogramEllipse(cx, cy, ux, uy, e1, vx, vy, e2, - -7, 7.5, 2, 1)); - } - - @Test - public void staticIntersectsParallelogramTriangle() { - assertTrue(Parallelogram2afp.intersectsParallelogramTriangle(cx, cy, ux, uy, e1, vx, vy, e2, - -5, 15, -3, 16, -8, 19)); - assertTrue(Parallelogram2afp.intersectsParallelogramTriangle(cx, cy, ux, uy, e1, vx, vy, e2, - -5, 15, -8, 19, -3, 16)); - assertFalse(Parallelogram2afp.intersectsParallelogramTriangle(cx, cy, ux, uy, e1, vx, vy, e2, - 0, -5, 2, -4, -3, -1)); - assertFalse(Parallelogram2afp.intersectsParallelogramTriangle(cx, cy, ux, uy, e1, vx, vy, e2, - 0, -5, -3, -1, 2, -4)); - assertFalse(Parallelogram2afp.intersectsParallelogramTriangle(cx, cy, ux, uy, e1, vx, vy, e2, - 20, 0, 22, 1, 17, 4)); - assertFalse(Parallelogram2afp.intersectsParallelogramTriangle(cx, cy, ux, uy, e1, vx, vy, e2, - 20, 0, 17, 4, 22, 1)); - assertFalse(Parallelogram2afp.intersectsParallelogramTriangle(cx, cy, ux, uy, e1, vx, vy, e2, - 17.18034, 9, 19.18034, 10, 14.18034, 13)); - assertFalse(Parallelogram2afp.intersectsParallelogramTriangle(cx, cy, ux, uy, e1, vx, vy, e2, - 17.18034, 9, 14.18034, 13, 19.18034, 10)); - assertTrue(Parallelogram2afp.intersectsParallelogramTriangle(cx, cy, ux, uy, e1, vx, vy, e2, - 0, 10, 2, 11, -3, 14)); - assertTrue(Parallelogram2afp.intersectsParallelogramTriangle(cx, cy, ux, uy, e1, vx, vy, e2, - 0, 10, -3, 14, 2, 11)); - assertTrue(Parallelogram2afp.intersectsParallelogramTriangle(cx, cy, ux, uy, e1, vx, vy, e2, - 0, 20, 2, 21, -3, 24)); - } - - @Test - public void staticIntersectsParallelogramParallelogram() { - double ux2 = -0.9284766908852592; - double uy2 = 0.3713906763541037; - double et1 = 5; - double vx2 = 0.3713906763541037; - double vy2 = 0.9284766908852592; - double et2 = 3; - // P + (-0.9284766908852592,0.3713906763541037) * 5 + (0.3713906763541037,0.9284766908852592) * 3 - // P - (-0.9284766908852592,0.3713906763541037) * 5 + (0.3713906763541037,0.9284766908852592) * 3 - // P - (-0.9284766908852592,0.3713906763541037) * 5 - (0.3713906763541037,0.9284766908852592) * 3 - // P + (-0.9284766908852592,0.3713906763541037) * 5 - (0.3713906763541037,0.9284766908852592) * 3 - assertFalse(Parallelogram2afp.intersectsParallelogramParallelogram(cx, cy, ux, uy, e1, vx, vy, e2, - -10, 0, - ux2, uy2, et1, vx2, vy2, et2)); - assertFalse(Parallelogram2afp.intersectsParallelogramParallelogram(cx, cy, ux, uy, e1, vx, vy, e2, - -15, 25, - ux2, uy2, et1, vx2, vy2, et2)); - assertFalse(Parallelogram2afp.intersectsParallelogramParallelogram(cx, cy, ux, uy, e1, vx, vy, e2, - 2, -6, - ux2, uy2, et1, vx2, vy2, et2)); - assertFalse(Parallelogram2afp.intersectsParallelogramParallelogram(cx, cy, ux, uy, e1, vx, vy, e2, - 2, -5, - ux2, uy2, et1, vx2, vy2, et2)); - assertTrue(Parallelogram2afp.intersectsParallelogramParallelogram(cx, cy, ux, uy, e1, vx, vy, e2, - 2, -4, - ux2, uy2, et1, vx2, vy2, et2)); - assertTrue(Parallelogram2afp.intersectsParallelogramParallelogram(cx, cy, ux, uy, e1, vx, vy, e2, - pEx, pEy, - ux2, uy2, et1, vx2, vy2, et2)); - assertTrue(Parallelogram2afp.intersectsParallelogramParallelogram(cx, cy, ux, uy, e1, vx, vy, e2, - 6, 6, - ux2, uy2, et1, vx2, vy2, et2)); - assertTrue(Parallelogram2afp.intersectsParallelogramParallelogram(cx, cy, ux, uy, e1, vx, vy, e2, - 6, 6, - ux2, uy2, 10 * et1, vx2, vy2, 10 * et2)); - } - - @Test - public void staticIntersectsParallelogramRectangle() { - assertFalse(Parallelogram2afp.intersectsParallelogramRectangle(cx, cy, ux, uy, e1, vx, vy, e2, - 0, 0, 1, 1)); - assertTrue(Parallelogram2afp.intersectsParallelogramRectangle(cx, cy, ux, uy, e1, vx, vy, e2, - 0, 2, 1, 1)); - assertTrue(Parallelogram2afp.intersectsParallelogramRectangle(cx, cy, ux, uy, e1, vx, vy, e2, - -5.5, 8.5, 1, 1)); - assertFalse(Parallelogram2afp.intersectsParallelogramRectangle(cx, cy, ux, uy, e1, vx, vy, e2, - -6, 16, 1, 1)); - assertFalse(Parallelogram2afp.intersectsParallelogramRectangle(cx, cy, ux, uy, e1, vx, vy, e2, - 146, 16, 1, 1)); - assertTrue(Parallelogram2afp.intersectsParallelogramRectangle(cx, cy, ux, uy, e1, vx, vy, e2, - 12, 14, 1, 1)); - assertTrue(Parallelogram2afp.intersectsParallelogramRectangle(cx, cy, ux, uy, e1, vx, vy, e2, - 0, 8, 1, 1)); - assertTrue(Parallelogram2afp.intersectsParallelogramRectangle(cx, cy, ux, uy, e1, vx, vy, e2, - 10, -1, 1, 1)); - assertTrue(Parallelogram2afp.intersectsParallelogramRectangle(cx, cy, ux, uy, e1, vx, vy, e2, - -15, -10, 35, 40)); - assertTrue(Parallelogram2afp.intersectsParallelogramRectangle(cx, cy, ux, uy, e1, vx, vy, e2, - -4.79634, 14.50886, 1, 1)); - } - - @Test - public void staticIntersectsParallelogramRoundRectangle() { - assertFalse(Parallelogram2afp.intersectsParallelogramRoundRectangle(cx, cy, ux, uy, e1, vx, vy, e2, - 0, 0, 1, 1, .1, .05)); - assertTrue(Parallelogram2afp.intersectsParallelogramRoundRectangle(cx, cy, ux, uy, e1, vx, vy, e2, - 0, 2, 1, 1, .1, .05)); - assertTrue(Parallelogram2afp.intersectsParallelogramRoundRectangle(cx, cy, ux, uy, e1, vx, vy, e2, - -5.5, 8.5, 1, 1, .1, .05)); - assertFalse(Parallelogram2afp.intersectsParallelogramRoundRectangle(cx, cy, ux, uy, e1, vx, vy, e2, - -6, 16, 1, 1, .1, .05)); - assertFalse(Parallelogram2afp.intersectsParallelogramRoundRectangle(cx, cy, ux, uy, e1, vx, vy, e2, - 146, 16, 1, 1, .1, .05)); - assertTrue(Parallelogram2afp.intersectsParallelogramRoundRectangle(cx, cy, ux, uy, e1, vx, vy, e2, - 12, 14, 1, 1, .1, .05)); - assertTrue(Parallelogram2afp.intersectsParallelogramRoundRectangle(cx, cy, ux, uy, e1, vx, vy, e2, - 0, 8, 1, 1, .1, .05)); - assertTrue(Parallelogram2afp.intersectsParallelogramRoundRectangle(cx, cy, ux, uy, e1, vx, vy, e2, - 10, -1, 1, 1, .1, .05)); - assertTrue(Parallelogram2afp.intersectsParallelogramRoundRectangle(cx, cy, ux, uy, e1, vx, vy, e2, - -15, -10, 35, 40, .1, .05)); - assertFalse(Parallelogram2afp.intersectsParallelogramRoundRectangle(cx, cy, ux, uy, e1, vx, vy, e2, - -4.79634, 14.50886, 1, 1, .1, .05)); - } - - @Override - public void testClone() { - T clone = this.shape.clone(); - assertNotNull(clone); - assertNotSame(this.shape, clone); - assertEquals(this.shape.getClass(), clone.getClass()); - assertEpsilonEquals(cx, clone.getCenterX()); - assertEpsilonEquals(cy, clone.getCenterY()); - assertEpsilonEquals(ux, clone.getFirstAxisX()); - assertEpsilonEquals(uy, clone.getFirstAxisY()); - assertEpsilonEquals(e1, clone.getFirstAxisExtent()); - assertEpsilonEquals(vx, clone.getSecondAxisX()); - assertEpsilonEquals(vy, clone.getSecondAxisY()); - assertEpsilonEquals(e2, clone.getSecondAxisExtent()); - } - - @Override - public void equalsObject() { - assertFalse(this.shape.equals(null)); - assertFalse(this.shape.equals(new Object())); - assertFalse(this.shape.equals(createParallelogram(0, cy, ux, uy, e1, vx, vy, e2))); - assertFalse(this.shape.equals(createParallelogram(cx, cy, ux, uy, e1, vx, vy, 20))); - assertFalse(this.shape.equals(createSegment(5, 8, 6, 10))); - assertTrue(this.shape.equals(this.shape)); - assertTrue(this.shape.equals(createParallelogram(cx, cy, ux, uy, e1, vx, vy, e2))); - } - - @Override - public void equalsObject_withPathIterator() { - assertFalse(this.shape.equals((PathIterator2afp) null)); - assertFalse(this.shape.equals(createParallelogram(0, cy, ux, uy, e1, vx, vy, e2).getPathIterator())); - assertFalse(this.shape.equals(createParallelogram(cx, cy, ux, uy, e1, vx, vy, 20).getPathIterator())); - assertFalse(this.shape.equals(createSegment(5, 8, 6, 10).getPathIterator())); - assertTrue(this.shape.equals(this.shape.getPathIterator())); - assertTrue(this.shape.equals(createParallelogram(cx, cy, ux, uy, e1, vx, vy, e2).getPathIterator())); - } - - @Override - public void equalsToPathIterator() { - assertFalse(this.shape.equalsToPathIterator(null)); - assertFalse(this.shape.equalsToPathIterator(createParallelogram(0, cy, ux, uy, e1, vx, vy, e2).getPathIterator())); - assertFalse(this.shape.equalsToPathIterator(createParallelogram(cx, cy, ux, uy, e1, vx, vy, 20).getPathIterator())); - assertFalse(this.shape.equalsToPathIterator(createSegment(5, 8, 6, 10).getPathIterator())); - assertTrue(this.shape.equalsToPathIterator(this.shape.getPathIterator())); - assertTrue(this.shape.equalsToPathIterator(createParallelogram(cx, cy, ux, uy, e1, vx, vy, e2).getPathIterator())); - } - - @Override - public void equalsToShape() { - assertFalse(this.shape.equalsToShape(null)); - assertFalse(this.shape.equalsToShape((T) createParallelogram(0, cy, ux, uy, e1, vx, vy, e2))); - assertFalse(this.shape.equalsToShape((T) createParallelogram(cx, cy, ux, uy, e1, vx, vy, 20))); - assertTrue(this.shape.equalsToShape(this.shape)); - assertTrue(this.shape.equalsToShape((T) createParallelogram(cx, cy, ux, uy, e1, vx, vy, e2))); - } - - @Override - public void isEmpty() { - assertFalse(this.shape.isEmpty()); - this.shape.clear(); - assertTrue(this.shape.isEmpty()); - } - - @Override - public void clear() { - this.shape.clear(); - assertEpsilonEquals(0, this.shape.getCenterX()); - assertEpsilonEquals(0, this.shape.getCenterY()); - assertEpsilonEquals(1, this.shape.getFirstAxisX()); - assertEpsilonEquals(0, this.shape.getFirstAxisY()); - assertEpsilonEquals(0, this.shape.getFirstAxisExtent()); - assertEpsilonEquals(0, this.shape.getSecondAxisX()); - assertEpsilonEquals(1, this.shape.getSecondAxisY()); - assertEpsilonEquals(0, this.shape.getSecondAxisExtent()); - } - - @Override - public void containsDoubleDouble() { - assertFalse(this.shape.contains(0, 0)); - assertFalse(this.shape.contains(-20, 0)); - assertTrue(this.shape.contains(12, -4)); - assertTrue(this.shape.contains(14, 0)); - assertFalse(this.shape.contains(15, 0)); - assertFalse(this.shape.contains(20, 8)); - assertTrue(this.shape.contains(8, 16)); - assertFalse(this.shape.contains(-4, 20)); - assertFalse(this.shape.contains(-5, 12)); - assertTrue(this.shape.contains(0, 6)); - assertTrue(this.shape.contains(0, 7)); - assertTrue(this.shape.contains(0, 8)); - assertTrue(this.shape.contains(0, 9)); - assertTrue(this.shape.contains(0, 10)); - assertFalse(this.shape.contains(0, 27)); - assertTrue(this.shape.contains(cx, cy)); - assertTrue(this.shape.contains(16, 8)); - } - - @Override - public void containsPoint2D() { - assertFalse(this.shape.contains(createPoint(0, 0))); - assertFalse(this.shape.contains(createPoint(-20, 0))); - assertTrue(this.shape.contains(createPoint(12, -4))); - assertTrue(this.shape.contains(createPoint(14, 0))); - assertFalse(this.shape.contains(createPoint(15, 0))); - assertFalse(this.shape.contains(createPoint(20, 8))); - assertTrue(this.shape.contains(createPoint(8, 16))); - assertFalse(this.shape.contains(createPoint(-4, 20))); - assertFalse(this.shape.contains(createPoint(-5, 12))); - assertTrue(this.shape.contains(createPoint(0, 6))); - assertTrue(this.shape.contains(createPoint(0, 7))); - assertTrue(this.shape.contains(createPoint(0, 8))); - assertTrue(this.shape.contains(createPoint(0, 9))); - assertTrue(this.shape.contains(createPoint(0, 10))); - assertFalse(this.shape.contains(createPoint(0, 27))); - assertTrue(this.shape.contains(createPoint(cx, cy))); - assertTrue(this.shape.contains(createPoint( 16, 8))); - } - - @Override - public void getClosestPointTo() { - Point2D closest; - - closest = this.shape.getClosestPointTo(createPoint(-20, 9)); - assertEpsilonEquals(pHx, closest.getX()); - assertEpsilonEquals(pHy, closest.getY()); - - closest = this.shape.getClosestPointTo(createPoint(0, 0)); - assertEpsilonEquals(1.90983, closest.getX()); - assertEpsilonEquals(1.90983, closest.getY()); - - closest = this.shape.getClosestPointTo(createPoint(5, -10)); - assertEpsilonEquals(9.40983, closest.getX()); - assertEpsilonEquals(-5.59017, closest.getY()); - - closest = this.shape.getClosestPointTo(createPoint(14, -20)); - assertEpsilonEquals(pEx, closest.getX()); - assertEpsilonEquals(pEy, closest.getY()); - - closest = this.shape.getClosestPointTo(createPoint(-6, 15)); - assertEpsilonEquals(-3.81679, closest.getX()); - assertEpsilonEquals(14.4542, closest.getY()); - - closest = this.shape.getClosestPointTo(createPoint(0, 10)); - assertEpsilonEquals(0, closest.getX()); - assertEpsilonEquals(10, closest.getY()); - - closest = this.shape.getClosestPointTo(createPoint(10, 0)); - assertEpsilonEquals(10, closest.getX()); - assertEpsilonEquals(0, closest.getY()); - - closest = this.shape.getClosestPointTo(createPoint(15, -4)); - assertEpsilonEquals(13.99326, closest.getX()); - assertEpsilonEquals(-3.74832, closest.getY()); - - closest = this.shape.getClosestPointTo(createPoint(-5, 25)); - assertEpsilonEquals(-1.40503, closest.getX()); - assertEpsilonEquals(24.10126, closest.getY()); - - closest = this.shape.getClosestPointTo(createPoint(0, 20)); - assertEpsilonEquals(0, closest.getX()); - assertEpsilonEquals(20, closest.getY()); - - closest = this.shape.getClosestPointTo(createPoint(10, 10)); - assertEpsilonEquals(10, closest.getX()); - assertEpsilonEquals(10, closest.getY()); - - closest = this.shape.getClosestPointTo(createPoint(20, 0)); - assertEpsilonEquals(15.22856, closest.getX()); - assertEpsilonEquals(1.19286, closest.getY()); - - closest = this.shape.getClosestPointTo(createPoint(-3, 35)); - assertEpsilonEquals(pGx, closest.getX()); - assertEpsilonEquals(pGy, closest.getY()); - - closest = this.shape.getClosestPointTo(createPoint(5, 35)); - assertEpsilonEquals(pGx, closest.getX()); - assertEpsilonEquals(pGy, closest.getY()); - - closest = this.shape.getClosestPointTo(createPoint(20, 15)); - assertEpsilonEquals(15.59017, closest.getX()); - assertEpsilonEquals(10.59017, closest.getY()); - - closest = this.shape.getClosestPointTo(createPoint(35, 10)); - assertEpsilonEquals(pFx, closest.getX()); - assertEpsilonEquals(pFy, closest.getY()); - - closest = this.shape.getClosestPointTo(createPoint(-8, 29)); - assertEpsilonEquals(pGx, closest.getX()); - assertEpsilonEquals(pGy, closest.getY()); - } - - @Override - public void getFarthestPointTo() { - Point2D farthest; - - farthest = this.shape.getFarthestPointTo(createPoint(-20, 9)); - assertEpsilonEquals(pEx, farthest.getX()); - assertEpsilonEquals(pEy, farthest.getY()); - - farthest = this.shape.getFarthestPointTo(createPoint(0, 0)); - assertEpsilonEquals(pGx, farthest.getX()); - assertEpsilonEquals(pGy, farthest.getY()); - - farthest = this.shape.getFarthestPointTo(createPoint(5, -10)); - assertEpsilonEquals(pGx, farthest.getX()); - assertEpsilonEquals(pGy, farthest.getY()); - - farthest = this.shape.getFarthestPointTo(createPoint(14, -20)); - assertEpsilonEquals(pGx, farthest.getX()); - assertEpsilonEquals(pGy, farthest.getY()); - - farthest = this.shape.getFarthestPointTo(createPoint(-6, 15)); - assertEpsilonEquals(pEx, farthest.getX()); - assertEpsilonEquals(pEy, farthest.getY()); - - farthest = this.shape.getFarthestPointTo(createPoint(0, 10)); - assertEpsilonEquals(pEx, farthest.getX()); - assertEpsilonEquals(pEy, farthest.getY()); - - farthest = this.shape.getFarthestPointTo(createPoint(10, 0)); - assertEpsilonEquals(pGx, farthest.getX()); - assertEpsilonEquals(pGy, farthest.getY()); - - farthest = this.shape.getFarthestPointTo(createPoint(15, -4)); - assertEpsilonEquals(pGx, farthest.getX()); - assertEpsilonEquals(pGy, farthest.getY()); - - farthest = this.shape.getFarthestPointTo(createPoint(-5, 25)); - assertEpsilonEquals(pEx, farthest.getX()); - assertEpsilonEquals(pEy, farthest.getY()); - - farthest = this.shape.getFarthestPointTo(createPoint(0, 20)); - assertEpsilonEquals(pEx, farthest.getX()); - assertEpsilonEquals(pEy, farthest.getY()); - - farthest = this.shape.getFarthestPointTo(createPoint(10, 10)); - assertEpsilonEquals(pGx, farthest.getX()); - assertEpsilonEquals(pGy, farthest.getY()); - - farthest = this.shape.getFarthestPointTo(createPoint(20, 0)); - assertEpsilonEquals(pGx, farthest.getX()); - assertEpsilonEquals(pGy, farthest.getY()); - - farthest = this.shape.getFarthestPointTo(createPoint(-3, 35)); - assertEpsilonEquals(pEx, farthest.getX()); - assertEpsilonEquals(pEy, farthest.getY()); - - farthest = this.shape.getFarthestPointTo(createPoint(5, 35)); - assertEpsilonEquals(pEx, farthest.getX()); - assertEpsilonEquals(pEy, farthest.getY()); - - farthest = this.shape.getFarthestPointTo(createPoint(20, 15)); - assertEpsilonEquals(pHx, farthest.getX()); - assertEpsilonEquals(pHy, farthest.getY()); - - farthest = this.shape.getFarthestPointTo(createPoint(35, 10)); - assertEpsilonEquals(pHx, farthest.getX()); - assertEpsilonEquals(pHy, farthest.getY()); - - farthest = this.shape.getFarthestPointTo(createPoint(-8, 29)); - assertEpsilonEquals(pEx, farthest.getX()); - assertEpsilonEquals(pEy, farthest.getY()); - } - - @Override - public void translateDoubleDouble() { - this.shape.translate(123.456, 789.123); - assertEpsilonEquals(cx + 123.456, this.shape.getCenterX()); - assertEpsilonEquals(cy + 789.123, this.shape.getCenterY()); - assertEpsilonEquals(ux, this.shape.getFirstAxisX()); - assertEpsilonEquals(uy, this.shape.getFirstAxisY()); - assertEpsilonEquals(e1, this.shape.getFirstAxisExtent()); - assertEpsilonEquals(vx, this.shape.getSecondAxisX()); - assertEpsilonEquals(vy, this.shape.getSecondAxisY()); - assertEpsilonEquals(e2, this.shape.getSecondAxisExtent()); - } - - @Override - public void translateVector2D() { - this.shape.translate(createVector(123.456, 789.123)); - assertEpsilonEquals(cx + 123.456, this.shape.getCenterX()); - assertEpsilonEquals(cy + 789.123, this.shape.getCenterY()); - assertEpsilonEquals(ux, this.shape.getFirstAxisX()); - assertEpsilonEquals(uy, this.shape.getFirstAxisY()); - assertEpsilonEquals(e1, this.shape.getFirstAxisExtent()); - assertEpsilonEquals(vx, this.shape.getSecondAxisX()); - assertEpsilonEquals(vy, this.shape.getSecondAxisY()); - assertEpsilonEquals(e2, this.shape.getSecondAxisExtent()); - } - - @Override - public void getDistance() { - assertEpsilonEquals(14.81966, this.shape.getDistance(createPoint(-20, 9))); - assertEpsilonEquals(2.7009, this.shape.getDistance(createPoint(0, 0))); - assertEpsilonEquals(6.23644, this.shape.getDistance(createPoint(5, -10))); - assertEpsilonEquals(11.1863, this.shape.getDistance(createPoint(14, -20))); - assertEpsilonEquals(2.25040, this.shape.getDistance(createPoint(-6, 15))); - assertEpsilonEquals(0, this.shape.getDistance(createPoint(0, 10))); - assertEpsilonEquals(0, this.shape.getDistance(createPoint(10, 0))); - assertEpsilonEquals(1.03772, this.shape.getDistance(createPoint(15, -4))); - assertEpsilonEquals(3.70561, this.shape.getDistance(createPoint(-5, 25))); - assertEpsilonEquals(0, this.shape.getDistance(createPoint(0, 20))); - assertEpsilonEquals(0, this.shape.getDistance(createPoint(10, 10))); - assertEpsilonEquals(4.91829, this.shape.getDistance(createPoint(20, 0))); - assertEpsilonEquals(8.42901, this.shape.getDistance(createPoint(-3, 35))); - assertEpsilonEquals(9.91864, this.shape.getDistance(createPoint(5, 35))); - assertEpsilonEquals(6.23644, this.shape.getDistance(createPoint(20, 15))); - assertEpsilonEquals(17.8477, this.shape.getDistance(createPoint(35, 10))); - assertEpsilonEquals(7.59135, this.shape.getDistance(createPoint(-8, 29))); - } - - @Override - public void getDistanceSquared() { - assertEpsilonEquals(219.62232, this.shape.getDistanceSquared(createPoint(-20, 9))); - assertEpsilonEquals(7.29486, this.shape.getDistanceSquared(createPoint(0, 0))); - assertEpsilonEquals(38.89318, this.shape.getDistanceSquared(createPoint(5, -10))); - assertEpsilonEquals(125.13319, this.shape.getDistanceSquared(createPoint(14, -20))); - assertEpsilonEquals(5.0643, this.shape.getDistanceSquared(createPoint(-6, 15))); - assertEpsilonEquals(0, this.shape.getDistanceSquared(createPoint(0, 10))); - assertEpsilonEquals(0, this.shape.getDistanceSquared(createPoint(10, 0))); - assertEpsilonEquals(1.07686, this.shape.getDistanceSquared(createPoint(15, -4))); - assertEpsilonEquals(13.73155, this.shape.getDistanceSquared(createPoint(-5, 25))); - assertEpsilonEquals(0, this.shape.getDistanceSquared(createPoint(0, 20))); - assertEpsilonEquals(0, this.shape.getDistanceSquared(createPoint(10, 10))); - assertEpsilonEquals(24.18958, this.shape.getDistanceSquared(createPoint(20, 0))); - assertEpsilonEquals(71.04805, this.shape.getDistanceSquared(createPoint(-3, 35))); - assertEpsilonEquals(98.37931, this.shape.getDistanceSquared(createPoint(5, 35))); - assertEpsilonEquals(38.89318, this.shape.getDistanceSquared(createPoint(20, 15))); - assertEpsilonEquals(318.54029, this.shape.getDistanceSquared(createPoint(35, 10))); - assertEpsilonEquals(57.62859, this.shape.getDistanceSquared(createPoint(-8, 29))); - } - - @Override - public void getDistanceL1() { - assertEpsilonEquals(14.81966, this.shape.getDistanceL1(createPoint(-20, 9))); - assertEpsilonEquals(3.81966, this.shape.getDistanceL1(createPoint(0, 0))); - assertEpsilonEquals(8.81966, this.shape.getDistanceL1(createPoint(5, -10))); - assertEpsilonEquals(12.40325, this.shape.getDistanceL1(createPoint(14, -20))); - assertEpsilonEquals(2.72901, this.shape.getDistanceL1(createPoint(-6, 15))); - assertEpsilonEquals(0, this.shape.getDistanceL1(createPoint(0, 10))); - assertEpsilonEquals(0, this.shape.getDistanceL1(createPoint(10, 0))); - assertEpsilonEquals(1.25842, this.shape.getDistanceL1(createPoint(15, -4))); - assertEpsilonEquals(4.49371, this.shape.getDistanceL1(createPoint(-5, 25))); - assertEpsilonEquals(0, this.shape.getDistanceL1(createPoint(0, 20))); - assertEpsilonEquals(0, this.shape.getDistanceL1(createPoint(10, 10))); - assertEpsilonEquals(5.9643, this.shape.getDistanceL1(createPoint(20, 0))); - assertEpsilonEquals(10.40326, this.shape.getDistanceL1(createPoint(-3, 35))); - assertEpsilonEquals(13.81966, this.shape.getDistanceL1(createPoint(5, 35))); - assertEpsilonEquals(8.81966, this.shape.getDistanceL1(createPoint(20, 15))); - assertEpsilonEquals(18.81966, this.shape.getDistanceL1(createPoint(35, 10))); - assertEpsilonEquals(9.40326, this.shape.getDistanceL1(createPoint(-8, 29))); - } - - @Override - public void getDistanceLinf() { - assertEpsilonEquals(14.81966, this.shape.getDistanceLinf(createPoint(-20, 9))); - assertEpsilonEquals(1.90983, this.shape.getDistanceLinf(createPoint(0, 0))); - assertEpsilonEquals(4.40983, this.shape.getDistanceLinf(createPoint(5, -10))); - assertEpsilonEquals(11.11146, this.shape.getDistanceLinf(createPoint(14, -20))); - assertEpsilonEquals(2.18321, this.shape.getDistanceLinf(createPoint(-6, 15))); - assertEpsilonEquals(0, this.shape.getDistanceLinf(createPoint(0, 10))); - assertEpsilonEquals(0, this.shape.getDistanceLinf(createPoint(10, 0))); - assertEpsilonEquals(1.00674, this.shape.getDistanceLinf(createPoint(15, -4))); - assertEpsilonEquals(3.59497, this.shape.getDistanceLinf(createPoint(-5, 25))); - assertEpsilonEquals(0, this.shape.getDistanceLinf(createPoint(0, 20))); - assertEpsilonEquals(0, this.shape.getDistanceLinf(createPoint(10, 10))); - assertEpsilonEquals(4.77144, this.shape.getDistanceLinf(createPoint(20, 0))); - assertEpsilonEquals(8.11146, this.shape.getDistanceLinf(createPoint(-3, 35))); - assertEpsilonEquals(8.11146, this.shape.getDistanceLinf(createPoint(5, 35))); - assertEpsilonEquals(4.40983, this.shape.getDistanceLinf(createPoint(20, 15))); - assertEpsilonEquals(17.81966, this.shape.getDistanceLinf(createPoint(35, 10))); - assertEpsilonEquals(7.2918, this.shape.getDistanceLinf(createPoint(-8, 29))); - } - - @Override - public void setIT() { - this.shape.set((T) createParallelogram(17, 20, 1, 0, 15, 0, 1, 14)); - assertEpsilonEquals(17, this.shape.getCenterX()); - assertEpsilonEquals(20, this.shape.getCenterY()); - assertEpsilonEquals(1, this.shape.getFirstAxisX()); - assertEpsilonEquals(0, this.shape.getFirstAxisY()); - assertEpsilonEquals(15, this.shape.getFirstAxisExtent()); - assertEpsilonEquals(0, this.shape.getSecondAxisX()); - assertEpsilonEquals(1, this.shape.getSecondAxisY()); - assertEpsilonEquals(14, this.shape.getSecondAxisExtent()); - } - - @Override - public void getPathIterator() { - PathIterator2afp pi = this.shape.getPathIterator(); - assertElement(pi, PathElementType.MOVE_TO, pGx, pGy); - assertElement(pi, PathElementType.LINE_TO, pHx, pHy); - assertElement(pi, PathElementType.LINE_TO, pEx, pEy); - assertElement(pi, PathElementType.LINE_TO, pFx, pFy); - assertElement(pi, PathElementType.CLOSE, pGx, pGy); - assertNoElement(pi); - } - - @Override - public void getPathIteratorTransform2D() { - PathIterator2afp pi = this.shape.getPathIterator(null); - assertElement(pi, PathElementType.MOVE_TO, pGx, pGy); - assertElement(pi, PathElementType.LINE_TO, pHx, pHy); - assertElement(pi, PathElementType.LINE_TO, pEx, pEy); - assertElement(pi, PathElementType.LINE_TO, pFx, pFy); - assertElement(pi, PathElementType.CLOSE, pGx, pGy); - assertNoElement(pi); - - Transform2D transform; - - transform = new Transform2D(); - pi = this.shape.getPathIterator(transform); - assertElement(pi, PathElementType.MOVE_TO, pGx, pGy); - assertElement(pi, PathElementType.LINE_TO, pHx, pHy); - assertElement(pi, PathElementType.LINE_TO, pEx, pEy); - assertElement(pi, PathElementType.LINE_TO, pFx, pFy); - assertElement(pi, PathElementType.CLOSE, pGx, pGy); - assertNoElement(pi); - - transform = new Transform2D(); - transform.setTranslation(18, -45); - pi = this.shape.getPathIterator(transform); - assertElement(pi, PathElementType.MOVE_TO, pGx + 18, pGy - 45); - assertElement(pi, PathElementType.LINE_TO, pHx + 18, pHy - 45); - assertElement(pi, PathElementType.LINE_TO, pEx + 18, pEy - 45); - assertElement(pi, PathElementType.LINE_TO, pFx + 18, pFy - 45); - assertElement(pi, PathElementType.CLOSE, pGx + 18, pGy - 45); - assertNoElement(pi); - } - - @Override - public void createTransformedShape() { - PathIterator2afp pi = this.shape.createTransformedShape(null).getPathIterator(); - assertElement(pi, PathElementType.MOVE_TO, pGx, pGy); - assertElement(pi, PathElementType.LINE_TO, pHx, pHy); - assertElement(pi, PathElementType.LINE_TO, pEx, pEy); - assertElement(pi, PathElementType.LINE_TO, pFx, pFy); - assertElement(pi, PathElementType.CLOSE, pGx, pGy); - assertNoElement(pi); - - Transform2D transform; - - transform = new Transform2D(); - pi = this.shape.createTransformedShape(transform).getPathIterator(); - assertElement(pi, PathElementType.MOVE_TO, pGx, pGy); - assertElement(pi, PathElementType.LINE_TO, pHx, pHy); - assertElement(pi, PathElementType.LINE_TO, pEx, pEy); - assertElement(pi, PathElementType.LINE_TO, pFx, pFy); - assertElement(pi, PathElementType.CLOSE, pGx, pGy); - assertNoElement(pi); - - transform = new Transform2D(); - transform.setTranslation(18, -45); - pi = this.shape.createTransformedShape(transform).getPathIterator(); - assertElement(pi, PathElementType.MOVE_TO, pGx + 18, pGy - 45); - assertElement(pi, PathElementType.LINE_TO, pHx + 18, pHy - 45); - assertElement(pi, PathElementType.LINE_TO, pEx + 18, pEy - 45); - assertElement(pi, PathElementType.LINE_TO, pFx + 18, pFy - 45); - assertElement(pi, PathElementType.CLOSE, pGx + 18, pGy - 45); - assertNoElement(pi); - } - - @Override - public void toBoundingBox() { - B box = this.shape.toBoundingBox(); - assertEpsilonEquals(pHx, box.getMinX()); - assertEpsilonEquals(pEy, box.getMinY()); - assertEpsilonEquals(pFx, box.getMaxX()); - assertEpsilonEquals(pGy, box.getMaxY()); - } - - @Override - public void toBoundingBoxB() { - B box = createRectangle(0, 0, 0, 0); - this.shape.toBoundingBox(box); - assertEpsilonEquals(pHx, box.getMinX()); - assertEpsilonEquals(pEy, box.getMinY()); - assertEpsilonEquals(pFx, box.getMaxX()); - assertEpsilonEquals(pGy, box.getMaxY()); - } - - @Override - public void containsRectangle2afp() { - assertFalse(this.shape.contains(createRectangle(0, 0, 1, 1))); - assertFalse(this.shape.contains(createRectangle(0, 1, 1, 1))); - assertFalse(this.shape.contains(createRectangle(0, 2, 1, 1))); - assertFalse(this.shape.contains(createRectangle(0, 3, 1, 1))); - assertTrue(this.shape.contains(createRectangle(0, 4, 1, 1))); - assertTrue(this.shape.contains(createRectangle(0, 5, 1, 1))); - assertTrue(this.shape.contains(createRectangle(0, 6, 1, 1))); - } - - @Override - public void containsShape2D() { - assertFalse(this.shape.contains(createCircle(0, 0, 1))); - assertFalse(this.shape.contains(createCircle(0, 1, 1))); - assertFalse(this.shape.contains(createCircle(0, 2, 1))); - assertFalse(this.shape.contains(createCircle(0, 3, 1))); - assertFalse(this.shape.contains(createCircle(0, 4, 1))); - assertFalse(this.shape.contains(createCircle(0, 5, 1))); - assertTrue(this.shape.contains(createCircle(0, 6, 1))); - } - - @Test - public void rotateDouble() { - this.shape.rotate(-MathConstants.DEMI_PI); - assertEpsilonEquals(6, this.shape.getCenterX()); - assertEpsilonEquals(9, this.shape.getCenterY()); - assertEpsilonEquals(9.701400000000000e-01, this.shape.getFirstAxisX()); - assertEpsilonEquals(-2.425400000000000e-01, this.shape.getFirstAxisY()); - assertEpsilonEquals(9.21954, this.shape.getFirstAxisExtent()); - assertEpsilonEquals(7.071100000000000e-01, this.shape.getSecondAxisX()); - assertEpsilonEquals(7.071100000000000e-01, this.shape.getSecondAxisY()); - assertEpsilonEquals(12.64911, this.shape.getSecondAxisExtent()); - } - - @Test - public void getCenter() { - Point2D c = this.shape.getCenter(); - assertEpsilonEquals(6, c.getX()); - assertEpsilonEquals(9, c.getY()); - } - - @Test - public void getCenterX() { - assertEpsilonEquals(6, this.shape.getCenterX()); - } - - @Test - public void getCenterY() { - assertEpsilonEquals(9, this.shape.getCenterY()); - } - - @Test - public void setCenterDoubleDouble() { - this.shape.setCenter(123.456, -789.123); - assertEpsilonEquals(123.456, this.shape.getCenterX()); - assertEpsilonEquals(-789.123, this.shape.getCenterY()); - assertEpsilonEquals(ux, this.shape.getFirstAxisX()); - assertEpsilonEquals(uy, this.shape.getFirstAxisY()); - assertEpsilonEquals(e1, this.shape.getFirstAxisExtent()); - assertEpsilonEquals(vx, this.shape.getSecondAxisX()); - assertEpsilonEquals(vy, this.shape.getSecondAxisY()); - assertEpsilonEquals(e2, this.shape.getSecondAxisExtent()); - } - - @Test - public void setCenterPoint2D() { - this.shape.setCenter(createPoint(123.456, -789.123)); - assertEpsilonEquals(123.456, this.shape.getCenterX()); - assertEpsilonEquals(-789.123, this.shape.getCenterY()); - assertEpsilonEquals(ux, this.shape.getFirstAxisX()); - assertEpsilonEquals(uy, this.shape.getFirstAxisY()); - assertEpsilonEquals(e1, this.shape.getFirstAxisExtent()); - assertEpsilonEquals(vx, this.shape.getSecondAxisX()); - assertEpsilonEquals(vy, this.shape.getSecondAxisY()); - assertEpsilonEquals(e2, this.shape.getSecondAxisExtent()); - } - - @Test - public void setCenterX() { - this.shape.setCenterX(123.456); - assertEpsilonEquals(123.456, this.shape.getCenterX()); - assertEpsilonEquals(cy, this.shape.getCenterY()); - assertEpsilonEquals(ux, this.shape.getFirstAxisX()); - assertEpsilonEquals(uy, this.shape.getFirstAxisY()); - assertEpsilonEquals(e1, this.shape.getFirstAxisExtent()); - assertEpsilonEquals(vx, this.shape.getSecondAxisX()); - assertEpsilonEquals(vy, this.shape.getSecondAxisY()); - assertEpsilonEquals(e2, this.shape.getSecondAxisExtent()); - } - - @Test - public void setCenterY() { - this.shape.setCenterY(123.456); - assertEpsilonEquals(cx, this.shape.getCenterX()); - assertEpsilonEquals(123.456, this.shape.getCenterY()); - assertEpsilonEquals(ux, this.shape.getFirstAxisX()); - assertEpsilonEquals(uy, this.shape.getFirstAxisY()); - assertEpsilonEquals(e1, this.shape.getFirstAxisExtent()); - assertEpsilonEquals(vx, this.shape.getSecondAxisX()); - assertEpsilonEquals(vy, this.shape.getSecondAxisY()); - assertEpsilonEquals(e2, this.shape.getSecondAxisExtent()); - } - - @Test - public void getFirstAxis() { - Vector2D v = this.shape.getFirstAxis(); - assertEpsilonEquals(ux, v.getX()); - assertEpsilonEquals(uy, v.getY()); - } - - @Test - public void getFirstAxisX() { - assertEpsilonEquals(ux, this.shape.getFirstAxisX()); - } - - @Test - public void getFirstAxisY() { - assertEpsilonEquals(uy, this.shape.getFirstAxisY()); - } - - @Test - public void getSecondAxis() { - Vector2D v = this.shape.getSecondAxis(); - assertEpsilonEquals(vx, v.getX()); - assertEpsilonEquals(vy, v.getY()); - } - - @Test - public void getSecondAxisX() { - assertEpsilonEquals(vx, this.shape.getSecondAxisX()); - } - - @Test - public void getSecondAxisY() { - assertEpsilonEquals(vy, this.shape.getSecondAxisY()); - } - - @Test - public void getFirstAxisExtent() { - assertEpsilonEquals(e1, this.shape.getFirstAxisExtent()); - } - - @Test - public void setFirstAxisExtent() { - this.shape.setFirstAxisExtent(123.456); - assertEpsilonEquals(cx, this.shape.getCenterX()); - assertEpsilonEquals(cy, this.shape.getCenterY()); - assertEpsilonEquals(ux, this.shape.getFirstAxisX()); - assertEpsilonEquals(uy, this.shape.getFirstAxisY()); - assertEpsilonEquals(123.456, this.shape.getFirstAxisExtent()); - assertEpsilonEquals(vx, this.shape.getSecondAxisX()); - assertEpsilonEquals(vy, this.shape.getSecondAxisY()); - assertEpsilonEquals(e2, this.shape.getSecondAxisExtent()); - } - - @Test - public void getSecondAxisExtent() { - assertEpsilonEquals(e2, this.shape.getSecondAxisExtent()); - } - - @Test - public void setSecondAxisExtent() { - this.shape.setSecondAxisExtent(123.456); - assertEpsilonEquals(cx, this.shape.getCenterX()); - assertEpsilonEquals(cy, this.shape.getCenterY()); - assertEpsilonEquals(ux, this.shape.getFirstAxisX()); - assertEpsilonEquals(uy, this.shape.getFirstAxisY()); - assertEpsilonEquals(e1, this.shape.getFirstAxisExtent()); - assertEpsilonEquals(vx, this.shape.getSecondAxisX()); - assertEpsilonEquals(vy, this.shape.getSecondAxisY()); - assertEpsilonEquals(123.456, this.shape.getSecondAxisExtent()); - } - - @Test - public void setFirstAxisDoubleDouble_unitVector() { - Vector2D newU = createVector(123.456, 456.789).toUnitVector(); - this.shape.setFirstAxis(newU.getX(), newU.getY()); - assertEpsilonEquals(cx, this.shape.getCenterX()); - assertEpsilonEquals(cy, this.shape.getCenterY()); - assertEpsilonEquals(newU.getX(), this.shape.getFirstAxisX()); - assertEpsilonEquals(newU.getY(), this.shape.getFirstAxisY()); - assertEpsilonEquals(e1, this.shape.getFirstAxisExtent()); - assertEpsilonEquals(vx, this.shape.getSecondAxisX()); - assertEpsilonEquals(vy, this.shape.getSecondAxisY()); - assertEpsilonEquals(e2, this.shape.getSecondAxisExtent()); - } - - @Test(expected = AssertionError.class) - public void setFirstAxisDoubleDouble_notUnitVector() { - this.shape.setFirstAxis(123.456, 456.789); - } - - @Test - public void setFirstAxisVector2D_unitVector() { - Vector2D newU = createVector(123.456, 456.789).toUnitVector(); - this.shape.setFirstAxis(newU); - assertEpsilonEquals(cx, this.shape.getCenterX()); - assertEpsilonEquals(cy, this.shape.getCenterY()); - assertEpsilonEquals(newU.getX(), this.shape.getFirstAxisX()); - assertEpsilonEquals(newU.getY(), this.shape.getFirstAxisY()); - assertEpsilonEquals(e1, this.shape.getFirstAxisExtent()); - assertEpsilonEquals(vx, this.shape.getSecondAxisX()); - assertEpsilonEquals(vy, this.shape.getSecondAxisY()); - assertEpsilonEquals(e2, this.shape.getSecondAxisExtent()); - } - - @Test(expected = AssertionError.class) - public void setFirstAxisVector2D_notUnitVector() { - this.shape.setFirstAxis(createVector(123.456, 456.789)); - } - - @Test - public void setFirstAxisVector2DDouble_unitVector() { - Vector2D newU = createVector(123.456, 456.789).toUnitVector(); - this.shape.setFirstAxis(newU, 159.753); - assertEpsilonEquals(cx, this.shape.getCenterX()); - assertEpsilonEquals(cy, this.shape.getCenterY()); - assertEpsilonEquals(newU.getX(), this.shape.getFirstAxisX()); - assertEpsilonEquals(newU.getY(), this.shape.getFirstAxisY()); - assertEpsilonEquals(159.753, this.shape.getFirstAxisExtent()); - assertEpsilonEquals(vx, this.shape.getSecondAxisX()); - assertEpsilonEquals(vy, this.shape.getSecondAxisY()); - assertEpsilonEquals(e2, this.shape.getSecondAxisExtent()); - } - - @Test - public void setFirstAxisDoubleDoubleDouble() { - Vector2D newU = createVector(123.456, 456.789).toUnitVector(); - this.shape.setFirstAxis(newU.getX(), newU.getY(), 159.753); - assertEpsilonEquals(cx, this.shape.getCenterX()); - assertEpsilonEquals(cy, this.shape.getCenterY()); - assertEpsilonEquals(newU.getX(), this.shape.getFirstAxisX()); - assertEpsilonEquals(newU.getY(), this.shape.getFirstAxisY()); - assertEpsilonEquals(159.753, this.shape.getFirstAxisExtent()); - assertEpsilonEquals(vx, this.shape.getSecondAxisX()); - assertEpsilonEquals(vy, this.shape.getSecondAxisY()); - assertEpsilonEquals(e2, this.shape.getSecondAxisExtent()); - } - - @Test - public void setSecondAxisDoubleDouble_unitVector() { - Vector2D newV = createVector(123.456, 456.789).toUnitVector(); - this.shape.setSecondAxis(newV.getX(), newV.getY()); - assertEpsilonEquals(cx, this.shape.getCenterX()); - assertEpsilonEquals(cy, this.shape.getCenterY()); - assertEpsilonEquals(ux, this.shape.getFirstAxisX()); - assertEpsilonEquals(uy, this.shape.getFirstAxisY()); - assertEpsilonEquals(e1, this.shape.getFirstAxisExtent()); - assertEpsilonEquals(newV.getX(), this.shape.getSecondAxisX()); - assertEpsilonEquals(newV.getY(), this.shape.getSecondAxisY()); - assertEpsilonEquals(e2, this.shape.getSecondAxisExtent()); - } - - @Test(expected = AssertionError.class) - public void setSecondAxisDoubleDouble_notUnitVector() { - this.shape.setSecondAxis(123.456, 456.789); - } - - @Test - public void setSecondAxisVector2D_unitVector() { - Vector2D newV = createVector(123.456, 456.789).toUnitVector(); - this.shape.setSecondAxis(newV); - assertEpsilonEquals(cx, this.shape.getCenterX()); - assertEpsilonEquals(cy, this.shape.getCenterY()); - assertEpsilonEquals(ux, this.shape.getFirstAxisX()); - assertEpsilonEquals(uy, this.shape.getFirstAxisY()); - assertEpsilonEquals(e1, this.shape.getFirstAxisExtent()); - assertEpsilonEquals(newV.getX(), this.shape.getSecondAxisX()); - assertEpsilonEquals(newV.getY(), this.shape.getSecondAxisY()); - assertEpsilonEquals(e2, this.shape.getSecondAxisExtent()); - } - - @Test(expected = AssertionError.class) - public void setSecondAxisVector2D_notUnitVector() { - this.shape.setSecondAxis(createVector(123.456, 456.789)); - } - - @Test - public void setSecondAxisVector2DDouble() { - Vector2D newV = createVector(123.456, 456.789).toUnitVector(); - this.shape.setSecondAxis(newV, 159.753); - assertEpsilonEquals(cx, this.shape.getCenterX()); - assertEpsilonEquals(cy, this.shape.getCenterY()); - assertEpsilonEquals(ux, this.shape.getFirstAxisX()); - assertEpsilonEquals(uy, this.shape.getFirstAxisY()); - assertEpsilonEquals(e1, this.shape.getFirstAxisExtent()); - assertEpsilonEquals(newV.getX(), this.shape.getSecondAxisX()); - assertEpsilonEquals(newV.getY(), this.shape.getSecondAxisY()); - assertEpsilonEquals(159.753, this.shape.getSecondAxisExtent()); - } - - @Test - public void setSecondAxisDoubleDoubleDouble() { - Vector2D newV = createVector(123.456, 456.789).toUnitVector(); - this.shape.setSecondAxis(newV.getX(), newV.getY(), 159.753); - assertEpsilonEquals(cx, this.shape.getCenterX()); - assertEpsilonEquals(cy, this.shape.getCenterY()); - assertEpsilonEquals(ux, this.shape.getFirstAxisX()); - assertEpsilonEquals(uy, this.shape.getFirstAxisY()); - assertEpsilonEquals(e1, this.shape.getFirstAxisExtent()); - assertEpsilonEquals(newV.getX(), this.shape.getSecondAxisX()); - assertEpsilonEquals(newV.getY(), this.shape.getSecondAxisY()); - assertEpsilonEquals(159.753, this.shape.getSecondAxisExtent()); - } - - @Test - public void setDoubleDoubleDoubleDoubleDoubleDoubleDoubleDouble() { - Vector2D newU = createVector(-456.789, 159.753).toUnitVector(); - Vector2D newV = createVector(123.456, 456.789).toUnitVector(); - this.shape.set(-6, -4, newU.getX(), newU.getY(), 147.369, newV.getX(), newV.getY(), 159.753); - assertEpsilonEquals(-6, this.shape.getCenterX()); - assertEpsilonEquals(-4, this.shape.getCenterY()); - assertEpsilonEquals(newU.getX(), this.shape.getFirstAxisX()); - assertEpsilonEquals(newU.getY(), this.shape.getFirstAxisY()); - assertEpsilonEquals(147.369, this.shape.getFirstAxisExtent()); - assertEpsilonEquals(newV.getX(), this.shape.getSecondAxisX()); - assertEpsilonEquals(newV.getY(), this.shape.getSecondAxisY()); - assertEpsilonEquals(159.753, this.shape.getSecondAxisExtent()); - } - - @Test - public void setPoint2DVector2DDoubleVector2DDouble() { - Vector2D newU = createVector(-456.789, 159.753).toUnitVector(); - Vector2D newV = createVector(123.456, 456.789).toUnitVector(); - this.shape.set(createPoint(-6, -4), newU, 147.369, newV, 159.753); - assertEpsilonEquals(-6, this.shape.getCenterX()); - assertEpsilonEquals(-4, this.shape.getCenterY()); - assertEpsilonEquals(newU.getX(), this.shape.getFirstAxisX()); - assertEpsilonEquals(newU.getY(), this.shape.getFirstAxisY()); - assertEpsilonEquals(147.369, this.shape.getFirstAxisExtent()); - assertEpsilonEquals(newV.getX(), this.shape.getSecondAxisX()); - assertEpsilonEquals(newV.getY(), this.shape.getSecondAxisY()); - assertEpsilonEquals(159.753, this.shape.getSecondAxisExtent()); - } - - @Test - public void setFromPointCloudIterable() { - double obrux = 0.8944271909999159; - double obruy = -0.4472135954999579; - double obre1 = 13.99999; - double obrvx = 0.4472135954999579; - double obrvy = 0.8944271909999159; - double obre2 = 12.99999; - - this.shape.setFromPointCloud((List) Arrays.asList( - createPoint(11.7082, -0.94427), createPoint(16.18034, 8), - createPoint(-1.7082, 16.94427), createPoint(-6.18034, 8))); - - assertEpsilonEquals(5, this.shape.getCenterX()); - assertEpsilonEquals(8, this.shape.getCenterY()); - assertEpsilonEquals(obrux, this.shape.getFirstAxisX()); - assertEpsilonEquals(obruy, this.shape.getFirstAxisY()); - assertEpsilonEquals(10, this.shape.getFirstAxisExtent()); - assertEpsilonEquals(obrvx, this.shape.getSecondAxisX()); - assertEpsilonEquals(obrvy, this.shape.getSecondAxisY()); - assertEpsilonEquals(5, this.shape.getSecondAxisExtent()); - } - - @Test - public void setFromPointCloudPoint2DArray() { - double obrux = 0.8944271909999159; - double obruy = -0.4472135954999579; - double obre1 = 13.99999; - double obrvx = 0.4472135954999579; - double obrvy = 0.8944271909999159; - double obre2 = 12.99999; - - this.shape.setFromPointCloud( - createPoint(11.7082, -0.94427), createPoint(16.18034, 8), - createPoint(-1.7082, 16.94427), createPoint(-6.18034, 8)); - - assertEpsilonEquals(5, this.shape.getCenterX()); - assertEpsilonEquals(8, this.shape.getCenterY()); - assertEpsilonEquals(obrux, this.shape.getFirstAxisX()); - assertEpsilonEquals(obruy, this.shape.getFirstAxisY()); - assertEpsilonEquals(10, this.shape.getFirstAxisExtent()); - assertEpsilonEquals(obrvx, this.shape.getSecondAxisX()); - assertEpsilonEquals(obrvy, this.shape.getSecondAxisY()); - assertEpsilonEquals(5, this.shape.getSecondAxisExtent()); - } - - @Override - public void intersectsCircle2afp() { - assertFalse(this.shape.intersects(createCircle(.5, .5, .5))); - assertFalse(this.shape.intersects(createCircle(.5, 1.5, .5))); - assertFalse(this.shape.intersects(createCircle(.5, 2.5, .5))); - assertTrue(this.shape.intersects(createCircle(.5, 3.5, .5))); - assertTrue(this.shape.intersects(createCircle(4.5, 3.5, .5))); - assertFalse(this.shape.intersects(createCircle(10, -7, .5))); - assertFalse(this.shape.intersects(createCircle(10.1, -7, .5))); - assertTrue(this.shape.intersects(createCircle(10.2, -7, .5))); - assertTrue(this.shape.intersects(createCircle(10, -1, 5))); - } - - @Override - public void intersectsEllipse2afp() { - assertFalse(this.shape.intersects(createEllipse(0, 0, 2, 1))); - assertFalse(this.shape.intersects(createEllipse(0, 1, 2, 1))); - assertTrue(this.shape.intersects(createEllipse(0, 2, 2, 1))); - assertTrue(this.shape.intersects(createEllipse(0, 3, 2, 1))); - assertTrue(this.shape.intersects(createEllipse(0, 4, 2, 1))); - assertTrue(this.shape.intersects(createEllipse(1, 3, 2, 1))); - assertTrue(this.shape.intersects(createEllipse(5, 5, 2, 1))); - assertFalse(this.shape.intersects(createEllipse(0.1, 1, 2, 1))); - assertFalse(this.shape.intersects(createEllipse(0.2, 1, 2, 1))); - assertTrue(this.shape.intersects(createEllipse(0.3, 1, 2, 1))); - assertTrue(this.shape.intersects(createEllipse(0.4, 1, 2, 1))); - assertFalse(this.shape.intersects(createEllipse(-7, 7.5, 2, 1))); - } - - @Override - public void intersectsSegment2afp() { - assertFalse(this.shape.intersects(createSegment(0, 0, 1, 1))); - assertTrue(this.shape.intersects(createSegment(5, 5, 4, 6))); - assertTrue(this.shape.intersects(createSegment(2, -2, 5, 0))); - assertFalse(this.shape.intersects(createSegment(-20, -5, -10, 6))); - assertFalse(this.shape.intersects(createSegment(-5, 0, -10, 16))); - assertTrue(this.shape.intersects(createSegment(-10, 1, 10, 20))); - } - - @Override - public void intersectsPath2afp() { - Path2afp path = createPath(); - path.moveTo(-15, 2); - path.lineTo(6, -9); - path.lineTo(19, -9); - path.lineTo(20, 26); - path.lineTo(-6, 30); - assertFalse(this.shape.intersects(path)); - path.closePath(); - assertTrue(this.shape.intersects(path)); - } - - @Override - public void intersectsPathIterator2afp() { - Path2afp path = createPath(); - path.moveTo(-15, 2); - path.lineTo(6, -9); - path.lineTo(19, -9); - path.lineTo(20, 26); - path.lineTo(-6, 30); - assertFalse(this.shape.intersects(path.getPathIterator())); - path.closePath(); - assertTrue(this.shape.intersects(path.getPathIterator())); - } - - @Override - public void intersectsTriangle2afp() { - assertTrue(this.shape.intersects(createTriangle(-5, 15, -3, 16, -8, 19))); - assertTrue(this.shape.intersects(createTriangle(-5, 15, -8, 19, -3, 16))); - assertFalse(this.shape.intersects(createTriangle(0, -5, 2, -4, -3, -1))); - assertFalse(this.shape.intersects(createTriangle(0, -5, -3, -1, 2, -4))); - assertFalse(this.shape.intersects(createTriangle(20, 0, 22, 1, 17, 4))); - assertFalse(this.shape.intersects(createTriangle(20, 0, 17, 4, 22, 1))); - assertFalse(this.shape.intersects(createTriangle(17.18034, 9, 19.18034, 10, 14.18034, 13))); - assertFalse(this.shape.intersects(createTriangle(17.18034, 9, 14.18034, 13, 19.18034, 10))); - assertTrue(this.shape.intersects(createTriangle(0, 10, 2, 11, -3, 14))); - assertTrue(this.shape.intersects(createTriangle(0, 10, -3, 14, 2, 11))); - assertTrue(this.shape.intersects(createTriangle(0, 20, 2, 21, -3, 24))); - } - - @Override - public void intersectsRectangle2afp() { - assertFalse(this.shape.intersects(createRectangle(0, 0, 1, 1))); - assertTrue(this.shape.intersects(createRectangle(0, 2, 1, 1))); - assertTrue(this.shape.intersects(createRectangle(-5.5, 8.5, 1, 1))); - assertFalse(this.shape.intersects(createRectangle(-6, 16, 1, 1))); - assertFalse(this.shape.intersects(createRectangle(146, 16, 1, 1))); - assertTrue(this.shape.intersects(createRectangle(12, 14, 1, 1))); - assertTrue(this.shape.intersects(createRectangle(0, 8, 1, 1))); - assertTrue(this.shape.intersects(createRectangle(10, -1, 1, 1))); - assertTrue(this.shape.intersects(createRectangle(-15, -10, 35, 40))); - } - - @Override - public void intersectsParallelogram2afp() { - double ux2 = -0.9284766908852592; - double uy2 = 0.3713906763541037; - double et1 = 5; - double vx2 = 0.3713906763541037; - double vy2 = 0.9284766908852592; - double et2 = 3; - assertFalse(this.shape.intersects(createParallelogram(-10, 0, - ux2, uy2, et1, vx2, vy2, et2))); - assertFalse(this.shape.intersects(createParallelogram(-15, 25, - ux2, uy2, et1, vx2, vy2, et2))); - assertFalse(this.shape.intersects(createParallelogram(2, -6, - ux2, uy2, et1, vx2, vy2, et2))); - assertFalse(this.shape.intersects(createParallelogram(2, -5, - ux2, uy2, et1, vx2, vy2, et2))); - assertTrue(this.shape.intersects(createParallelogram(2, -4, - ux2, uy2, et1, vx2, vy2, et2))); - assertTrue(this.shape.intersects(createParallelogram(pEx, pEy, - ux2, uy2, et1, vx2, vy2, et2))); - assertTrue(this.shape.intersects(createParallelogram(6, 6, - ux2, uy2, et1, vx2, vy2, et2))); - assertTrue(this.shape.intersects(createParallelogram(6, 6, - ux2, uy2, 10 * et1, vx2, vy2, 10 * et2))); - } - - @Override - public void intersectsRoundRectangle2afp() { - assertFalse(this.shape.intersects(createRoundRectangle(0, 0, 1, 1, .1, .05))); - assertTrue(this.shape.intersects(createRoundRectangle(0, 2, 1, 1, .1, .05))); - assertTrue(this.shape.intersects(createRoundRectangle(-5.5, 8.5, 1, 1, .1, .05))); - assertFalse(this.shape.intersects(createRoundRectangle(-6, 16, 1, 1, .1, .05))); - assertFalse(this.shape.intersects(createRoundRectangle(146, 16, 1, 1, .1, .05))); - assertTrue(this.shape.intersects(createRoundRectangle(12, 14, 1, 1, .1, .05))); - assertTrue(this.shape.intersects(createRoundRectangle(0, 8, 1, 1, .1, .05))); - assertTrue(this.shape.intersects(createRoundRectangle(10, -1, 1, 1, .1, .05))); - assertTrue(this.shape.intersects(createRoundRectangle(-15, -10, 35, 40, .1, .05))); - assertFalse(this.shape.intersects(createRoundRectangle(-4.79634, 14.50886, 1, 1, .1, .05))); - } - - @Override - public void intersectsOrientedRectangle2afp() { - OrientedRectangle2afp rectangle = createOrientedRectangle( - 6, 9, - 0.894427190999916, -0.447213595499958, 13.999990000000002, - 12.999989999999997); - double ux2 = 0.55914166827779; - double uy2 = 0.829072128825671; - double et1 = 10; - double vx2 = -0.989660599000356; - double vy2 = -0.143429072318889; - double et2 = 15; - assertFalse(createParallelogram( - -20, -20, ux2, uy2, et1, vx2, vy2, et2).intersects(rectangle)); - assertFalse(createParallelogram( - -40, 20, ux2, uy2, et1, vx2, vy2, et2).intersects(rectangle)); - assertTrue(createParallelogram( - -20, -10, ux2, uy2, et1, vx2, vy2, et2).intersects(rectangle)); - assertTrue(createParallelogram( - 10, -10, ux2, uy2, et1, vx2, vy2, et2).intersects(rectangle)); - assertTrue(createParallelogram( - 5, 5, ux2, uy2, et1, vx2, vy2, et2).intersects(rectangle)); - } - - @Override - public void intersectsShape2D() { - assertTrue(this.shape.intersects((Shape2D) createCircle(.5, 3.5, .5))); - assertTrue(this.shape.intersects((Shape2D) createRectangle(12, 14, 1, 1))); - } - - @Override - public void operator_addVector2D() { - this.shape.operator_add(createVector(123.456, 789.123)); - assertEpsilonEquals(cx + 123.456, this.shape.getCenterX()); - assertEpsilonEquals(cy + 789.123, this.shape.getCenterY()); - assertEpsilonEquals(ux, this.shape.getFirstAxisX()); - assertEpsilonEquals(uy, this.shape.getFirstAxisY()); - assertEpsilonEquals(e1, this.shape.getFirstAxisExtent()); - assertEpsilonEquals(vx, this.shape.getSecondAxisX()); - assertEpsilonEquals(vy, this.shape.getSecondAxisY()); - assertEpsilonEquals(e2, this.shape.getSecondAxisExtent()); - } - - @Override - public void operator_plusVector2D() { - T shape = this.shape.operator_plus(createVector(123.456, 789.123)); - assertEpsilonEquals(cx + 123.456, shape.getCenterX()); - assertEpsilonEquals(cy + 789.123, shape.getCenterY()); - assertEpsilonEquals(ux, shape.getFirstAxisX()); - assertEpsilonEquals(uy, shape.getFirstAxisY()); - assertEpsilonEquals(e1, shape.getFirstAxisExtent()); - assertEpsilonEquals(vx, shape.getSecondAxisX()); - assertEpsilonEquals(vy, shape.getSecondAxisY()); - assertEpsilonEquals(e2, shape.getSecondAxisExtent()); - } - - @Override - public void operator_removeVector2D() { - this.shape.operator_remove(createVector(123.456, 789.123)); - assertEpsilonEquals(cx - 123.456, this.shape.getCenterX()); - assertEpsilonEquals(cy - 789.123, this.shape.getCenterY()); - assertEpsilonEquals(ux, this.shape.getFirstAxisX()); - assertEpsilonEquals(uy, this.shape.getFirstAxisY()); - assertEpsilonEquals(e1, this.shape.getFirstAxisExtent()); - assertEpsilonEquals(vx, this.shape.getSecondAxisX()); - assertEpsilonEquals(vy, this.shape.getSecondAxisY()); - assertEpsilonEquals(e2, this.shape.getSecondAxisExtent()); - } - - @Override - public void operator_minusVector2D() { - T shape = this.shape.operator_minus(createVector(123.456, 789.123)); - assertEpsilonEquals(cx - 123.456, shape.getCenterX()); - assertEpsilonEquals(cy - 789.123, shape.getCenterY()); - assertEpsilonEquals(ux, shape.getFirstAxisX()); - assertEpsilonEquals(uy, shape.getFirstAxisY()); - assertEpsilonEquals(e1, shape.getFirstAxisExtent()); - assertEpsilonEquals(vx, shape.getSecondAxisX()); - assertEpsilonEquals(vy, shape.getSecondAxisY()); - assertEpsilonEquals(e2, shape.getSecondAxisExtent()); - } - - @Override - public void operator_multiplyTransform2D() { - PathIterator2afp pi = this.shape.operator_multiply(null).getPathIterator(); - assertElement(pi, PathElementType.MOVE_TO, pGx, pGy); - assertElement(pi, PathElementType.LINE_TO, pHx, pHy); - assertElement(pi, PathElementType.LINE_TO, pEx, pEy); - assertElement(pi, PathElementType.LINE_TO, pFx, pFy); - assertElement(pi, PathElementType.CLOSE, pGx, pGy); - assertNoElement(pi); - - Transform2D transform; - - transform = new Transform2D(); - pi = this.shape.operator_multiply(transform).getPathIterator(); - assertElement(pi, PathElementType.MOVE_TO, pGx, pGy); - assertElement(pi, PathElementType.LINE_TO, pHx, pHy); - assertElement(pi, PathElementType.LINE_TO, pEx, pEy); - assertElement(pi, PathElementType.LINE_TO, pFx, pFy); - assertElement(pi, PathElementType.CLOSE, pGx, pGy); - assertNoElement(pi); - - transform = new Transform2D(); - transform.setTranslation(18, -45); - pi = this.shape.operator_multiply(transform).getPathIterator(); - assertElement(pi, PathElementType.MOVE_TO, pGx + 18, pGy - 45); - assertElement(pi, PathElementType.LINE_TO, pHx + 18, pHy - 45); - assertElement(pi, PathElementType.LINE_TO, pEx + 18, pEy - 45); - assertElement(pi, PathElementType.LINE_TO, pFx + 18, pFy - 45); - assertElement(pi, PathElementType.CLOSE, pGx + 18, pGy - 45); - assertNoElement(pi); - } - - @Override - public void operator_andPoint2D() { - assertFalse(this.shape.operator_and(createPoint(0, 0))); - assertFalse(this.shape.operator_and(createPoint(-20, 0))); - assertTrue(this.shape.operator_and(createPoint(12, -4))); - assertTrue(this.shape.operator_and(createPoint(14, 0))); - assertFalse(this.shape.operator_and(createPoint(15, 0))); - assertFalse(this.shape.operator_and(createPoint(20, 8))); - assertTrue(this.shape.operator_and(createPoint(8, 16))); - assertFalse(this.shape.operator_and(createPoint(-4, 20))); - assertFalse(this.shape.operator_and(createPoint(-5, 12))); - assertTrue(this.shape.operator_and(createPoint(0, 6))); - assertTrue(this.shape.operator_and(createPoint(0, 7))); - assertTrue(this.shape.operator_and(createPoint(0, 8))); - assertTrue(this.shape.operator_and(createPoint(0, 9))); - assertTrue(this.shape.operator_and(createPoint(0, 10))); - assertFalse(this.shape.operator_and(createPoint(0, 27))); - assertTrue(this.shape.operator_and(createPoint(cx, cy))); - assertTrue(this.shape.operator_and(createPoint( 16, 8))); - } - - @Override - public void operator_andShape2D() { - assertTrue(this.shape.operator_and(createCircle(.5, 3.5, .5))); - assertTrue(this.shape.operator_and(createRectangle(12, 14, 1, 1))); - } - - @Override - public void operator_upToPoint2D() { - assertEpsilonEquals(14.81966, this.shape.operator_upTo(createPoint(-20, 9))); - assertEpsilonEquals(2.7009, this.shape.operator_upTo(createPoint(0, 0))); - assertEpsilonEquals(6.23644, this.shape.operator_upTo(createPoint(5, -10))); - assertEpsilonEquals(11.1863, this.shape.operator_upTo(createPoint(14, -20))); - assertEpsilonEquals(2.25040, this.shape.operator_upTo(createPoint(-6, 15))); - assertEpsilonEquals(0, this.shape.operator_upTo(createPoint(0, 10))); - assertEpsilonEquals(0, this.shape.operator_upTo(createPoint(10, 0))); - assertEpsilonEquals(1.03772, this.shape.operator_upTo(createPoint(15, -4))); - assertEpsilonEquals(3.70561, this.shape.operator_upTo(createPoint(-5, 25))); - assertEpsilonEquals(0, this.shape.operator_upTo(createPoint(0, 20))); - assertEpsilonEquals(0, this.shape.operator_upTo(createPoint(10, 10))); - assertEpsilonEquals(4.91829, this.shape.operator_upTo(createPoint(20, 0))); - assertEpsilonEquals(8.42901, this.shape.operator_upTo(createPoint(-3, 35))); - assertEpsilonEquals(9.91864, this.shape.operator_upTo(createPoint(5, 35))); - assertEpsilonEquals(6.23644, this.shape.operator_upTo(createPoint(20, 15))); - assertEpsilonEquals(17.8477, this.shape.operator_upTo(createPoint(35, 10))); - assertEpsilonEquals(7.59135, this.shape.operator_upTo(createPoint(-8, 29))); - } - - @Test - public void isCCW() { - assertTrue(this.shape.isCCW()); - assertTrue(createParallelogram(cx, cy, ux, uy, e1, vx, vy, e2).isCCW()); - assertTrue(createParallelogram( - 4.7, 15, - 0.12403, 0.99228, 18.02776, - -0.44721, 0.89443, 20).isCCW()); - assertTrue(createParallelogram( - -10, -3, - -.8944271909999159, .4472135954999579, 2, - .5547001962252290, -.8320502943378436, 1).isCCW()); - assertFalse(createParallelogram( - -10, 7, - -0.9863939238321437, 0.1643989873053573, 1, - 0.9998000599800071, 0.01999600119960014, 2).isCCW()); - assertFalse(createParallelogram( - 0, -6, - -0.9863939238321437, 0.1643989873053573, 1, - 0.9998000599800071, 0.01999600119960014, 2).isCCW()); - } - - @Test - @Ignore - public void getDistanceSquaredRectangle2afp() { - throw new RuntimeException(); - } - - @Test - @Ignore - public void getDistanceSquaredMultiShape2afp() { - throw new RuntimeException(); - } - - @Test - @Ignore - public void getDistanceSquaredCircle2afp() { - throw new RuntimeException(); - } - - @Test - @Ignore - public void getDistanceSquaredTriangle2afp() { - throw new RuntimeException(); - } - - @Test - @Ignore - public void getDistanceSquaredEllipse2afp() { - throw new RuntimeException(); - } - - @Test - @Ignore - public void getDistanceSquaredSegment2afp() { - throw new RuntimeException(); - } - - @Test - @Ignore - public void getDistanceSquaredPath2afp() { - throw new RuntimeException(); - } - - @Test - @Ignore - public void getDistanceSquaredOrientedRectangle2afp() { - throw new RuntimeException(); - } - - @Test - @Ignore - public void getDistanceSquaredParallelogram2afp() { - throw new RuntimeException(); - } - - @Test - @Ignore - public void getDistanceSquaredRoundRectangle2afp() { - throw new RuntimeException(); - } - - @Test - @Ignore - public void getClosestPointToEllipse2afp() { - throw new RuntimeException(); - } - - @Test - @Ignore - public void getClosestPointToCircle2afp() { - throw new RuntimeException(); - } - - @Test - @Ignore - public void getClosestPointToRectangle2afp() { - throw new RuntimeException(); - } - - @Test - @Ignore - public void getClosestPointToSegment2afp() { - throw new RuntimeException(); - } - - @Test - @Ignore - public void getClosestPointToTriangle2afp() { - throw new RuntimeException(); - } - - @Test - @Ignore - public void getClosestPointToPath2afp() { - throw new RuntimeException(); - } - - @Test - @Ignore - public void getClosestPointToOrientedRectangle2afp() { - throw new RuntimeException(); - } - - @Test - @Ignore - public void getClosestPointToParallelogram2afp() { - throw new RuntimeException(); - } - - @Test - @Ignore - public void getClosestPointToRoundRectangle2afp() { - throw new RuntimeException(); - } - - @Test - @Ignore - public void getClosestPointToMultiShape2afp() { - throw new RuntimeException(); - } - + protected final double cx = 6; + protected final double cy = 9; + protected final double ux = 2.425356250363330e-01; + protected final double uy = 9.701425001453320e-01; + protected final double e1 = 9.219544457292887; + protected final double vx = -7.071067811865475e-01; + protected final double vy = 7.071067811865475e-01; + protected final double e2 = 1.264911064067352e+01; + + // Points' names are in the ggb diagram + protected final double pEx = 12.7082; + protected final double pEy = -8.88854; + protected final double pFx = 17.18034; + protected final double pFy = 9; + protected final double pGx = -0.7082; + protected final double pGy = 26.88854; + protected final double pHx = -5.18034; + protected final double pHy = 9; + + @Override + protected final T createShape() { + return (T) createParallelogram(cx, cy, ux, uy, e1, vx, vy, e2); + } + + @Test + public void staticComputeOrthogonalAxis() { + double obrux = 0.8944271909999159; + double obruy = -0.4472135954999579; + double obre1 = 13.99999; + double obrvx = 0.4472135954999579; + double obrvy = 0.8944271909999159; + double obre2 = 12.99999; + List points = Arrays.asList( + createPoint(11.7082, -0.94427), createPoint(16.18034, 8), + createPoint(-1.7082, 16.94427), createPoint(-6.18034, 8)); + Vector2D R, S; + R = createVector(Double.NaN, Double.NaN); + S = createVector(Double.NaN, Double.NaN); + Parallelogram2afp.computeOrthogonalAxes(points, R, S); + assertEpsilonEquals(obrux, R.getX()); + assertEpsilonEquals(obruy, R.getY()); + assertEpsilonEquals(obrvx, S.getX()); + assertEpsilonEquals(obrvy, S.getY()); + } + + @Test + public void staticProjectVectorOnParallelogramRAxis() { + assertEpsilonEquals(-e1, Parallelogram2afp.projectVectorOnParallelogramRAxis(ux, uy, vx, vy, pEx - cx, pEy - cy)); + assertEpsilonEquals(e1, Parallelogram2afp.projectVectorOnParallelogramRAxis(ux, uy, vx, vy, pFx - cx, pFy - cy)); + assertEpsilonEquals(e1, Parallelogram2afp.projectVectorOnParallelogramRAxis(ux, uy, vx, vy, pGx - cx, pGy - cy)); + assertEpsilonEquals(-e1, Parallelogram2afp.projectVectorOnParallelogramRAxis(ux, uy, vx, vy, pHx - cx, pHy - cy)); + assertEpsilonEquals(-12.36932, Parallelogram2afp.projectVectorOnParallelogramRAxis(ux, uy, vx, vy, -cx, -cy)); + } + + @Test + public void staticProjectVectorOnParallelogramSAxis() { + assertEpsilonEquals(-e2, Parallelogram2afp.projectVectorOnParallelogramSAxis(ux, uy, vx, vy, pEx - cx, pEy - cy)); + assertEpsilonEquals(-e2, Parallelogram2afp.projectVectorOnParallelogramSAxis(ux, uy, vx, vy, pFx - cx, pFy - cy)); + assertEpsilonEquals(e2, Parallelogram2afp.projectVectorOnParallelogramSAxis(ux, uy, vx, vy, pGx - cx, pGy - cy)); + assertEpsilonEquals(e2, Parallelogram2afp.projectVectorOnParallelogramSAxis(ux, uy, vx, vy, pHx - cx, pHy - cy)); + assertEpsilonEquals(4.24264, Parallelogram2afp.projectVectorOnParallelogramSAxis(ux, uy, vx, vy, -cx, -cy)); + } + + @Test + public void staticComputeCenterExtents() { + List points = Arrays.asList( + createPoint(pEx, pEy), createPoint(pGx, pGy), + createPoint(pFx, pFy), createPoint(pEx, pEy)); + Vector2D R, S; + Point2D center; + Tuple2D extents; + R = createVector(ux, uy); + S = createVector(vx, vy); + center = createPoint(Double.NaN, Double.NaN); + extents = createVector(Double.NaN, Double.NaN); + Parallelogram2afp.computeCenterExtents(points, R, S, center, extents); + assertEpsilonEquals(cx, center.getX()); + assertEpsilonEquals(cy, center.getY()); + assertEpsilonEquals(e1, extents.getX()); + assertEpsilonEquals(e2, extents.getY()); + } + + @Test + public void staticComputeClosestPoint() { + Point2D closest; + + closest = createPoint(Double.NaN, Double.NaN); + Parallelogram2afp.computeClosestPoint( + -20, 9, + cx, cy, ux, uy, e1, vx, vy, e2, + closest); + assertFpPointEquals(pHx, pHy, closest); + + closest = createPoint(Double.NaN, Double.NaN); + Parallelogram2afp.computeClosestPoint( + 0, 0, + cx, cy, ux, uy, e1, vx, vy, e2, + closest); + assertFpPointEquals(1.90983, 1.90983, closest); + + closest = createPoint(Double.NaN, Double.NaN); + Parallelogram2afp.computeClosestPoint( + 5, -10, + cx, cy, ux, uy, e1, vx, vy, e2, + closest); + assertFpPointEquals(9.40983, -5.59017, closest); + + closest = createPoint(Double.NaN, Double.NaN); + Parallelogram2afp.computeClosestPoint( + 14, -20, + cx, cy, ux, uy, e1, vx, vy, e2, + closest); + assertFpPointEquals(pEx, pEy, closest); + + closest = createPoint(Double.NaN, Double.NaN); + Parallelogram2afp.computeClosestPoint( + -6, 15, + cx, cy, ux, uy, e1, vx, vy, e2, + closest); + assertFpPointEquals(-3.81679, 14.4542, closest); + + closest = createPoint(Double.NaN, Double.NaN); + Parallelogram2afp.computeClosestPoint( + 0, 10, + cx, cy, ux, uy, e1, vx, vy, e2, + closest); + assertFpPointEquals(0, 10, closest); + + closest = createPoint(Double.NaN, Double.NaN); + Parallelogram2afp.computeClosestPoint( + 10, 0, + cx, cy, ux, uy, e1, vx, vy, e2, + closest); + assertFpPointEquals(10, 0, closest); + + closest = createPoint(Double.NaN, Double.NaN); + Parallelogram2afp.computeClosestPoint( + 15, -4, + cx, cy, ux, uy, e1, vx, vy, e2, + closest); + assertFpPointEquals(13.99326, -3.74832, closest); + + closest = createPoint(Double.NaN, Double.NaN); + Parallelogram2afp.computeClosestPoint( + -5, 25, + cx, cy, ux, uy, e1, vx, vy, e2, + closest); + assertFpPointEquals(-1.40503, 24.10126, closest); + + closest = createPoint(Double.NaN, Double.NaN); + Parallelogram2afp.computeClosestPoint( + 0, 20, + cx, cy, ux, uy, e1, vx, vy, e2, + closest); + assertFpPointEquals(0, 20, closest); + + closest = createPoint(Double.NaN, Double.NaN); + Parallelogram2afp.computeClosestPoint( + 10, 10, + cx, cy, ux, uy, e1, vx, vy, e2, + closest); + assertFpPointEquals(10, 10, closest); + + closest = createPoint(Double.NaN, Double.NaN); + Parallelogram2afp.computeClosestPoint( + 20, 0, + cx, cy, ux, uy, e1, vx, vy, e2, + closest); + assertFpPointEquals(15.22856, 1.19286, closest); + + closest = createPoint(Double.NaN, Double.NaN); + Parallelogram2afp.computeClosestPoint( + -3, 35, + cx, cy, ux, uy, e1, vx, vy, e2, + closest); + assertFpPointEquals(pGx, pGy, closest); + + closest = createPoint(Double.NaN, Double.NaN); + Parallelogram2afp.computeClosestPoint( + 5, 35, + cx, cy, ux, uy, e1, vx, vy, e2, + closest); + assertFpPointEquals(pGx, pGy, closest); + + closest = createPoint(Double.NaN, Double.NaN); + Parallelogram2afp.computeClosestPoint( + 20, 15, + cx, cy, ux, uy, e1, vx, vy, e2, + closest); + assertFpPointEquals(15.59017, 10.59017, closest); + + closest = createPoint(Double.NaN, Double.NaN); + Parallelogram2afp.computeClosestPoint( + 35, 10, + cx, cy, ux, uy, e1, vx, vy, e2, + closest); + assertFpPointEquals(pFx, pFy, closest); + + closest = createPoint(Double.NaN, Double.NaN); + Parallelogram2afp.computeClosestPoint( + -8, 29, + cx, cy, ux, uy, e1, vx, vy, e2, + closest); + assertFpPointEquals(pGx, pGy, closest); + + closest = createPoint(Double.NaN, Double.NaN); + Parallelogram2afp.computeClosestPoint(0, 0, + 4.7, 15, + 0.12403, 0.99228, + 18.02776, + -0.44721, 0.89443, + 20, + closest); + assertFpPointEquals(0.81573, 0.40786, closest); + + // In triangle.ggb + closest = createPoint(Double.NaN, Double.NaN); + Parallelogram2afp.computeClosestPoint(-5.2964, 3.19501, + -10, 7, + -0.9863939238321437, 0.1643989873053573, + 1, + 0.9998000599800071, 0.01999600119960014, + 2, + closest); + assertFpPointEquals(-7.01401, 6.87559, closest); + + // In triangle.ggb + closest = createPoint(Double.NaN, Double.NaN); + Parallelogram2afp.computeClosestPoint(-1, -2, + 0, -6, + -0.9863939238321437, 0.1643989873053573, + 1, + 0.9998000599800071, 0.01999600119960014, + 2, + closest); + assertFpPointEquals(-0.92331, -5.83434, closest); + + // In segment.ggb + closest = createPoint(Double.NaN, Double.NaN); + Parallelogram2afp.computeClosestPoint(0, 0, + -10, -3, + -.8944271909999159, .4472135954999579, + 2, + .5547001962252290, -.8320502943378436, + 1, + closest); + assertFpPointEquals(-7.65645, -4.72648, closest); + } + + @Test + public void staticComputeFarthestPoint() { + Point2D farthest; + + farthest = createPoint(Double.NaN, Double.NaN); + Parallelogram2afp.computeFarthestPoint( + -20, 9, + cx, cy, ux, uy, e1, vx, vy, e2, + farthest); + assertFpPointEquals(pEx, pEy, farthest); + + farthest = createPoint(Double.NaN, Double.NaN); + Parallelogram2afp.computeFarthestPoint( + 0, 0, + cx, cy, ux, uy, e1, vx, vy, e2, + farthest); + assertFpPointEquals(pGx, pGy, farthest); + + farthest = createPoint(Double.NaN, Double.NaN); + Parallelogram2afp.computeFarthestPoint( + 5, -10, + cx, cy, ux, uy, e1, vx, vy, e2, + farthest); + assertFpPointEquals(pGx, pGy, farthest); + + farthest = createPoint(Double.NaN, Double.NaN); + Parallelogram2afp.computeFarthestPoint( + 14, -20, + cx, cy, ux, uy, e1, vx, vy, e2, + farthest); + assertFpPointEquals(pGx, pGy, farthest); + + farthest = createPoint(Double.NaN, Double.NaN); + Parallelogram2afp.computeFarthestPoint( + -6, 15, + cx, cy, ux, uy, e1, vx, vy, e2, + farthest); + assertFpPointEquals(pEx, pEy, farthest); + + farthest = createPoint(Double.NaN, Double.NaN); + Parallelogram2afp.computeFarthestPoint( + 0, 10, + cx, cy, ux, uy, e1, vx, vy, e2, + farthest); + assertFpPointEquals(pEx, pEy, farthest); + + farthest = createPoint(Double.NaN, Double.NaN); + Parallelogram2afp.computeFarthestPoint( + 10, 0, + cx, cy, ux, uy, e1, vx, vy, e2, + farthest); + assertFpPointEquals(pGx, pGy, farthest); + + farthest = createPoint(Double.NaN, Double.NaN); + Parallelogram2afp.computeFarthestPoint( + 15, -4, + cx, cy, ux, uy, e1, vx, vy, e2, + farthest); + assertFpPointEquals(pGx, pGy, farthest); + + farthest = createPoint(Double.NaN, Double.NaN); + Parallelogram2afp.computeFarthestPoint( + -5, 25, + cx, cy, ux, uy, e1, vx, vy, e2, + farthest); + assertFpPointEquals(pEx, pEy, farthest); + + farthest = createPoint(Double.NaN, Double.NaN); + Parallelogram2afp.computeFarthestPoint( + 0, 20, + cx, cy, ux, uy, e1, vx, vy, e2, + farthest); + assertFpPointEquals(pEx, pEy, farthest); + + farthest = createPoint(Double.NaN, Double.NaN); + Parallelogram2afp.computeFarthestPoint( + 10, 10, + cx, cy, ux, uy, e1, vx, vy, e2, + farthest); + assertFpPointEquals(pGx, pGy, farthest); + + farthest = createPoint(Double.NaN, Double.NaN); + Parallelogram2afp.computeFarthestPoint( + 20, 0, + cx, cy, ux, uy, e1, vx, vy, e2, + farthest); + assertFpPointEquals(pGx, pGy, farthest); + + farthest = createPoint(Double.NaN, Double.NaN); + Parallelogram2afp.computeFarthestPoint( + -3, 35, + cx, cy, ux, uy, e1, vx, vy, e2, + farthest); + assertFpPointEquals(pEx, pEy, farthest); + + farthest = createPoint(Double.NaN, Double.NaN); + Parallelogram2afp.computeFarthestPoint( + 5, 35, + cx, cy, ux, uy, e1, vx, vy, e2, + farthest); + assertFpPointEquals(pEx, pEy, farthest); + + farthest = createPoint(Double.NaN, Double.NaN); + Parallelogram2afp.computeFarthestPoint( + 20, 15, + cx, cy, ux, uy, e1, vx, vy, e2, + farthest); + assertFpPointEquals(pHx, pHy, farthest); + + farthest = createPoint(Double.NaN, Double.NaN); + Parallelogram2afp.computeFarthestPoint( + 35, 10, + cx, cy, ux, uy, e1, vx, vy, e2, + farthest); + assertFpPointEquals(pHx, pHy, farthest); + + farthest = createPoint(Double.NaN, Double.NaN); + Parallelogram2afp.computeFarthestPoint( + -8, 29, + cx, cy, ux, uy, e1, vx, vy, e2, + farthest); + assertFpPointEquals(pEx, pEy, farthest); + + farthest = createPoint(Double.NaN, Double.NaN); + Parallelogram2afp.computeFarthestPoint(0, 0, + 4.7, 15, + 0.12403, 0.99228, + 18.02776, + -0.44721, 0.89443, + 20, + farthest); + assertFpPointEquals(-2.0082, 50.77719, farthest); + } + + @Test + public void staticContainsParallelogramPoint() { + assertFalse(Parallelogram2afp.containsParallelogramPoint(cx, cy, ux, uy, e1, vx, vy, e2, + 0, 0)); + assertFalse(Parallelogram2afp.containsParallelogramPoint(cx, cy, ux, uy, e1, vx, vy, e2, + -20, 0)); + assertTrue(Parallelogram2afp.containsParallelogramPoint(cx, cy, ux, uy, e1, vx, vy, e2, + 12, -4)); + assertTrue(Parallelogram2afp.containsParallelogramPoint(cx, cy, ux, uy, e1, vx, vy, e2, + 14, 0)); + assertFalse(Parallelogram2afp.containsParallelogramPoint(cx, cy, ux, uy, e1, vx, vy, e2, + 15, 0)); + assertFalse(Parallelogram2afp.containsParallelogramPoint(cx, cy, ux, uy, e1, vx, vy, e2, + 20, 8)); + assertTrue(Parallelogram2afp.containsParallelogramPoint(cx, cy, ux, uy, e1, vx, vy, e2, + 8, 16)); + assertFalse(Parallelogram2afp.containsParallelogramPoint(cx, cy, ux, uy, e1, vx, vy, e2, + -4, 20)); + assertFalse(Parallelogram2afp.containsParallelogramPoint(cx, cy, ux, uy, e1, vx, vy, e2, + -5, 12)); + + assertTrue(Parallelogram2afp.containsParallelogramPoint(cx, cy, ux, uy, e1, vx, vy, e2, + 0, 6)); + assertTrue(Parallelogram2afp.containsParallelogramPoint(cx, cy, ux, uy, e1, vx, vy, e2, + 0, 7)); + assertTrue(Parallelogram2afp.containsParallelogramPoint(cx, cy, ux, uy, e1, vx, vy, e2, + 0, 8)); + assertTrue(Parallelogram2afp.containsParallelogramPoint(cx, cy, ux, uy, e1, vx, vy, e2, + 0, 9)); + assertTrue(Parallelogram2afp.containsParallelogramPoint(cx, cy, ux, uy, e1, vx, vy, e2, + 0, 10)); + assertFalse(Parallelogram2afp.containsParallelogramPoint(cx, cy, ux, uy, e1, vx, vy, e2, + 0, 27)); + + assertTrue(Parallelogram2afp.containsParallelogramPoint(cx, cy, ux, uy, e1, vx, vy, e2, + cx, cy)); + + assertTrue(Parallelogram2afp.containsParallelogramPoint(cx, cy, ux, uy, e1, vx, vy, e2, + 16, 8)); + } + + @Test + public void staticContainsParallelogramRectangle() { + assertFalse(Parallelogram2afp.containsParallelogramRectangle(cx, cy, ux, uy, e1, vx, vy, e2, + 0, 0, 1, 1)); + assertFalse(Parallelogram2afp.containsParallelogramRectangle(cx, cy, ux, uy, e1, vx, vy, e2, + 0, 1, 1, 1)); + assertFalse(Parallelogram2afp.containsParallelogramRectangle(cx, cy, ux, uy, e1, vx, vy, e2, + 0, 2, 1, 1)); + assertFalse(Parallelogram2afp.containsParallelogramRectangle(cx, cy, ux, uy, e1, vx, vy, e2, + 0, 3, 1, 1)); + assertTrue(Parallelogram2afp.containsParallelogramRectangle(cx, cy, ux, uy, e1, vx, vy, e2, + 0, 4, 1, 1)); + assertTrue(Parallelogram2afp.containsParallelogramRectangle(cx, cy, ux, uy, e1, vx, vy, e2, + 0, 5, 1, 1)); + assertTrue(Parallelogram2afp.containsParallelogramRectangle(cx, cy, ux, uy, e1, vx, vy, e2, + 0, 6, 1, 1)); + } + + @Test + public void staticIntersectsParallelogramSegment() { + assertFalse(Parallelogram2afp.intersectsParallelogramSegment(cx, cy, ux, uy, e1, vx, vy, e2, + 0, 0, 1, 1)); + assertTrue(Parallelogram2afp.intersectsParallelogramSegment(cx, cy, ux, uy, e1, vx, vy, e2, + 5, 5, 4, 6)); + assertTrue(Parallelogram2afp.intersectsParallelogramSegment(cx, cy, ux, uy, e1, vx, vy, e2, + 2, -2, 5, 0)); + assertFalse(Parallelogram2afp.intersectsParallelogramSegment(cx, cy, ux, uy, e1, vx, vy, e2, + -20, -5, -10, 6)); + assertFalse(Parallelogram2afp.intersectsParallelogramSegment(cx, cy, ux, uy, e1, vx, vy, e2, + -5, 0, -10, 16)); + assertTrue(Parallelogram2afp.intersectsParallelogramSegment(cx, cy, ux, uy, e1, vx, vy, e2, + -10, 1, 10, 20)); + } + + @Test + public void staticIntersectsParallelogramCircle() { + assertFalse(Parallelogram2afp.intersectsParallelogramCircle(cx, cy, ux, uy, e1, vx, vy, e2, + .5, .5, .5)); + assertFalse(Parallelogram2afp.intersectsParallelogramCircle(cx, cy, ux, uy, e1, vx, vy, e2, + .5, 1.5, .5)); + assertFalse(Parallelogram2afp.intersectsParallelogramCircle(cx, cy, ux, uy, e1, vx, vy, e2, + .5, 2.5, .5)); + assertTrue(Parallelogram2afp.intersectsParallelogramCircle(cx, cy, ux, uy, e1, vx, vy, e2, + .5, 3.5, .5)); + assertTrue(Parallelogram2afp.intersectsParallelogramCircle(cx, cy, ux, uy, e1, vx, vy, e2, + 4.5, 3.5, .5)); + + assertFalse(Parallelogram2afp.intersectsParallelogramCircle(cx, cy, ux, uy, e1, vx, vy, e2, + 10, -7, .5)); + assertFalse(Parallelogram2afp.intersectsParallelogramCircle(cx, cy, ux, uy, e1, vx, vy, e2, + 10.1, -7, .5)); + assertTrue(Parallelogram2afp.intersectsParallelogramCircle(cx, cy, ux, uy, e1, vx, vy, e2, + 10.2, -7, .5)); + + assertTrue(Parallelogram2afp.intersectsParallelogramCircle(cx, cy, ux, uy, e1, vx, vy, e2, + 10, -1, 5)); + } + + @Test + public void staticIntersectsParallelogramEllipse() { + assertFalse(Parallelogram2afp.intersectsParallelogramEllipse(cx, cy, ux, uy, e1, vx, vy, e2, + 0, 0, 2, 1)); + assertFalse(Parallelogram2afp.intersectsParallelogramEllipse(cx, cy, ux, uy, e1, vx, vy, e2, + 0, 1, 2, 1)); + assertTrue(Parallelogram2afp.intersectsParallelogramEllipse(cx, cy, ux, uy, e1, vx, vy, e2, + 0, 2, 2, 1)); + assertTrue(Parallelogram2afp.intersectsParallelogramEllipse(cx, cy, ux, uy, e1, vx, vy, e2, + 0, 3, 2, 1)); + assertTrue(Parallelogram2afp.intersectsParallelogramEllipse(cx, cy, ux, uy, e1, vx, vy, e2, + 0, 4, 2, 1)); + assertTrue(Parallelogram2afp.intersectsParallelogramEllipse(cx, cy, ux, uy, e1, vx, vy, e2, + 1, 3, 2, 1)); + + assertTrue(Parallelogram2afp.intersectsParallelogramEllipse(cx, cy, ux, uy, e1, vx, vy, e2, + 5, 5, 2, 1)); + + assertFalse(Parallelogram2afp.intersectsParallelogramEllipse(cx, cy, ux, uy, e1, vx, vy, e2, + 0.1, 1, 2, 1)); + assertFalse(Parallelogram2afp.intersectsParallelogramEllipse(cx, cy, ux, uy, e1, vx, vy, e2, + 0.2, 1, 2, 1)); + assertTrue(Parallelogram2afp.intersectsParallelogramEllipse(cx, cy, ux, uy, e1, vx, vy, e2, + 0.3, 1, 2, 1)); + assertTrue(Parallelogram2afp.intersectsParallelogramEllipse(cx, cy, ux, uy, e1, vx, vy, e2, + 0.4, 1, 2, 1)); + + assertFalse(Parallelogram2afp.intersectsParallelogramEllipse(cx, cy, ux, uy, e1, vx, vy, e2, + -7, 7.5, 2, 1)); + } + + @Test + public void staticIntersectsParallelogramTriangle() { + assertTrue(Parallelogram2afp.intersectsParallelogramTriangle(cx, cy, ux, uy, e1, vx, vy, e2, + -5, 15, -3, 16, -8, 19)); + assertTrue(Parallelogram2afp.intersectsParallelogramTriangle(cx, cy, ux, uy, e1, vx, vy, e2, + -5, 15, -8, 19, -3, 16)); + assertFalse(Parallelogram2afp.intersectsParallelogramTriangle(cx, cy, ux, uy, e1, vx, vy, e2, + 0, -5, 2, -4, -3, -1)); + assertFalse(Parallelogram2afp.intersectsParallelogramTriangle(cx, cy, ux, uy, e1, vx, vy, e2, + 0, -5, -3, -1, 2, -4)); + assertFalse(Parallelogram2afp.intersectsParallelogramTriangle(cx, cy, ux, uy, e1, vx, vy, e2, + 20, 0, 22, 1, 17, 4)); + assertFalse(Parallelogram2afp.intersectsParallelogramTriangle(cx, cy, ux, uy, e1, vx, vy, e2, + 20, 0, 17, 4, 22, 1)); + assertFalse(Parallelogram2afp.intersectsParallelogramTriangle(cx, cy, ux, uy, e1, vx, vy, e2, + 17.18034, 9, 19.18034, 10, 14.18034, 13)); + assertFalse(Parallelogram2afp.intersectsParallelogramTriangle(cx, cy, ux, uy, e1, vx, vy, e2, + 17.18034, 9, 14.18034, 13, 19.18034, 10)); + assertTrue(Parallelogram2afp.intersectsParallelogramTriangle(cx, cy, ux, uy, e1, vx, vy, e2, + 0, 10, 2, 11, -3, 14)); + assertTrue(Parallelogram2afp.intersectsParallelogramTriangle(cx, cy, ux, uy, e1, vx, vy, e2, + 0, 10, -3, 14, 2, 11)); + assertTrue(Parallelogram2afp.intersectsParallelogramTriangle(cx, cy, ux, uy, e1, vx, vy, e2, + 0, 20, 2, 21, -3, 24)); + } + + @Test + public void staticIntersectsParallelogramParallelogram() { + double ux2 = -0.9284766908852592; + double uy2 = 0.3713906763541037; + double et1 = 5; + double vx2 = 0.3713906763541037; + double vy2 = 0.9284766908852592; + double et2 = 3; + // P + (-0.9284766908852592,0.3713906763541037) * 5 + (0.3713906763541037,0.9284766908852592) * 3 + // P - (-0.9284766908852592,0.3713906763541037) * 5 + (0.3713906763541037,0.9284766908852592) * 3 + // P - (-0.9284766908852592,0.3713906763541037) * 5 - (0.3713906763541037,0.9284766908852592) * 3 + // P + (-0.9284766908852592,0.3713906763541037) * 5 - (0.3713906763541037,0.9284766908852592) * 3 + assertFalse(Parallelogram2afp.intersectsParallelogramParallelogram(cx, cy, ux, uy, e1, vx, vy, e2, + -10, 0, + ux2, uy2, et1, vx2, vy2, et2)); + assertFalse(Parallelogram2afp.intersectsParallelogramParallelogram(cx, cy, ux, uy, e1, vx, vy, e2, + -15, 25, + ux2, uy2, et1, vx2, vy2, et2)); + assertFalse(Parallelogram2afp.intersectsParallelogramParallelogram(cx, cy, ux, uy, e1, vx, vy, e2, + 2, -6, + ux2, uy2, et1, vx2, vy2, et2)); + assertFalse(Parallelogram2afp.intersectsParallelogramParallelogram(cx, cy, ux, uy, e1, vx, vy, e2, + 2, -5, + ux2, uy2, et1, vx2, vy2, et2)); + assertTrue(Parallelogram2afp.intersectsParallelogramParallelogram(cx, cy, ux, uy, e1, vx, vy, e2, + 2, -4, + ux2, uy2, et1, vx2, vy2, et2)); + assertTrue(Parallelogram2afp.intersectsParallelogramParallelogram(cx, cy, ux, uy, e1, vx, vy, e2, + pEx, pEy, + ux2, uy2, et1, vx2, vy2, et2)); + assertTrue(Parallelogram2afp.intersectsParallelogramParallelogram(cx, cy, ux, uy, e1, vx, vy, e2, + 6, 6, + ux2, uy2, et1, vx2, vy2, et2)); + assertTrue(Parallelogram2afp.intersectsParallelogramParallelogram(cx, cy, ux, uy, e1, vx, vy, e2, + 6, 6, + ux2, uy2, 10 * et1, vx2, vy2, 10 * et2)); + } + + @Test + public void staticIntersectsParallelogramRectangle() { + assertFalse(Parallelogram2afp.intersectsParallelogramRectangle(cx, cy, ux, uy, e1, vx, vy, e2, + 0, 0, 1, 1)); + assertTrue(Parallelogram2afp.intersectsParallelogramRectangle(cx, cy, ux, uy, e1, vx, vy, e2, + 0, 2, 1, 1)); + assertTrue(Parallelogram2afp.intersectsParallelogramRectangle(cx, cy, ux, uy, e1, vx, vy, e2, + -5.5, 8.5, 1, 1)); + assertFalse(Parallelogram2afp.intersectsParallelogramRectangle(cx, cy, ux, uy, e1, vx, vy, e2, + -6, 16, 1, 1)); + assertFalse(Parallelogram2afp.intersectsParallelogramRectangle(cx, cy, ux, uy, e1, vx, vy, e2, + 146, 16, 1, 1)); + assertTrue(Parallelogram2afp.intersectsParallelogramRectangle(cx, cy, ux, uy, e1, vx, vy, e2, + 12, 14, 1, 1)); + assertTrue(Parallelogram2afp.intersectsParallelogramRectangle(cx, cy, ux, uy, e1, vx, vy, e2, + 0, 8, 1, 1)); + assertTrue(Parallelogram2afp.intersectsParallelogramRectangle(cx, cy, ux, uy, e1, vx, vy, e2, + 10, -1, 1, 1)); + assertTrue(Parallelogram2afp.intersectsParallelogramRectangle(cx, cy, ux, uy, e1, vx, vy, e2, + -15, -10, 35, 40)); + assertTrue(Parallelogram2afp.intersectsParallelogramRectangle(cx, cy, ux, uy, e1, vx, vy, e2, + -4.79634, 14.50886, 1, 1)); + } + + @Test + public void staticIntersectsParallelogramRoundRectangle() { + assertFalse(Parallelogram2afp.intersectsParallelogramRoundRectangle(cx, cy, ux, uy, e1, vx, vy, e2, + 0, 0, 1, 1, .1, .05)); + assertTrue(Parallelogram2afp.intersectsParallelogramRoundRectangle(cx, cy, ux, uy, e1, vx, vy, e2, + 0, 2, 1, 1, .1, .05)); + assertTrue(Parallelogram2afp.intersectsParallelogramRoundRectangle(cx, cy, ux, uy, e1, vx, vy, e2, + -5.5, 8.5, 1, 1, .1, .05)); + assertFalse(Parallelogram2afp.intersectsParallelogramRoundRectangle(cx, cy, ux, uy, e1, vx, vy, e2, + -6, 16, 1, 1, .1, .05)); + assertFalse(Parallelogram2afp.intersectsParallelogramRoundRectangle(cx, cy, ux, uy, e1, vx, vy, e2, + 146, 16, 1, 1, .1, .05)); + assertTrue(Parallelogram2afp.intersectsParallelogramRoundRectangle(cx, cy, ux, uy, e1, vx, vy, e2, + 12, 14, 1, 1, .1, .05)); + assertTrue(Parallelogram2afp.intersectsParallelogramRoundRectangle(cx, cy, ux, uy, e1, vx, vy, e2, + 0, 8, 1, 1, .1, .05)); + assertTrue(Parallelogram2afp.intersectsParallelogramRoundRectangle(cx, cy, ux, uy, e1, vx, vy, e2, + 10, -1, 1, 1, .1, .05)); + assertTrue(Parallelogram2afp.intersectsParallelogramRoundRectangle(cx, cy, ux, uy, e1, vx, vy, e2, + -15, -10, 35, 40, .1, .05)); + assertFalse(Parallelogram2afp.intersectsParallelogramRoundRectangle(cx, cy, ux, uy, e1, vx, vy, e2, + -4.79634, 14.50886, 1, 1, .1, .05)); + } + + @Override + public void testClone() { + T clone = this.shape.clone(); + assertNotNull(clone); + assertNotSame(this.shape, clone); + assertEquals(this.shape.getClass(), clone.getClass()); + assertEpsilonEquals(cx, clone.getCenterX()); + assertEpsilonEquals(cy, clone.getCenterY()); + assertEpsilonEquals(ux, clone.getFirstAxisX()); + assertEpsilonEquals(uy, clone.getFirstAxisY()); + assertEpsilonEquals(e1, clone.getFirstAxisExtent()); + assertEpsilonEquals(vx, clone.getSecondAxisX()); + assertEpsilonEquals(vy, clone.getSecondAxisY()); + assertEpsilonEquals(e2, clone.getSecondAxisExtent()); + } + + @Override + public void equalsObject() { + assertFalse(this.shape.equals(null)); + assertFalse(this.shape.equals(new Object())); + assertFalse(this.shape.equals(createParallelogram(0, cy, ux, uy, e1, vx, vy, e2))); + assertFalse(this.shape.equals(createParallelogram(cx, cy, ux, uy, e1, vx, vy, 20))); + assertFalse(this.shape.equals(createSegment(5, 8, 6, 10))); + assertTrue(this.shape.equals(this.shape)); + assertTrue(this.shape.equals(createParallelogram(cx, cy, ux, uy, e1, vx, vy, e2))); + } + + @Override + public void equalsObject_withPathIterator() { + assertFalse(this.shape.equals((PathIterator2afp) null)); + assertFalse(this.shape.equals(createParallelogram(0, cy, ux, uy, e1, vx, vy, e2).getPathIterator())); + assertFalse(this.shape.equals(createParallelogram(cx, cy, ux, uy, e1, vx, vy, 20).getPathIterator())); + assertFalse(this.shape.equals(createSegment(5, 8, 6, 10).getPathIterator())); + assertTrue(this.shape.equals(this.shape.getPathIterator())); + assertTrue(this.shape.equals(createParallelogram(cx, cy, ux, uy, e1, vx, vy, e2).getPathIterator())); + } + + @Override + public void equalsToPathIterator() { + assertFalse(this.shape.equalsToPathIterator(null)); + assertFalse(this.shape.equalsToPathIterator(createParallelogram(0, cy, ux, uy, e1, vx, vy, e2).getPathIterator())); + assertFalse(this.shape.equalsToPathIterator(createParallelogram(cx, cy, ux, uy, e1, vx, vy, 20).getPathIterator())); + assertFalse(this.shape.equalsToPathIterator(createSegment(5, 8, 6, 10).getPathIterator())); + assertTrue(this.shape.equalsToPathIterator(this.shape.getPathIterator())); + assertTrue(this.shape.equalsToPathIterator(createParallelogram(cx, cy, ux, uy, e1, vx, vy, e2).getPathIterator())); + } + + @Override + public void equalsToShape() { + assertFalse(this.shape.equalsToShape(null)); + assertFalse(this.shape.equalsToShape((T) createParallelogram(0, cy, ux, uy, e1, vx, vy, e2))); + assertFalse(this.shape.equalsToShape((T) createParallelogram(cx, cy, ux, uy, e1, vx, vy, 20))); + assertTrue(this.shape.equalsToShape(this.shape)); + assertTrue(this.shape.equalsToShape((T) createParallelogram(cx, cy, ux, uy, e1, vx, vy, e2))); + } + + @Override + public void isEmpty() { + assertFalse(this.shape.isEmpty()); + this.shape.clear(); + assertTrue(this.shape.isEmpty()); + } + + @Override + public void clear() { + this.shape.clear(); + assertEpsilonEquals(0, this.shape.getCenterX()); + assertEpsilonEquals(0, this.shape.getCenterY()); + assertEpsilonEquals(1, this.shape.getFirstAxisX()); + assertEpsilonEquals(0, this.shape.getFirstAxisY()); + assertEpsilonEquals(0, this.shape.getFirstAxisExtent()); + assertEpsilonEquals(0, this.shape.getSecondAxisX()); + assertEpsilonEquals(1, this.shape.getSecondAxisY()); + assertEpsilonEquals(0, this.shape.getSecondAxisExtent()); + } + + @Override + public void containsDoubleDouble() { + assertFalse(this.shape.contains(0, 0)); + assertFalse(this.shape.contains(-20, 0)); + assertTrue(this.shape.contains(12, -4)); + assertTrue(this.shape.contains(14, 0)); + assertFalse(this.shape.contains(15, 0)); + assertFalse(this.shape.contains(20, 8)); + assertTrue(this.shape.contains(8, 16)); + assertFalse(this.shape.contains(-4, 20)); + assertFalse(this.shape.contains(-5, 12)); + assertTrue(this.shape.contains(0, 6)); + assertTrue(this.shape.contains(0, 7)); + assertTrue(this.shape.contains(0, 8)); + assertTrue(this.shape.contains(0, 9)); + assertTrue(this.shape.contains(0, 10)); + assertFalse(this.shape.contains(0, 27)); + assertTrue(this.shape.contains(cx, cy)); + assertTrue(this.shape.contains(16, 8)); + } + + @Override + public void containsPoint2D() { + assertFalse(this.shape.contains(createPoint(0, 0))); + assertFalse(this.shape.contains(createPoint(-20, 0))); + assertTrue(this.shape.contains(createPoint(12, -4))); + assertTrue(this.shape.contains(createPoint(14, 0))); + assertFalse(this.shape.contains(createPoint(15, 0))); + assertFalse(this.shape.contains(createPoint(20, 8))); + assertTrue(this.shape.contains(createPoint(8, 16))); + assertFalse(this.shape.contains(createPoint(-4, 20))); + assertFalse(this.shape.contains(createPoint(-5, 12))); + assertTrue(this.shape.contains(createPoint(0, 6))); + assertTrue(this.shape.contains(createPoint(0, 7))); + assertTrue(this.shape.contains(createPoint(0, 8))); + assertTrue(this.shape.contains(createPoint(0, 9))); + assertTrue(this.shape.contains(createPoint(0, 10))); + assertFalse(this.shape.contains(createPoint(0, 27))); + assertTrue(this.shape.contains(createPoint(cx, cy))); + assertTrue(this.shape.contains(createPoint( 16, 8))); + } + + @Override + public void getClosestPointTo() { + Point2D closest; + + closest = this.shape.getClosestPointTo(createPoint(-20, 9)); + assertEpsilonEquals(pHx, closest.getX()); + assertEpsilonEquals(pHy, closest.getY()); + + closest = this.shape.getClosestPointTo(createPoint(0, 0)); + assertEpsilonEquals(1.90983, closest.getX()); + assertEpsilonEquals(1.90983, closest.getY()); + + closest = this.shape.getClosestPointTo(createPoint(5, -10)); + assertEpsilonEquals(9.40983, closest.getX()); + assertEpsilonEquals(-5.59017, closest.getY()); + + closest = this.shape.getClosestPointTo(createPoint(14, -20)); + assertEpsilonEquals(pEx, closest.getX()); + assertEpsilonEquals(pEy, closest.getY()); + + closest = this.shape.getClosestPointTo(createPoint(-6, 15)); + assertEpsilonEquals(-3.81679, closest.getX()); + assertEpsilonEquals(14.4542, closest.getY()); + + closest = this.shape.getClosestPointTo(createPoint(0, 10)); + assertEpsilonEquals(0, closest.getX()); + assertEpsilonEquals(10, closest.getY()); + + closest = this.shape.getClosestPointTo(createPoint(10, 0)); + assertEpsilonEquals(10, closest.getX()); + assertEpsilonEquals(0, closest.getY()); + + closest = this.shape.getClosestPointTo(createPoint(15, -4)); + assertEpsilonEquals(13.99326, closest.getX()); + assertEpsilonEquals(-3.74832, closest.getY()); + + closest = this.shape.getClosestPointTo(createPoint(-5, 25)); + assertEpsilonEquals(-1.40503, closest.getX()); + assertEpsilonEquals(24.10126, closest.getY()); + + closest = this.shape.getClosestPointTo(createPoint(0, 20)); + assertEpsilonEquals(0, closest.getX()); + assertEpsilonEquals(20, closest.getY()); + + closest = this.shape.getClosestPointTo(createPoint(10, 10)); + assertEpsilonEquals(10, closest.getX()); + assertEpsilonEquals(10, closest.getY()); + + closest = this.shape.getClosestPointTo(createPoint(20, 0)); + assertEpsilonEquals(15.22856, closest.getX()); + assertEpsilonEquals(1.19286, closest.getY()); + + closest = this.shape.getClosestPointTo(createPoint(-3, 35)); + assertEpsilonEquals(pGx, closest.getX()); + assertEpsilonEquals(pGy, closest.getY()); + + closest = this.shape.getClosestPointTo(createPoint(5, 35)); + assertEpsilonEquals(pGx, closest.getX()); + assertEpsilonEquals(pGy, closest.getY()); + + closest = this.shape.getClosestPointTo(createPoint(20, 15)); + assertEpsilonEquals(15.59017, closest.getX()); + assertEpsilonEquals(10.59017, closest.getY()); + + closest = this.shape.getClosestPointTo(createPoint(35, 10)); + assertEpsilonEquals(pFx, closest.getX()); + assertEpsilonEquals(pFy, closest.getY()); + + closest = this.shape.getClosestPointTo(createPoint(-8, 29)); + assertEpsilonEquals(pGx, closest.getX()); + assertEpsilonEquals(pGy, closest.getY()); + } + + @Override + public void getFarthestPointTo() { + Point2D farthest; + + farthest = this.shape.getFarthestPointTo(createPoint(-20, 9)); + assertEpsilonEquals(pEx, farthest.getX()); + assertEpsilonEquals(pEy, farthest.getY()); + + farthest = this.shape.getFarthestPointTo(createPoint(0, 0)); + assertEpsilonEquals(pGx, farthest.getX()); + assertEpsilonEquals(pGy, farthest.getY()); + + farthest = this.shape.getFarthestPointTo(createPoint(5, -10)); + assertEpsilonEquals(pGx, farthest.getX()); + assertEpsilonEquals(pGy, farthest.getY()); + + farthest = this.shape.getFarthestPointTo(createPoint(14, -20)); + assertEpsilonEquals(pGx, farthest.getX()); + assertEpsilonEquals(pGy, farthest.getY()); + + farthest = this.shape.getFarthestPointTo(createPoint(-6, 15)); + assertEpsilonEquals(pEx, farthest.getX()); + assertEpsilonEquals(pEy, farthest.getY()); + + farthest = this.shape.getFarthestPointTo(createPoint(0, 10)); + assertEpsilonEquals(pEx, farthest.getX()); + assertEpsilonEquals(pEy, farthest.getY()); + + farthest = this.shape.getFarthestPointTo(createPoint(10, 0)); + assertEpsilonEquals(pGx, farthest.getX()); + assertEpsilonEquals(pGy, farthest.getY()); + + farthest = this.shape.getFarthestPointTo(createPoint(15, -4)); + assertEpsilonEquals(pGx, farthest.getX()); + assertEpsilonEquals(pGy, farthest.getY()); + + farthest = this.shape.getFarthestPointTo(createPoint(-5, 25)); + assertEpsilonEquals(pEx, farthest.getX()); + assertEpsilonEquals(pEy, farthest.getY()); + + farthest = this.shape.getFarthestPointTo(createPoint(0, 20)); + assertEpsilonEquals(pEx, farthest.getX()); + assertEpsilonEquals(pEy, farthest.getY()); + + farthest = this.shape.getFarthestPointTo(createPoint(10, 10)); + assertEpsilonEquals(pGx, farthest.getX()); + assertEpsilonEquals(pGy, farthest.getY()); + + farthest = this.shape.getFarthestPointTo(createPoint(20, 0)); + assertEpsilonEquals(pGx, farthest.getX()); + assertEpsilonEquals(pGy, farthest.getY()); + + farthest = this.shape.getFarthestPointTo(createPoint(-3, 35)); + assertEpsilonEquals(pEx, farthest.getX()); + assertEpsilonEquals(pEy, farthest.getY()); + + farthest = this.shape.getFarthestPointTo(createPoint(5, 35)); + assertEpsilonEquals(pEx, farthest.getX()); + assertEpsilonEquals(pEy, farthest.getY()); + + farthest = this.shape.getFarthestPointTo(createPoint(20, 15)); + assertEpsilonEquals(pHx, farthest.getX()); + assertEpsilonEquals(pHy, farthest.getY()); + + farthest = this.shape.getFarthestPointTo(createPoint(35, 10)); + assertEpsilonEquals(pHx, farthest.getX()); + assertEpsilonEquals(pHy, farthest.getY()); + + farthest = this.shape.getFarthestPointTo(createPoint(-8, 29)); + assertEpsilonEquals(pEx, farthest.getX()); + assertEpsilonEquals(pEy, farthest.getY()); + } + + @Override + public void translateDoubleDouble() { + this.shape.translate(123.456, 789.123); + assertEpsilonEquals(cx + 123.456, this.shape.getCenterX()); + assertEpsilonEquals(cy + 789.123, this.shape.getCenterY()); + assertEpsilonEquals(ux, this.shape.getFirstAxisX()); + assertEpsilonEquals(uy, this.shape.getFirstAxisY()); + assertEpsilonEquals(e1, this.shape.getFirstAxisExtent()); + assertEpsilonEquals(vx, this.shape.getSecondAxisX()); + assertEpsilonEquals(vy, this.shape.getSecondAxisY()); + assertEpsilonEquals(e2, this.shape.getSecondAxisExtent()); + } + + @Override + public void translateVector2D() { + this.shape.translate(createVector(123.456, 789.123)); + assertEpsilonEquals(cx + 123.456, this.shape.getCenterX()); + assertEpsilonEquals(cy + 789.123, this.shape.getCenterY()); + assertEpsilonEquals(ux, this.shape.getFirstAxisX()); + assertEpsilonEquals(uy, this.shape.getFirstAxisY()); + assertEpsilonEquals(e1, this.shape.getFirstAxisExtent()); + assertEpsilonEquals(vx, this.shape.getSecondAxisX()); + assertEpsilonEquals(vy, this.shape.getSecondAxisY()); + assertEpsilonEquals(e2, this.shape.getSecondAxisExtent()); + } + + @Override + public void getDistance() { + assertEpsilonEquals(14.81966, this.shape.getDistance(createPoint(-20, 9))); + assertEpsilonEquals(2.7009, this.shape.getDistance(createPoint(0, 0))); + assertEpsilonEquals(6.23644, this.shape.getDistance(createPoint(5, -10))); + assertEpsilonEquals(11.1863, this.shape.getDistance(createPoint(14, -20))); + assertEpsilonEquals(2.25040, this.shape.getDistance(createPoint(-6, 15))); + assertEpsilonEquals(0, this.shape.getDistance(createPoint(0, 10))); + assertEpsilonEquals(0, this.shape.getDistance(createPoint(10, 0))); + assertEpsilonEquals(1.03772, this.shape.getDistance(createPoint(15, -4))); + assertEpsilonEquals(3.70561, this.shape.getDistance(createPoint(-5, 25))); + assertEpsilonEquals(0, this.shape.getDistance(createPoint(0, 20))); + assertEpsilonEquals(0, this.shape.getDistance(createPoint(10, 10))); + assertEpsilonEquals(4.91829, this.shape.getDistance(createPoint(20, 0))); + assertEpsilonEquals(8.42901, this.shape.getDistance(createPoint(-3, 35))); + assertEpsilonEquals(9.91864, this.shape.getDistance(createPoint(5, 35))); + assertEpsilonEquals(6.23644, this.shape.getDistance(createPoint(20, 15))); + assertEpsilonEquals(17.8477, this.shape.getDistance(createPoint(35, 10))); + assertEpsilonEquals(7.59135, this.shape.getDistance(createPoint(-8, 29))); + } + + @Override + public void getDistanceSquared() { + assertEpsilonEquals(219.62232, this.shape.getDistanceSquared(createPoint(-20, 9))); + assertEpsilonEquals(7.29486, this.shape.getDistanceSquared(createPoint(0, 0))); + assertEpsilonEquals(38.89318, this.shape.getDistanceSquared(createPoint(5, -10))); + assertEpsilonEquals(125.13319, this.shape.getDistanceSquared(createPoint(14, -20))); + assertEpsilonEquals(5.0643, this.shape.getDistanceSquared(createPoint(-6, 15))); + assertEpsilonEquals(0, this.shape.getDistanceSquared(createPoint(0, 10))); + assertEpsilonEquals(0, this.shape.getDistanceSquared(createPoint(10, 0))); + assertEpsilonEquals(1.07686, this.shape.getDistanceSquared(createPoint(15, -4))); + assertEpsilonEquals(13.73155, this.shape.getDistanceSquared(createPoint(-5, 25))); + assertEpsilonEquals(0, this.shape.getDistanceSquared(createPoint(0, 20))); + assertEpsilonEquals(0, this.shape.getDistanceSquared(createPoint(10, 10))); + assertEpsilonEquals(24.18958, this.shape.getDistanceSquared(createPoint(20, 0))); + assertEpsilonEquals(71.04805, this.shape.getDistanceSquared(createPoint(-3, 35))); + assertEpsilonEquals(98.37931, this.shape.getDistanceSquared(createPoint(5, 35))); + assertEpsilonEquals(38.89318, this.shape.getDistanceSquared(createPoint(20, 15))); + assertEpsilonEquals(318.54029, this.shape.getDistanceSquared(createPoint(35, 10))); + assertEpsilonEquals(57.62859, this.shape.getDistanceSquared(createPoint(-8, 29))); + } + + @Override + public void getDistanceL1() { + assertEpsilonEquals(14.81966, this.shape.getDistanceL1(createPoint(-20, 9))); + assertEpsilonEquals(3.81966, this.shape.getDistanceL1(createPoint(0, 0))); + assertEpsilonEquals(8.81966, this.shape.getDistanceL1(createPoint(5, -10))); + assertEpsilonEquals(12.40325, this.shape.getDistanceL1(createPoint(14, -20))); + assertEpsilonEquals(2.72901, this.shape.getDistanceL1(createPoint(-6, 15))); + assertEpsilonEquals(0, this.shape.getDistanceL1(createPoint(0, 10))); + assertEpsilonEquals(0, this.shape.getDistanceL1(createPoint(10, 0))); + assertEpsilonEquals(1.25842, this.shape.getDistanceL1(createPoint(15, -4))); + assertEpsilonEquals(4.49371, this.shape.getDistanceL1(createPoint(-5, 25))); + assertEpsilonEquals(0, this.shape.getDistanceL1(createPoint(0, 20))); + assertEpsilonEquals(0, this.shape.getDistanceL1(createPoint(10, 10))); + assertEpsilonEquals(5.9643, this.shape.getDistanceL1(createPoint(20, 0))); + assertEpsilonEquals(10.40326, this.shape.getDistanceL1(createPoint(-3, 35))); + assertEpsilonEquals(13.81966, this.shape.getDistanceL1(createPoint(5, 35))); + assertEpsilonEquals(8.81966, this.shape.getDistanceL1(createPoint(20, 15))); + assertEpsilonEquals(18.81966, this.shape.getDistanceL1(createPoint(35, 10))); + assertEpsilonEquals(9.40326, this.shape.getDistanceL1(createPoint(-8, 29))); + } + + @Override + public void getDistanceLinf() { + assertEpsilonEquals(14.81966, this.shape.getDistanceLinf(createPoint(-20, 9))); + assertEpsilonEquals(1.90983, this.shape.getDistanceLinf(createPoint(0, 0))); + assertEpsilonEquals(4.40983, this.shape.getDistanceLinf(createPoint(5, -10))); + assertEpsilonEquals(11.11146, this.shape.getDistanceLinf(createPoint(14, -20))); + assertEpsilonEquals(2.18321, this.shape.getDistanceLinf(createPoint(-6, 15))); + assertEpsilonEquals(0, this.shape.getDistanceLinf(createPoint(0, 10))); + assertEpsilonEquals(0, this.shape.getDistanceLinf(createPoint(10, 0))); + assertEpsilonEquals(1.00674, this.shape.getDistanceLinf(createPoint(15, -4))); + assertEpsilonEquals(3.59497, this.shape.getDistanceLinf(createPoint(-5, 25))); + assertEpsilonEquals(0, this.shape.getDistanceLinf(createPoint(0, 20))); + assertEpsilonEquals(0, this.shape.getDistanceLinf(createPoint(10, 10))); + assertEpsilonEquals(4.77144, this.shape.getDistanceLinf(createPoint(20, 0))); + assertEpsilonEquals(8.11146, this.shape.getDistanceLinf(createPoint(-3, 35))); + assertEpsilonEquals(8.11146, this.shape.getDistanceLinf(createPoint(5, 35))); + assertEpsilonEquals(4.40983, this.shape.getDistanceLinf(createPoint(20, 15))); + assertEpsilonEquals(17.81966, this.shape.getDistanceLinf(createPoint(35, 10))); + assertEpsilonEquals(7.2918, this.shape.getDistanceLinf(createPoint(-8, 29))); + } + + @Override + public void setIT() { + this.shape.set((T) createParallelogram(17, 20, 1, 0, 15, 0, 1, 14)); + assertEpsilonEquals(17, this.shape.getCenterX()); + assertEpsilonEquals(20, this.shape.getCenterY()); + assertEpsilonEquals(1, this.shape.getFirstAxisX()); + assertEpsilonEquals(0, this.shape.getFirstAxisY()); + assertEpsilonEquals(15, this.shape.getFirstAxisExtent()); + assertEpsilonEquals(0, this.shape.getSecondAxisX()); + assertEpsilonEquals(1, this.shape.getSecondAxisY()); + assertEpsilonEquals(14, this.shape.getSecondAxisExtent()); + } + + @Override + public void getPathIterator() { + PathIterator2afp pi = this.shape.getPathIterator(); + assertElement(pi, PathElementType.MOVE_TO, pGx, pGy); + assertElement(pi, PathElementType.LINE_TO, pHx, pHy); + assertElement(pi, PathElementType.LINE_TO, pEx, pEy); + assertElement(pi, PathElementType.LINE_TO, pFx, pFy); + assertElement(pi, PathElementType.CLOSE, pGx, pGy); + assertNoElement(pi); + } + + @Override + public void getPathIteratorTransform2D() { + PathIterator2afp pi = this.shape.getPathIterator(null); + assertElement(pi, PathElementType.MOVE_TO, pGx, pGy); + assertElement(pi, PathElementType.LINE_TO, pHx, pHy); + assertElement(pi, PathElementType.LINE_TO, pEx, pEy); + assertElement(pi, PathElementType.LINE_TO, pFx, pFy); + assertElement(pi, PathElementType.CLOSE, pGx, pGy); + assertNoElement(pi); + + Transform2D transform; + + transform = new Transform2D(); + pi = this.shape.getPathIterator(transform); + assertElement(pi, PathElementType.MOVE_TO, pGx, pGy); + assertElement(pi, PathElementType.LINE_TO, pHx, pHy); + assertElement(pi, PathElementType.LINE_TO, pEx, pEy); + assertElement(pi, PathElementType.LINE_TO, pFx, pFy); + assertElement(pi, PathElementType.CLOSE, pGx, pGy); + assertNoElement(pi); + + transform = new Transform2D(); + transform.setTranslation(18, -45); + pi = this.shape.getPathIterator(transform); + assertElement(pi, PathElementType.MOVE_TO, pGx + 18, pGy - 45); + assertElement(pi, PathElementType.LINE_TO, pHx + 18, pHy - 45); + assertElement(pi, PathElementType.LINE_TO, pEx + 18, pEy - 45); + assertElement(pi, PathElementType.LINE_TO, pFx + 18, pFy - 45); + assertElement(pi, PathElementType.CLOSE, pGx + 18, pGy - 45); + assertNoElement(pi); + } + + @Override + public void createTransformedShape() { + PathIterator2afp pi = this.shape.createTransformedShape(null).getPathIterator(); + assertElement(pi, PathElementType.MOVE_TO, pGx, pGy); + assertElement(pi, PathElementType.LINE_TO, pHx, pHy); + assertElement(pi, PathElementType.LINE_TO, pEx, pEy); + assertElement(pi, PathElementType.LINE_TO, pFx, pFy); + assertElement(pi, PathElementType.CLOSE, pGx, pGy); + assertNoElement(pi); + + Transform2D transform; + + transform = new Transform2D(); + pi = this.shape.createTransformedShape(transform).getPathIterator(); + assertElement(pi, PathElementType.MOVE_TO, pGx, pGy); + assertElement(pi, PathElementType.LINE_TO, pHx, pHy); + assertElement(pi, PathElementType.LINE_TO, pEx, pEy); + assertElement(pi, PathElementType.LINE_TO, pFx, pFy); + assertElement(pi, PathElementType.CLOSE, pGx, pGy); + assertNoElement(pi); + + transform = new Transform2D(); + transform.setTranslation(18, -45); + pi = this.shape.createTransformedShape(transform).getPathIterator(); + assertElement(pi, PathElementType.MOVE_TO, pGx + 18, pGy - 45); + assertElement(pi, PathElementType.LINE_TO, pHx + 18, pHy - 45); + assertElement(pi, PathElementType.LINE_TO, pEx + 18, pEy - 45); + assertElement(pi, PathElementType.LINE_TO, pFx + 18, pFy - 45); + assertElement(pi, PathElementType.CLOSE, pGx + 18, pGy - 45); + assertNoElement(pi); + } + + @Override + public void toBoundingBox() { + B box = this.shape.toBoundingBox(); + assertEpsilonEquals(pHx, box.getMinX()); + assertEpsilonEquals(pEy, box.getMinY()); + assertEpsilonEquals(pFx, box.getMaxX()); + assertEpsilonEquals(pGy, box.getMaxY()); + } + + @Override + public void toBoundingBoxB() { + B box = createRectangle(0, 0, 0, 0); + this.shape.toBoundingBox(box); + assertEpsilonEquals(pHx, box.getMinX()); + assertEpsilonEquals(pEy, box.getMinY()); + assertEpsilonEquals(pFx, box.getMaxX()); + assertEpsilonEquals(pGy, box.getMaxY()); + } + + @Override + public void containsRectangle2afp() { + assertFalse(this.shape.contains(createRectangle(0, 0, 1, 1))); + assertFalse(this.shape.contains(createRectangle(0, 1, 1, 1))); + assertFalse(this.shape.contains(createRectangle(0, 2, 1, 1))); + assertFalse(this.shape.contains(createRectangle(0, 3, 1, 1))); + assertTrue(this.shape.contains(createRectangle(0, 4, 1, 1))); + assertTrue(this.shape.contains(createRectangle(0, 5, 1, 1))); + assertTrue(this.shape.contains(createRectangle(0, 6, 1, 1))); + } + + @Override + public void containsShape2D() { + assertFalse(this.shape.contains(createCircle(0, 0, 1))); + assertFalse(this.shape.contains(createCircle(0, 1, 1))); + assertFalse(this.shape.contains(createCircle(0, 2, 1))); + assertFalse(this.shape.contains(createCircle(0, 3, 1))); + assertFalse(this.shape.contains(createCircle(0, 4, 1))); + assertFalse(this.shape.contains(createCircle(0, 5, 1))); + assertTrue(this.shape.contains(createCircle(0, 6, 1))); + } + + @Test + public void rotateDouble() { + this.shape.rotate(-MathConstants.DEMI_PI); + assertEpsilonEquals(6, this.shape.getCenterX()); + assertEpsilonEquals(9, this.shape.getCenterY()); + assertEpsilonEquals(9.701400000000000e-01, this.shape.getFirstAxisX()); + assertEpsilonEquals(-2.425400000000000e-01, this.shape.getFirstAxisY()); + assertEpsilonEquals(9.21954, this.shape.getFirstAxisExtent()); + assertEpsilonEquals(7.071100000000000e-01, this.shape.getSecondAxisX()); + assertEpsilonEquals(7.071100000000000e-01, this.shape.getSecondAxisY()); + assertEpsilonEquals(12.64911, this.shape.getSecondAxisExtent()); + } + + @Test + public void getCenter() { + Point2D c = this.shape.getCenter(); + assertEpsilonEquals(6, c.getX()); + assertEpsilonEquals(9, c.getY()); + } + + @Test + public void getCenterX() { + assertEpsilonEquals(6, this.shape.getCenterX()); + } + + @Test + public void getCenterY() { + assertEpsilonEquals(9, this.shape.getCenterY()); + } + + @Test + public void setCenterDoubleDouble() { + this.shape.setCenter(123.456, -789.123); + assertEpsilonEquals(123.456, this.shape.getCenterX()); + assertEpsilonEquals(-789.123, this.shape.getCenterY()); + assertEpsilonEquals(ux, this.shape.getFirstAxisX()); + assertEpsilonEquals(uy, this.shape.getFirstAxisY()); + assertEpsilonEquals(e1, this.shape.getFirstAxisExtent()); + assertEpsilonEquals(vx, this.shape.getSecondAxisX()); + assertEpsilonEquals(vy, this.shape.getSecondAxisY()); + assertEpsilonEquals(e2, this.shape.getSecondAxisExtent()); + } + + @Test + public void setCenterPoint2D() { + this.shape.setCenter(createPoint(123.456, -789.123)); + assertEpsilonEquals(123.456, this.shape.getCenterX()); + assertEpsilonEquals(-789.123, this.shape.getCenterY()); + assertEpsilonEquals(ux, this.shape.getFirstAxisX()); + assertEpsilonEquals(uy, this.shape.getFirstAxisY()); + assertEpsilonEquals(e1, this.shape.getFirstAxisExtent()); + assertEpsilonEquals(vx, this.shape.getSecondAxisX()); + assertEpsilonEquals(vy, this.shape.getSecondAxisY()); + assertEpsilonEquals(e2, this.shape.getSecondAxisExtent()); + } + + @Test + public void setCenterX() { + this.shape.setCenterX(123.456); + assertEpsilonEquals(123.456, this.shape.getCenterX()); + assertEpsilonEquals(cy, this.shape.getCenterY()); + assertEpsilonEquals(ux, this.shape.getFirstAxisX()); + assertEpsilonEquals(uy, this.shape.getFirstAxisY()); + assertEpsilonEquals(e1, this.shape.getFirstAxisExtent()); + assertEpsilonEquals(vx, this.shape.getSecondAxisX()); + assertEpsilonEquals(vy, this.shape.getSecondAxisY()); + assertEpsilonEquals(e2, this.shape.getSecondAxisExtent()); + } + + @Test + public void setCenterY() { + this.shape.setCenterY(123.456); + assertEpsilonEquals(cx, this.shape.getCenterX()); + assertEpsilonEquals(123.456, this.shape.getCenterY()); + assertEpsilonEquals(ux, this.shape.getFirstAxisX()); + assertEpsilonEquals(uy, this.shape.getFirstAxisY()); + assertEpsilonEquals(e1, this.shape.getFirstAxisExtent()); + assertEpsilonEquals(vx, this.shape.getSecondAxisX()); + assertEpsilonEquals(vy, this.shape.getSecondAxisY()); + assertEpsilonEquals(e2, this.shape.getSecondAxisExtent()); + } + + @Test + public void getFirstAxis() { + Vector2D v = this.shape.getFirstAxis(); + assertEpsilonEquals(ux, v.getX()); + assertEpsilonEquals(uy, v.getY()); + } + + @Test + public void getFirstAxisX() { + assertEpsilonEquals(ux, this.shape.getFirstAxisX()); + } + + @Test + public void getFirstAxisY() { + assertEpsilonEquals(uy, this.shape.getFirstAxisY()); + } + + @Test + public void getSecondAxis() { + Vector2D v = this.shape.getSecondAxis(); + assertEpsilonEquals(vx, v.getX()); + assertEpsilonEquals(vy, v.getY()); + } + + @Test + public void getSecondAxisX() { + assertEpsilonEquals(vx, this.shape.getSecondAxisX()); + } + + @Test + public void getSecondAxisY() { + assertEpsilonEquals(vy, this.shape.getSecondAxisY()); + } + + @Test + public void getFirstAxisExtent() { + assertEpsilonEquals(e1, this.shape.getFirstAxisExtent()); + } + + @Test + public void setFirstAxisExtent() { + this.shape.setFirstAxisExtent(123.456); + assertEpsilonEquals(cx, this.shape.getCenterX()); + assertEpsilonEquals(cy, this.shape.getCenterY()); + assertEpsilonEquals(ux, this.shape.getFirstAxisX()); + assertEpsilonEquals(uy, this.shape.getFirstAxisY()); + assertEpsilonEquals(123.456, this.shape.getFirstAxisExtent()); + assertEpsilonEquals(vx, this.shape.getSecondAxisX()); + assertEpsilonEquals(vy, this.shape.getSecondAxisY()); + assertEpsilonEquals(e2, this.shape.getSecondAxisExtent()); + } + + @Test + public void getSecondAxisExtent() { + assertEpsilonEquals(e2, this.shape.getSecondAxisExtent()); + } + + @Test + public void setSecondAxisExtent() { + this.shape.setSecondAxisExtent(123.456); + assertEpsilonEquals(cx, this.shape.getCenterX()); + assertEpsilonEquals(cy, this.shape.getCenterY()); + assertEpsilonEquals(ux, this.shape.getFirstAxisX()); + assertEpsilonEquals(uy, this.shape.getFirstAxisY()); + assertEpsilonEquals(e1, this.shape.getFirstAxisExtent()); + assertEpsilonEquals(vx, this.shape.getSecondAxisX()); + assertEpsilonEquals(vy, this.shape.getSecondAxisY()); + assertEpsilonEquals(123.456, this.shape.getSecondAxisExtent()); + } + + @Test + public void setFirstAxisDoubleDouble_unitVector() { + Vector2D newU = createVector(123.456, 456.789).toUnitVector(); + this.shape.setFirstAxis(newU.getX(), newU.getY()); + assertEpsilonEquals(cx, this.shape.getCenterX()); + assertEpsilonEquals(cy, this.shape.getCenterY()); + assertEpsilonEquals(newU.getX(), this.shape.getFirstAxisX()); + assertEpsilonEquals(newU.getY(), this.shape.getFirstAxisY()); + assertEpsilonEquals(e1, this.shape.getFirstAxisExtent()); + assertEpsilonEquals(vx, this.shape.getSecondAxisX()); + assertEpsilonEquals(vy, this.shape.getSecondAxisY()); + assertEpsilonEquals(e2, this.shape.getSecondAxisExtent()); + } + + @Test(expected = AssertionError.class) + public void setFirstAxisDoubleDouble_notUnitVector() { + this.shape.setFirstAxis(123.456, 456.789); + } + + @Test + public void setFirstAxisVector2D_unitVector() { + Vector2D newU = createVector(123.456, 456.789).toUnitVector(); + this.shape.setFirstAxis(newU); + assertEpsilonEquals(cx, this.shape.getCenterX()); + assertEpsilonEquals(cy, this.shape.getCenterY()); + assertEpsilonEquals(newU.getX(), this.shape.getFirstAxisX()); + assertEpsilonEquals(newU.getY(), this.shape.getFirstAxisY()); + assertEpsilonEquals(e1, this.shape.getFirstAxisExtent()); + assertEpsilonEquals(vx, this.shape.getSecondAxisX()); + assertEpsilonEquals(vy, this.shape.getSecondAxisY()); + assertEpsilonEquals(e2, this.shape.getSecondAxisExtent()); + } + + @Test(expected = AssertionError.class) + public void setFirstAxisVector2D_notUnitVector() { + this.shape.setFirstAxis(createVector(123.456, 456.789)); + } + + @Test + public void setFirstAxisVector2DDouble_unitVector() { + Vector2D newU = createVector(123.456, 456.789).toUnitVector(); + this.shape.setFirstAxis(newU, 159.753); + assertEpsilonEquals(cx, this.shape.getCenterX()); + assertEpsilonEquals(cy, this.shape.getCenterY()); + assertEpsilonEquals(newU.getX(), this.shape.getFirstAxisX()); + assertEpsilonEquals(newU.getY(), this.shape.getFirstAxisY()); + assertEpsilonEquals(159.753, this.shape.getFirstAxisExtent()); + assertEpsilonEquals(vx, this.shape.getSecondAxisX()); + assertEpsilonEquals(vy, this.shape.getSecondAxisY()); + assertEpsilonEquals(e2, this.shape.getSecondAxisExtent()); + } + + @Test + public void setFirstAxisDoubleDoubleDouble() { + Vector2D newU = createVector(123.456, 456.789).toUnitVector(); + this.shape.setFirstAxis(newU.getX(), newU.getY(), 159.753); + assertEpsilonEquals(cx, this.shape.getCenterX()); + assertEpsilonEquals(cy, this.shape.getCenterY()); + assertEpsilonEquals(newU.getX(), this.shape.getFirstAxisX()); + assertEpsilonEquals(newU.getY(), this.shape.getFirstAxisY()); + assertEpsilonEquals(159.753, this.shape.getFirstAxisExtent()); + assertEpsilonEquals(vx, this.shape.getSecondAxisX()); + assertEpsilonEquals(vy, this.shape.getSecondAxisY()); + assertEpsilonEquals(e2, this.shape.getSecondAxisExtent()); + } + + @Test + public void setSecondAxisDoubleDouble_unitVector() { + Vector2D newV = createVector(123.456, 456.789).toUnitVector(); + this.shape.setSecondAxis(newV.getX(), newV.getY()); + assertEpsilonEquals(cx, this.shape.getCenterX()); + assertEpsilonEquals(cy, this.shape.getCenterY()); + assertEpsilonEquals(ux, this.shape.getFirstAxisX()); + assertEpsilonEquals(uy, this.shape.getFirstAxisY()); + assertEpsilonEquals(e1, this.shape.getFirstAxisExtent()); + assertEpsilonEquals(newV.getX(), this.shape.getSecondAxisX()); + assertEpsilonEquals(newV.getY(), this.shape.getSecondAxisY()); + assertEpsilonEquals(e2, this.shape.getSecondAxisExtent()); + } + + @Test(expected = AssertionError.class) + public void setSecondAxisDoubleDouble_notUnitVector() { + this.shape.setSecondAxis(123.456, 456.789); + } + + @Test + public void setSecondAxisVector2D_unitVector() { + Vector2D newV = createVector(123.456, 456.789).toUnitVector(); + this.shape.setSecondAxis(newV); + assertEpsilonEquals(cx, this.shape.getCenterX()); + assertEpsilonEquals(cy, this.shape.getCenterY()); + assertEpsilonEquals(ux, this.shape.getFirstAxisX()); + assertEpsilonEquals(uy, this.shape.getFirstAxisY()); + assertEpsilonEquals(e1, this.shape.getFirstAxisExtent()); + assertEpsilonEquals(newV.getX(), this.shape.getSecondAxisX()); + assertEpsilonEquals(newV.getY(), this.shape.getSecondAxisY()); + assertEpsilonEquals(e2, this.shape.getSecondAxisExtent()); + } + + @Test(expected = AssertionError.class) + public void setSecondAxisVector2D_notUnitVector() { + this.shape.setSecondAxis(createVector(123.456, 456.789)); + } + + @Test + public void setSecondAxisVector2DDouble() { + Vector2D newV = createVector(123.456, 456.789).toUnitVector(); + this.shape.setSecondAxis(newV, 159.753); + assertEpsilonEquals(cx, this.shape.getCenterX()); + assertEpsilonEquals(cy, this.shape.getCenterY()); + assertEpsilonEquals(ux, this.shape.getFirstAxisX()); + assertEpsilonEquals(uy, this.shape.getFirstAxisY()); + assertEpsilonEquals(e1, this.shape.getFirstAxisExtent()); + assertEpsilonEquals(newV.getX(), this.shape.getSecondAxisX()); + assertEpsilonEquals(newV.getY(), this.shape.getSecondAxisY()); + assertEpsilonEquals(159.753, this.shape.getSecondAxisExtent()); + } + + @Test + public void setSecondAxisDoubleDoubleDouble() { + Vector2D newV = createVector(123.456, 456.789).toUnitVector(); + this.shape.setSecondAxis(newV.getX(), newV.getY(), 159.753); + assertEpsilonEquals(cx, this.shape.getCenterX()); + assertEpsilonEquals(cy, this.shape.getCenterY()); + assertEpsilonEquals(ux, this.shape.getFirstAxisX()); + assertEpsilonEquals(uy, this.shape.getFirstAxisY()); + assertEpsilonEquals(e1, this.shape.getFirstAxisExtent()); + assertEpsilonEquals(newV.getX(), this.shape.getSecondAxisX()); + assertEpsilonEquals(newV.getY(), this.shape.getSecondAxisY()); + assertEpsilonEquals(159.753, this.shape.getSecondAxisExtent()); + } + + @Test + public void setDoubleDoubleDoubleDoubleDoubleDoubleDoubleDouble() { + Vector2D newU = createVector(-456.789, 159.753).toUnitVector(); + Vector2D newV = createVector(123.456, 456.789).toUnitVector(); + this.shape.set(-6, -4, newU.getX(), newU.getY(), 147.369, newV.getX(), newV.getY(), 159.753); + assertEpsilonEquals(-6, this.shape.getCenterX()); + assertEpsilonEquals(-4, this.shape.getCenterY()); + assertEpsilonEquals(newU.getX(), this.shape.getFirstAxisX()); + assertEpsilonEquals(newU.getY(), this.shape.getFirstAxisY()); + assertEpsilonEquals(147.369, this.shape.getFirstAxisExtent()); + assertEpsilonEquals(newV.getX(), this.shape.getSecondAxisX()); + assertEpsilonEquals(newV.getY(), this.shape.getSecondAxisY()); + assertEpsilonEquals(159.753, this.shape.getSecondAxisExtent()); + } + + @Test + public void setPoint2DVector2DDoubleVector2DDouble() { + Vector2D newU = createVector(-456.789, 159.753).toUnitVector(); + Vector2D newV = createVector(123.456, 456.789).toUnitVector(); + this.shape.set(createPoint(-6, -4), newU, 147.369, newV, 159.753); + assertEpsilonEquals(-6, this.shape.getCenterX()); + assertEpsilonEquals(-4, this.shape.getCenterY()); + assertEpsilonEquals(newU.getX(), this.shape.getFirstAxisX()); + assertEpsilonEquals(newU.getY(), this.shape.getFirstAxisY()); + assertEpsilonEquals(147.369, this.shape.getFirstAxisExtent()); + assertEpsilonEquals(newV.getX(), this.shape.getSecondAxisX()); + assertEpsilonEquals(newV.getY(), this.shape.getSecondAxisY()); + assertEpsilonEquals(159.753, this.shape.getSecondAxisExtent()); + } + + @Test + public void setFromPointCloudIterable() { + double obrux = 0.8944271909999159; + double obruy = -0.4472135954999579; + double obre1 = 13.99999; + double obrvx = 0.4472135954999579; + double obrvy = 0.8944271909999159; + double obre2 = 12.99999; + + this.shape.setFromPointCloud((List) Arrays.asList( + createPoint(11.7082, -0.94427), createPoint(16.18034, 8), + createPoint(-1.7082, 16.94427), createPoint(-6.18034, 8))); + + assertEpsilonEquals(5, this.shape.getCenterX()); + assertEpsilonEquals(8, this.shape.getCenterY()); + assertEpsilonEquals(obrux, this.shape.getFirstAxisX()); + assertEpsilonEquals(obruy, this.shape.getFirstAxisY()); + assertEpsilonEquals(10, this.shape.getFirstAxisExtent()); + assertEpsilonEquals(obrvx, this.shape.getSecondAxisX()); + assertEpsilonEquals(obrvy, this.shape.getSecondAxisY()); + assertEpsilonEquals(5, this.shape.getSecondAxisExtent()); + } + + @Test + public void setFromPointCloudPoint2DArray() { + double obrux = 0.8944271909999159; + double obruy = -0.4472135954999579; + double obre1 = 13.99999; + double obrvx = 0.4472135954999579; + double obrvy = 0.8944271909999159; + double obre2 = 12.99999; + + this.shape.setFromPointCloud( + createPoint(11.7082, -0.94427), createPoint(16.18034, 8), + createPoint(-1.7082, 16.94427), createPoint(-6.18034, 8)); + + assertEpsilonEquals(5, this.shape.getCenterX()); + assertEpsilonEquals(8, this.shape.getCenterY()); + assertEpsilonEquals(obrux, this.shape.getFirstAxisX()); + assertEpsilonEquals(obruy, this.shape.getFirstAxisY()); + assertEpsilonEquals(10, this.shape.getFirstAxisExtent()); + assertEpsilonEquals(obrvx, this.shape.getSecondAxisX()); + assertEpsilonEquals(obrvy, this.shape.getSecondAxisY()); + assertEpsilonEquals(5, this.shape.getSecondAxisExtent()); + } + + @Override + public void intersectsCircle2afp() { + assertFalse(this.shape.intersects(createCircle(.5, .5, .5))); + assertFalse(this.shape.intersects(createCircle(.5, 1.5, .5))); + assertFalse(this.shape.intersects(createCircle(.5, 2.5, .5))); + assertTrue(this.shape.intersects(createCircle(.5, 3.5, .5))); + assertTrue(this.shape.intersects(createCircle(4.5, 3.5, .5))); + assertFalse(this.shape.intersects(createCircle(10, -7, .5))); + assertFalse(this.shape.intersects(createCircle(10.1, -7, .5))); + assertTrue(this.shape.intersects(createCircle(10.2, -7, .5))); + assertTrue(this.shape.intersects(createCircle(10, -1, 5))); + } + + @Override + public void intersectsEllipse2afp() { + assertFalse(this.shape.intersects(createEllipse(0, 0, 2, 1))); + assertFalse(this.shape.intersects(createEllipse(0, 1, 2, 1))); + assertTrue(this.shape.intersects(createEllipse(0, 2, 2, 1))); + assertTrue(this.shape.intersects(createEllipse(0, 3, 2, 1))); + assertTrue(this.shape.intersects(createEllipse(0, 4, 2, 1))); + assertTrue(this.shape.intersects(createEllipse(1, 3, 2, 1))); + assertTrue(this.shape.intersects(createEllipse(5, 5, 2, 1))); + assertFalse(this.shape.intersects(createEllipse(0.1, 1, 2, 1))); + assertFalse(this.shape.intersects(createEllipse(0.2, 1, 2, 1))); + assertTrue(this.shape.intersects(createEllipse(0.3, 1, 2, 1))); + assertTrue(this.shape.intersects(createEllipse(0.4, 1, 2, 1))); + assertFalse(this.shape.intersects(createEllipse(-7, 7.5, 2, 1))); + } + + @Override + public void intersectsSegment2afp() { + assertFalse(this.shape.intersects(createSegment(0, 0, 1, 1))); + assertTrue(this.shape.intersects(createSegment(5, 5, 4, 6))); + assertTrue(this.shape.intersects(createSegment(2, -2, 5, 0))); + assertFalse(this.shape.intersects(createSegment(-20, -5, -10, 6))); + assertFalse(this.shape.intersects(createSegment(-5, 0, -10, 16))); + assertTrue(this.shape.intersects(createSegment(-10, 1, 10, 20))); + } + + @Override + public void intersectsPath2afp() { + Path2afp path = createPath(); + path.moveTo(-15, 2); + path.lineTo(6, -9); + path.lineTo(19, -9); + path.lineTo(20, 26); + path.lineTo(-6, 30); + assertFalse(this.shape.intersects(path)); + path.closePath(); + assertTrue(this.shape.intersects(path)); + } + + @Override + public void intersectsPathIterator2afp() { + Path2afp path = createPath(); + path.moveTo(-15, 2); + path.lineTo(6, -9); + path.lineTo(19, -9); + path.lineTo(20, 26); + path.lineTo(-6, 30); + assertFalse(this.shape.intersects(path.getPathIterator())); + path.closePath(); + assertTrue(this.shape.intersects(path.getPathIterator())); + } + + @Override + public void intersectsTriangle2afp() { + assertTrue(this.shape.intersects(createTriangle(-5, 15, -3, 16, -8, 19))); + assertTrue(this.shape.intersects(createTriangle(-5, 15, -8, 19, -3, 16))); + assertFalse(this.shape.intersects(createTriangle(0, -5, 2, -4, -3, -1))); + assertFalse(this.shape.intersects(createTriangle(0, -5, -3, -1, 2, -4))); + assertFalse(this.shape.intersects(createTriangle(20, 0, 22, 1, 17, 4))); + assertFalse(this.shape.intersects(createTriangle(20, 0, 17, 4, 22, 1))); + assertFalse(this.shape.intersects(createTriangle(17.18034, 9, 19.18034, 10, 14.18034, 13))); + assertFalse(this.shape.intersects(createTriangle(17.18034, 9, 14.18034, 13, 19.18034, 10))); + assertTrue(this.shape.intersects(createTriangle(0, 10, 2, 11, -3, 14))); + assertTrue(this.shape.intersects(createTriangle(0, 10, -3, 14, 2, 11))); + assertTrue(this.shape.intersects(createTriangle(0, 20, 2, 21, -3, 24))); + } + + @Override + public void intersectsRectangle2afp() { + assertFalse(this.shape.intersects(createRectangle(0, 0, 1, 1))); + assertTrue(this.shape.intersects(createRectangle(0, 2, 1, 1))); + assertTrue(this.shape.intersects(createRectangle(-5.5, 8.5, 1, 1))); + assertFalse(this.shape.intersects(createRectangle(-6, 16, 1, 1))); + assertFalse(this.shape.intersects(createRectangle(146, 16, 1, 1))); + assertTrue(this.shape.intersects(createRectangle(12, 14, 1, 1))); + assertTrue(this.shape.intersects(createRectangle(0, 8, 1, 1))); + assertTrue(this.shape.intersects(createRectangle(10, -1, 1, 1))); + assertTrue(this.shape.intersects(createRectangle(-15, -10, 35, 40))); + } + + @Override + public void intersectsParallelogram2afp() { + double ux2 = -0.9284766908852592; + double uy2 = 0.3713906763541037; + double et1 = 5; + double vx2 = 0.3713906763541037; + double vy2 = 0.9284766908852592; + double et2 = 3; + assertFalse(this.shape.intersects(createParallelogram(-10, 0, + ux2, uy2, et1, vx2, vy2, et2))); + assertFalse(this.shape.intersects(createParallelogram(-15, 25, + ux2, uy2, et1, vx2, vy2, et2))); + assertFalse(this.shape.intersects(createParallelogram(2, -6, + ux2, uy2, et1, vx2, vy2, et2))); + assertFalse(this.shape.intersects(createParallelogram(2, -5, + ux2, uy2, et1, vx2, vy2, et2))); + assertTrue(this.shape.intersects(createParallelogram(2, -4, + ux2, uy2, et1, vx2, vy2, et2))); + assertTrue(this.shape.intersects(createParallelogram(pEx, pEy, + ux2, uy2, et1, vx2, vy2, et2))); + assertTrue(this.shape.intersects(createParallelogram(6, 6, + ux2, uy2, et1, vx2, vy2, et2))); + assertTrue(this.shape.intersects(createParallelogram(6, 6, + ux2, uy2, 10 * et1, vx2, vy2, 10 * et2))); + } + + @Override + public void intersectsRoundRectangle2afp() { + assertFalse(this.shape.intersects(createRoundRectangle(0, 0, 1, 1, .1, .05))); + assertTrue(this.shape.intersects(createRoundRectangle(0, 2, 1, 1, .1, .05))); + assertTrue(this.shape.intersects(createRoundRectangle(-5.5, 8.5, 1, 1, .1, .05))); + assertFalse(this.shape.intersects(createRoundRectangle(-6, 16, 1, 1, .1, .05))); + assertFalse(this.shape.intersects(createRoundRectangle(146, 16, 1, 1, .1, .05))); + assertTrue(this.shape.intersects(createRoundRectangle(12, 14, 1, 1, .1, .05))); + assertTrue(this.shape.intersects(createRoundRectangle(0, 8, 1, 1, .1, .05))); + assertTrue(this.shape.intersects(createRoundRectangle(10, -1, 1, 1, .1, .05))); + assertTrue(this.shape.intersects(createRoundRectangle(-15, -10, 35, 40, .1, .05))); + assertFalse(this.shape.intersects(createRoundRectangle(-4.79634, 14.50886, 1, 1, .1, .05))); + } + + @Override + public void intersectsOrientedRectangle2afp() { + OrientedRectangle2afp rectangle = createOrientedRectangle( + 6, 9, + 0.894427190999916, -0.447213595499958, 13.999990000000002, + 12.999989999999997); + double ux2 = 0.55914166827779; + double uy2 = 0.829072128825671; + double et1 = 10; + double vx2 = -0.989660599000356; + double vy2 = -0.143429072318889; + double et2 = 15; + assertFalse(createParallelogram( + -20, -20, ux2, uy2, et1, vx2, vy2, et2).intersects(rectangle)); + assertFalse(createParallelogram( + -40, 20, ux2, uy2, et1, vx2, vy2, et2).intersects(rectangle)); + assertTrue(createParallelogram( + -20, -10, ux2, uy2, et1, vx2, vy2, et2).intersects(rectangle)); + assertTrue(createParallelogram( + 10, -10, ux2, uy2, et1, vx2, vy2, et2).intersects(rectangle)); + assertTrue(createParallelogram( + 5, 5, ux2, uy2, et1, vx2, vy2, et2).intersects(rectangle)); + } + + @Override + public void intersectsShape2D() { + assertTrue(this.shape.intersects((Shape2D) createCircle(.5, 3.5, .5))); + assertTrue(this.shape.intersects((Shape2D) createRectangle(12, 14, 1, 1))); + } + + @Override + public void operator_addVector2D() { + this.shape.operator_add(createVector(123.456, 789.123)); + assertEpsilonEquals(cx + 123.456, this.shape.getCenterX()); + assertEpsilonEquals(cy + 789.123, this.shape.getCenterY()); + assertEpsilonEquals(ux, this.shape.getFirstAxisX()); + assertEpsilonEquals(uy, this.shape.getFirstAxisY()); + assertEpsilonEquals(e1, this.shape.getFirstAxisExtent()); + assertEpsilonEquals(vx, this.shape.getSecondAxisX()); + assertEpsilonEquals(vy, this.shape.getSecondAxisY()); + assertEpsilonEquals(e2, this.shape.getSecondAxisExtent()); + } + + @Override + public void operator_plusVector2D() { + T shape = this.shape.operator_plus(createVector(123.456, 789.123)); + assertEpsilonEquals(cx + 123.456, shape.getCenterX()); + assertEpsilonEquals(cy + 789.123, shape.getCenterY()); + assertEpsilonEquals(ux, shape.getFirstAxisX()); + assertEpsilonEquals(uy, shape.getFirstAxisY()); + assertEpsilonEquals(e1, shape.getFirstAxisExtent()); + assertEpsilonEquals(vx, shape.getSecondAxisX()); + assertEpsilonEquals(vy, shape.getSecondAxisY()); + assertEpsilonEquals(e2, shape.getSecondAxisExtent()); + } + + @Override + public void operator_removeVector2D() { + this.shape.operator_remove(createVector(123.456, 789.123)); + assertEpsilonEquals(cx - 123.456, this.shape.getCenterX()); + assertEpsilonEquals(cy - 789.123, this.shape.getCenterY()); + assertEpsilonEquals(ux, this.shape.getFirstAxisX()); + assertEpsilonEquals(uy, this.shape.getFirstAxisY()); + assertEpsilonEquals(e1, this.shape.getFirstAxisExtent()); + assertEpsilonEquals(vx, this.shape.getSecondAxisX()); + assertEpsilonEquals(vy, this.shape.getSecondAxisY()); + assertEpsilonEquals(e2, this.shape.getSecondAxisExtent()); + } + + @Override + public void operator_minusVector2D() { + T shape = this.shape.operator_minus(createVector(123.456, 789.123)); + assertEpsilonEquals(cx - 123.456, shape.getCenterX()); + assertEpsilonEquals(cy - 789.123, shape.getCenterY()); + assertEpsilonEquals(ux, shape.getFirstAxisX()); + assertEpsilonEquals(uy, shape.getFirstAxisY()); + assertEpsilonEquals(e1, shape.getFirstAxisExtent()); + assertEpsilonEquals(vx, shape.getSecondAxisX()); + assertEpsilonEquals(vy, shape.getSecondAxisY()); + assertEpsilonEquals(e2, shape.getSecondAxisExtent()); + } + + @Override + public void operator_multiplyTransform2D() { + PathIterator2afp pi = this.shape.operator_multiply(null).getPathIterator(); + assertElement(pi, PathElementType.MOVE_TO, pGx, pGy); + assertElement(pi, PathElementType.LINE_TO, pHx, pHy); + assertElement(pi, PathElementType.LINE_TO, pEx, pEy); + assertElement(pi, PathElementType.LINE_TO, pFx, pFy); + assertElement(pi, PathElementType.CLOSE, pGx, pGy); + assertNoElement(pi); + + Transform2D transform; + + transform = new Transform2D(); + pi = this.shape.operator_multiply(transform).getPathIterator(); + assertElement(pi, PathElementType.MOVE_TO, pGx, pGy); + assertElement(pi, PathElementType.LINE_TO, pHx, pHy); + assertElement(pi, PathElementType.LINE_TO, pEx, pEy); + assertElement(pi, PathElementType.LINE_TO, pFx, pFy); + assertElement(pi, PathElementType.CLOSE, pGx, pGy); + assertNoElement(pi); + + transform = new Transform2D(); + transform.setTranslation(18, -45); + pi = this.shape.operator_multiply(transform).getPathIterator(); + assertElement(pi, PathElementType.MOVE_TO, pGx + 18, pGy - 45); + assertElement(pi, PathElementType.LINE_TO, pHx + 18, pHy - 45); + assertElement(pi, PathElementType.LINE_TO, pEx + 18, pEy - 45); + assertElement(pi, PathElementType.LINE_TO, pFx + 18, pFy - 45); + assertElement(pi, PathElementType.CLOSE, pGx + 18, pGy - 45); + assertNoElement(pi); + } + + @Override + public void operator_andPoint2D() { + assertFalse(this.shape.operator_and(createPoint(0, 0))); + assertFalse(this.shape.operator_and(createPoint(-20, 0))); + assertTrue(this.shape.operator_and(createPoint(12, -4))); + assertTrue(this.shape.operator_and(createPoint(14, 0))); + assertFalse(this.shape.operator_and(createPoint(15, 0))); + assertFalse(this.shape.operator_and(createPoint(20, 8))); + assertTrue(this.shape.operator_and(createPoint(8, 16))); + assertFalse(this.shape.operator_and(createPoint(-4, 20))); + assertFalse(this.shape.operator_and(createPoint(-5, 12))); + assertTrue(this.shape.operator_and(createPoint(0, 6))); + assertTrue(this.shape.operator_and(createPoint(0, 7))); + assertTrue(this.shape.operator_and(createPoint(0, 8))); + assertTrue(this.shape.operator_and(createPoint(0, 9))); + assertTrue(this.shape.operator_and(createPoint(0, 10))); + assertFalse(this.shape.operator_and(createPoint(0, 27))); + assertTrue(this.shape.operator_and(createPoint(cx, cy))); + assertTrue(this.shape.operator_and(createPoint( 16, 8))); + } + + @Override + public void operator_andShape2D() { + assertTrue(this.shape.operator_and(createCircle(.5, 3.5, .5))); + assertTrue(this.shape.operator_and(createRectangle(12, 14, 1, 1))); + } + + @Override + public void operator_upToPoint2D() { + assertEpsilonEquals(14.81966, this.shape.operator_upTo(createPoint(-20, 9))); + assertEpsilonEquals(2.7009, this.shape.operator_upTo(createPoint(0, 0))); + assertEpsilonEquals(6.23644, this.shape.operator_upTo(createPoint(5, -10))); + assertEpsilonEquals(11.1863, this.shape.operator_upTo(createPoint(14, -20))); + assertEpsilonEquals(2.25040, this.shape.operator_upTo(createPoint(-6, 15))); + assertEpsilonEquals(0, this.shape.operator_upTo(createPoint(0, 10))); + assertEpsilonEquals(0, this.shape.operator_upTo(createPoint(10, 0))); + assertEpsilonEquals(1.03772, this.shape.operator_upTo(createPoint(15, -4))); + assertEpsilonEquals(3.70561, this.shape.operator_upTo(createPoint(-5, 25))); + assertEpsilonEquals(0, this.shape.operator_upTo(createPoint(0, 20))); + assertEpsilonEquals(0, this.shape.operator_upTo(createPoint(10, 10))); + assertEpsilonEquals(4.91829, this.shape.operator_upTo(createPoint(20, 0))); + assertEpsilonEquals(8.42901, this.shape.operator_upTo(createPoint(-3, 35))); + assertEpsilonEquals(9.91864, this.shape.operator_upTo(createPoint(5, 35))); + assertEpsilonEquals(6.23644, this.shape.operator_upTo(createPoint(20, 15))); + assertEpsilonEquals(17.8477, this.shape.operator_upTo(createPoint(35, 10))); + assertEpsilonEquals(7.59135, this.shape.operator_upTo(createPoint(-8, 29))); + } + + @Test + public void isCCW() { + assertTrue(this.shape.isCCW()); + assertTrue(createParallelogram(cx, cy, ux, uy, e1, vx, vy, e2).isCCW()); + assertTrue(createParallelogram( + 4.7, 15, + 0.12403, 0.99228, 18.02776, + -0.44721, 0.89443, 20).isCCW()); + assertTrue(createParallelogram( + -10, -3, + -.8944271909999159, .4472135954999579, 2, + .5547001962252290, -.8320502943378436, 1).isCCW()); + assertFalse(createParallelogram( + -10, 7, + -0.9863939238321437, 0.1643989873053573, 1, + 0.9998000599800071, 0.01999600119960014, 2).isCCW()); + assertFalse(createParallelogram( + 0, -6, + -0.9863939238321437, 0.1643989873053573, 1, + 0.9998000599800071, 0.01999600119960014, 2).isCCW()); + } + + @Test + public void getClosestPointToCircle2afp() { + assertFpPointEquals(0.90983, 2.90983, this.shape.getClosestPointTo(createCircle(0, 2, 1))); + assertFpPointEquals(-5.18034, 9, this.shape.getClosestPointTo(createCircle(-12, 8, 1))); + assertClosestPointInBothShapes(this.shape, createCircle(16, 2, 1)); + assertClosestPointInBothShapes(this.shape, createCircle(12, 10, 1)); + } + + @Test + public void getDistanceSquaredCircle2afp() { + assertEpsilonEquals(0.08219, this.shape.getDistanceSquared(createCircle(0, 2, 1))); + assertEpsilonEquals(34.72259, this.shape.getDistanceSquared(createCircle(-12, 8, 1))); + assertEpsilonEquals(0, this.shape.getDistanceSquared(createCircle(16, 2, 1))); + assertEpsilonEquals(0, this.shape.getDistanceSquared(createCircle(12, 10, 1))); + } + + @Test + public void getClosestPointToSegment2afp() { + assertFpPointEquals(0.40983, 3.40983, this.shape.getClosestPointTo(createSegment(-2, 2, 0, 3))); + assertFpPointEquals(-5.18034, 9, this.shape.getClosestPointTo(createSegment(-12, 8, -10, 9))); + assertClosestPointInBothShapes(this.shape, createSegment(15, 2, 17, 3)); + assertClosestPointInBothShapes(this.shape, createSegment(12, 10, 14, 11)); + } + + @Test + public void getDistanceSquaredSegment2afp() { + assertEpsilonEquals(0.33592, this.shape.getDistanceSquared(createSegment(-2, 2, 0, 3))); + assertEpsilonEquals(23.22912, this.shape.getDistanceSquared(createSegment(-12, 8, -10, 9))); + assertEpsilonEquals(0, this.shape.getDistanceSquared(createSegment(15, 2, 17, 3))); + assertEpsilonEquals(0, this.shape.getDistanceSquared(createSegment(12, 10, 14, 11))); + } + + protected Triangle2afp createTestTriangle(double dx, double dy) { + return createTriangle(dx, dy, dx + 6, dy + 3, dx - 1, dy + 2.5); + } + + @Test + public void getClosestPointToTriangle2afp() { + assertFpPointEquals(3.40983, 0.40983, this.shape.getClosestPointTo(createTestTriangle(-5, -5))); + assertFpPointEquals(-5.18034, 9, this.shape.getClosestPointTo(createTestTriangle(-14, 5))); + assertClosestPointInBothShapes(this.shape, createTestTriangle(15, 2)); + assertClosestPointInBothShapes(this.shape, createTestTriangle(5, 5)); + } + + @Test + public void getDistanceSquaredTriangle2afp() { + assertEpsilonEquals(11.61456, this.shape.getDistanceSquared(createTestTriangle(-5, -5))); + assertEpsilonEquals(8.95048, this.shape.getDistanceSquared(createTestTriangle(-14, 5))); + assertEpsilonEquals(0, this.shape.getDistanceSquared(createTestTriangle(15, 2))); + assertEpsilonEquals(0, this.shape.getDistanceSquared(createTestTriangle(5, 5))); + } + + @Test + public void getClosestPointToRectangle2afp() { + assertFpPointEquals(2.40983, 1.40983, this.shape.getClosestPointTo(createRectangle(-5, -5, 2, 1))); + assertFpPointEquals(-5.18034, 9, this.shape.getClosestPointTo(createRectangle(-14, 5, 2, 1))); + assertClosestPointInBothShapes(this.shape, createRectangle(15, 2, 2, 1)); + assertClosestPointInBothShapes(this.shape, createRectangle(5, 5, 2, 1)); + } + + @Test + public void getDistanceSquaredRectangle2afp() { + assertEpsilonEquals(58.53252, this.shape.getDistanceSquared(createRectangle(-5, -5, 2, 1))); + assertEpsilonEquals(55.50776, this.shape.getDistanceSquared(createRectangle(-14, 5, 2, 1))); + assertEpsilonEquals(0, this.shape.getDistanceSquared(createRectangle(15, 2, 2, 1))); + assertEpsilonEquals(0, this.shape.getDistanceSquared(createRectangle(5, 5, 2, 1))); + } + + @Test + public void getClosestPointToEllipse2afp() { + assertFpPointEquals(2.52323, 1.29643, this.shape.getClosestPointTo(createEllipse(-5, -5, 2, 1))); + assertFpPointEquals(-5.18034, 9, this.shape.getClosestPointTo(createEllipse(-14, 5, 2, 1))); + assertClosestPointInBothShapes(this.shape, createRectangle(15, 2, 2, 1)); + assertClosestPointInBothShapes(this.shape, createRectangle(5, 5, 2, 1)); + } + + @Test + public void getDistanceSquaredEllipse2afp() { + assertEpsilonEquals(62.73969, this.shape.getDistanceSquared(createEllipse(-5, -5, 2, 1))); + assertEpsilonEquals(58.33165, this.shape.getDistanceSquared(createEllipse(-14, 5, 2, 1))); + assertEpsilonEquals(0, this.shape.getDistanceSquared(createEllipse(15, 2, 2, 1))); + assertEpsilonEquals(0, this.shape.getDistanceSquared(createEllipse(5, 5, 2, 1))); + } + + @Test + public void getClosestPointToRoundRectangle2afp() { + assertFpPointEquals(2.39519, 1.42447, this.shape.getClosestPointTo(createRoundRectangle(-5, -5, 2, 1, .2, .1))); + assertFpPointEquals(-5.18034, 9, this.shape.getClosestPointTo(createRoundRectangle(-14, 5, 2, 1, .2, .1))); + assertClosestPointInBothShapes(this.shape, createRoundRectangle(15, 2, 2, 1, .2, .1)); + assertClosestPointInBothShapes(this.shape, createRoundRectangle(5, 5, 2, 1, .2, .1)); + } + + @Test + public void getDistanceSquaredRoundRectangle2afp() { + assertEpsilonEquals(59.36397, this.shape.getDistanceSquared(createRoundRectangle(-5, -5, 2, 1, .2, .1))); + assertEpsilonEquals(56.0487, this.shape.getDistanceSquared(createRoundRectangle(-14, 5, 2, 1, .2, .1))); + assertEpsilonEquals(0, this.shape.getDistanceSquared(createRoundRectangle(15, 2, 2, 1, .2, .1))); + assertEpsilonEquals(0, this.shape.getDistanceSquared(createRoundRectangle(5, 5, 2, 1, .2, .1))); + } + + protected MultiShape2afp createTestMultiShape(double dx, double dy) { + Circle2afp circle = createCircle(dx - 3, dy + 2, 2); + Triangle2afp triangle = createTestTriangle(dx +1, dy - 1); + MultiShape2afp multishape = createMultiShape(); + multishape.add(circle); + multishape.add(triangle); + return multishape; + } + + @Test + public void getClosestPointToMultiShape2afp() { + assertFpPointEquals(4.40983, -0.59017, this.shape.getClosestPointTo(createTestMultiShape(-5, -5))); + assertFpPointEquals(-5.18034, 9, this.shape.getClosestPointTo(createTestMultiShape(-18, 5))); + assertClosestPointInBothShapes(this.shape, createTestMultiShape(15, 2)); + assertClosestPointInBothShapes(this.shape, createTestMultiShape(5, 5)); + } + + @Test + public void getDistanceSquaredMultiShape2afp() { + assertEpsilonEquals(11.61456, this.shape.getDistanceSquared(createTestMultiShape(-5, -5))); + assertEpsilonEquals(37.86844, this.shape.getDistanceSquared(createTestMultiShape(-18, 5))); + assertEpsilonEquals(0, this.shape.getDistanceSquared(createTestMultiShape(15, 2))); + assertEpsilonEquals(0, this.shape.getDistanceSquared(createTestMultiShape(5, 5))); + } + + protected Path2afp createNonEmptyPath(double x, double y) { + Path2afp path = createPath(); + path.moveTo(x, y); + path.lineTo(x + 1, y + .5); + path.lineTo(x, y + 1); + return path; + } + + @Test + public void getClosestPointToPath2afp() { + assertFpPointEquals(2.15983, 1.65983, this.shape.getClosestPointTo(createNonEmptyPath(-5, -5))); + assertFpPointEquals(-5.18034, 9, this.shape.getClosestPointTo(createNonEmptyPath(-18, 5))); + assertClosestPointInBothShapes(this.shape, createNonEmptyPath(15, 2)); + assertClosestPointInBothShapes(this.shape, createNonEmptyPath(5, 5)); + } + + @Test + public void getDistanceSquaredPath2afp() { + assertEpsilonEquals(75.88701, this.shape.getDistanceSquared(createNonEmptyPath(-5, -5))); + assertEpsilonEquals(151.95437, this.shape.getDistanceSquared(createNonEmptyPath(-18, 5))); + assertEpsilonEquals(0, this.shape.getDistanceSquared(createNonEmptyPath(15, 2))); + assertEpsilonEquals(0, this.shape.getDistanceSquared(createNonEmptyPath(5, 5))); + } + + protected Parallelogram2afp createTestParallelogram(double dx, double dy) { + Vector2D r = createVector(4, 1).toUnitVector(); + Vector2D s = createVector(-1, -1).toUnitVector(); + return createParallelogram(dx, dy, r.getX(), r.getY(), 2, s.getX(), s.getY(), 1); + } + + @Test + public void getClosestPointToParallelogram2afp() { + assertFpPointEquals(2.63744, 1.18222, this.shape.getClosestPointTo(createTestParallelogram(-5, -5))); + assertFpPointEquals(-5.18034, 9, this.shape.getClosestPointTo(createTestParallelogram(-18, 5))); + assertClosestPointInBothShapes(this.shape, createTestParallelogram(15, 2)); + assertClosestPointInBothShapes(this.shape, createTestParallelogram(5, 5)); + } + + @Test + public void getDistanceSquaredParallelogram2afp() { + assertEpsilonEquals(49.8011, this.shape.getDistanceSquared(createTestParallelogram(-5, -5))); + assertEpsilonEquals(111.35891, this.shape.getDistanceSquared(createTestParallelogram(-18, 5))); + assertEpsilonEquals(0, this.shape.getDistanceSquared(createTestParallelogram(15, 2))); + assertEpsilonEquals(0, this.shape.getDistanceSquared(createTestParallelogram(5, 5))); + } + + protected OrientedRectangle2afp createTestOrientedRectangle(double dx, double dy) { + Vector2D r = createVector(4, 1).toUnitVector(); + return createOrientedRectangle(dx, dy, r.getX(), r.getY(), 2, 1); + } + + @Test + public void getClosestPointToOrientedRectangle2afp() { + assertFpPointEquals(2.0311, 1.78856, this.shape.getClosestPointTo(createTestOrientedRectangle(-5, -5))); + assertFpPointEquals(-5.18034, 9, this.shape.getClosestPointTo(createTestOrientedRectangle(-18, 5))); + assertClosestPointInBothShapes(this.shape, createTestOrientedRectangle(15, 2)); + assertClosestPointInBothShapes(this.shape, createTestOrientedRectangle(5, 5)); + } + + @Test + public void getDistanceSquaredOrientedRectangle2afp() { + assertEpsilonEquals(56.88921, this.shape.getDistanceSquared(createTestOrientedRectangle(-5, -5))); + assertEpsilonEquals(130.12055, this.shape.getDistanceSquared(createTestOrientedRectangle(-18, 5))); + assertEpsilonEquals(0, this.shape.getDistanceSquared(createTestOrientedRectangle(15, 2))); + assertEpsilonEquals(0, this.shape.getDistanceSquared(createTestOrientedRectangle(5, 5))); + } + } \ No newline at end of file diff --git a/core/math/src/test/resources/org/arakhne/afc/math/geometry/d2/d/orientedrectangle.ggb b/core/math/src/test/resources/org/arakhne/afc/math/geometry/d2/d/orientedrectangle.ggb index f977d708912a18c415939b1f2ae4b31e3b30018f..2af3d16fdfbfc04d0b56b73b2284982c092a815e 100644 GIT binary patch delta 9910 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 a{{#K^ss7<6|I1o1Q|hURpsHy9UHgArhq3(t delta 8839 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 delta 10196 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