Skip to content

Commit

Permalink
(#3) Add unit tests for Polygon2D class
Browse files Browse the repository at this point in the history
Issues Fixed:
- Fixed issue with incorrect floating point 'equality' calculations -- floating point equality is now considered to be at least under `Maths.FloatPrecision`, or `0.000001f`.

Other Changes:
- Changed `Polygon2D#modifyPoints` to set translation, rotation, and scale to, if requested, the default game object translation, rotation, and scale.
  • Loading branch information
lucasstarsz committed Apr 12, 2021
1 parent 822af49 commit d192617
Show file tree
Hide file tree
Showing 5 changed files with 149 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import io.github.lucasstarsz.fastj.graphics.Boundary;
import io.github.lucasstarsz.fastj.graphics.DrawUtil;
import io.github.lucasstarsz.fastj.graphics.GameObject;
import io.github.lucasstarsz.fastj.math.Maths;
import io.github.lucasstarsz.fastj.math.Pointf;
import io.github.lucasstarsz.fastj.systems.game.Scene;

Expand Down Expand Up @@ -236,7 +237,7 @@ public boolean equals(Object other) {
Model2D otherModel2D = (Model2D) other;
return Objects.equals(translation, otherModel2D.translation)
&& Objects.equals(scale, otherModel2D.scale)
&& Float.compare(otherModel2D.rotation, rotation) == 0
&& Math.abs(otherModel2D.rotation - rotation) < Maths.FloatPrecision
&& Arrays.equals(polyArr, otherModel2D.polyArr)
&& Objects.equals(collisionObject, otherModel2D.collisionObject);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import io.github.lucasstarsz.fastj.graphics.Boundary;
import io.github.lucasstarsz.fastj.graphics.DrawUtil;
import io.github.lucasstarsz.fastj.graphics.GameObject;
import io.github.lucasstarsz.fastj.math.Maths;
import io.github.lucasstarsz.fastj.math.Pointf;
import io.github.lucasstarsz.fastj.systems.game.Scene;

Expand Down Expand Up @@ -196,13 +197,13 @@ public void modifyPoints(Pointf[] pts, boolean resetTranslation, boolean resetRo
renderPath = DrawUtil.createPath(points);

if (resetTranslation) {
translation.reset();
translation.set(GameObject.defaultTranslation.x, GameObject.defaultTranslation.y);
}
if (resetRotation) {
rotation = 0;
rotation = GameObject.defaultRotation;
}
if (resetScale) {
scale.set(1, 1);
scale.set(GameObject.defaultScale.x, GameObject.defaultScale.y);
}

setBoundaries(renderPath);
Expand Down Expand Up @@ -328,7 +329,7 @@ public boolean equals(Object other) {
&& Objects.equals(color, otherPolygon2D.color)
&& Objects.equals(translation, otherPolygon2D.translation)
&& Objects.equals(scale, otherPolygon2D.scale)
&& Float.compare(otherPolygon2D.rotation, rotation) == 0
&& Math.abs(otherPolygon2D.rotation - rotation) < Maths.FloatPrecision
&& Arrays.equals(points, otherPolygon2D.points)
&& Arrays.equals(DrawUtil.pointsOfPath(renderPath), DrawUtil.pointsOfPath(otherPolygon2D.renderPath));
}
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/io/github/lucasstarsz/fastj/math/Point.java
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@ public Pointf asPointf() {
* @return Whether the two's {@code x} and {@code y} values are equal.
*/
public boolean equalsPointf(Pointf other) {
return Float.compare(other.x, (float) x) == 0 && Float.compare(other.y, (float) y) == 0;
return Math.abs(other.x - (float) x) < Maths.FloatPrecision && Math.abs(other.y - (float) y) < Maths.FloatPrecision;
}

/**
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/io/github/lucasstarsz/fastj/math/Pointf.java
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ public Pointf divide(float f) {
* @return Whether the two's {@code x} and {@code y} values are equal.
*/
public boolean equalsPoint(Point other) {
return Float.compare((float) other.x, x) == 0 && Float.compare((float) other.y, y) == 0;
return Math.abs(other.x - x) < Maths.FloatPrecision && Math.abs(other.y - y) < Maths.FloatPrecision;
}

/**
Expand All @@ -356,7 +356,7 @@ public boolean equals(Object other) {
return false;
}
Pointf pointf = (Pointf) other;
return Float.compare(pointf.x, x) == 0 && Float.compare(pointf.y, y) == 0;
return Math.abs(pointf.x - x) < Maths.FloatPrecision && Math.abs(pointf.y - y) < Maths.FloatPrecision;
}

@Override
Expand Down
145 changes: 139 additions & 6 deletions src/test/java/unittest/testcases/graphics/shapes/Polygon2DTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,9 @@ public void checkPolygon2DCreation_withPointfArrayParam_andRandomlyGeneratedColo
boolean shouldFill = Maths.randomAtEdge(0d, 1d) != 0d;
boolean shouldRender = Maths.randomAtEdge(0d, 1d) != 0d;

Pointf randomTranslation = new Pointf((float) Maths.random(-50f, 50f), (float) Maths.random(-50f, 50f));
float randomRotation = (float) Maths.random(-50f, 50f);
Pointf randomScale = new Pointf((float) Maths.random(-50f, 50f), (float) Maths.random(-50f, 50f));
Pointf randomTranslation = new Pointf((float) Maths.random(-50d, 50d), (float) Maths.random(-50d, 50d));
float randomRotation = (float) Maths.random(-50d, 50d);
Pointf randomScale = new Pointf((float) Maths.random(-50d, 50d), (float) Maths.random(-50d, 50d));

Polygon2D polygon2D = new Polygon2D(square, randomTranslation, randomRotation, randomScale, randomColor, shouldFill, shouldRender);

Expand All @@ -78,9 +78,9 @@ public void checkPolygon2DCreation_withPointfArrayParam_andRandomlyGeneratedColo
boolean shouldFill = Maths.randomAtEdge(0d, 1d) != 0d;
boolean shouldRender = Maths.randomAtEdge(0d, 1d) != 0d;

Pointf randomTranslation = new Pointf((float) Maths.random(-50f, 50f), (float) Maths.random(-50f, 50f));
float randomRotation = (float) Maths.random(-50f, 50f);
Pointf randomScale = new Pointf((float) Maths.random(-50f, 50f), (float) Maths.random(-50f, 50f));
Pointf randomTranslation = new Pointf((float) Maths.random(-50d, 50d), (float) Maths.random(-50d, 50d));
float randomRotation = (float) Maths.random(-50d, 50d);
Pointf randomScale = new Pointf((float) Maths.random(-50d, 50d), (float) Maths.random(-50d, 50d));

Polygon2D polygon2D = (Polygon2D) new Polygon2D(square)
.setColor(randomColor)
Expand All @@ -98,4 +98,137 @@ public void checkPolygon2DCreation_withPointfArrayParam_andRandomlyGeneratedColo
assertEquals(randomScale, polygon2D.getScale(), "The created polygon's scaling should match the randomly generated scale.");
assertArrayEquals(square, polygon2D.getOriginalPoints(), "The created polygon's Pointf array should match the original Pointf array.");
}

@Test
public void checkModifyPointsOfPolygon2D_withTransformResetting() {
Pointf[] squarePoints = DrawUtil.createBox(Pointf.origin, 5f);
Pointf translationBeforeReset = new Pointf(
(float) Maths.random(0d, 1d),
(float) Maths.random(0d, 1d)
);
float rotationBeforeReset = (float) Maths.random(0d, 1d);
Pointf scaleBeforeReset = new Pointf(
(float) Maths.random(0d, 1d),
(float) Maths.random(0d, 1d)
);

Polygon2D square = (Polygon2D) new Polygon2D(squarePoints)
.setTranslation(translationBeforeReset)
.setRotation(rotationBeforeReset)
.setScale(scaleBeforeReset);

Pointf[] newSquarePoints = DrawUtil.createBox(Pointf.origin.copy().add(1f), 20f);
square.modifyPoints(newSquarePoints, true, true, true);

assertArrayEquals(newSquarePoints, square.getPoints(), "The expected points should match the square's points -- no transformations have been performed.");
assertArrayEquals(newSquarePoints, square.getOriginalPoints(), "The expected points should match the square's points.");
assertEquals(GameObject.defaultTranslation, square.getTranslation(), "The square's translation should match the default GameObject translation.");
assertEquals(GameObject.defaultRotation, square.getRotation(), "The square's rotation should match the default GameObject rotation.");
assertEquals(GameObject.defaultScale, square.getScale(), "The square's scale should match the default GameObject scale.");
}

@Test
public void checkModifyPointsOfPolygon2D_withoutTransformResetting() {
Pointf[] squarePoints = DrawUtil.createBox(Pointf.origin, 5f);
Pointf translationBeforeReset = new Pointf(
(float) Maths.random(0d, 1d),
(float) Maths.random(0d, 1d)
);
float rotationBeforeReset = (float) Maths.random(0d, 1d);
Pointf scaleBeforeReset = new Pointf(
(float) Maths.random(0d, 1d),
(float) Maths.random(0d, 1d)
);

Polygon2D square = (Polygon2D) new Polygon2D(squarePoints)
.setTranslation(translationBeforeReset)
.setRotation(rotationBeforeReset)
.setScale(scaleBeforeReset);

Pointf[] newSquarePoints = DrawUtil.createBox(Pointf.origin.copy().add(1f), 20f);
square.modifyPoints(newSquarePoints, false, false, false);

assertArrayEquals(newSquarePoints, square.getPoints(), "The expected points should match the square's points -- no transformations have been performed.");
assertArrayEquals(newSquarePoints, square.getOriginalPoints(), "The expected points should match the square's points.");
assertEquals(translationBeforeReset, square.getTranslation(), "The square's translation should match the translation before point modification.");
assertEquals(rotationBeforeReset, square.getRotation(), "The square's rotation should match the rotation before point modification.");
assertEquals(scaleBeforeReset, square.getScale(), "The square's scale should match the scale before point modification.");
}

@Test
public void checkPolygon2DTranslation_shouldMatchExpected() {
Pointf[] originalPoints = DrawUtil.createBox(Pointf.origin, 5f);
Pointf randomTranslation = new Pointf(
(float) Maths.random(0d, 1d),
(float) Maths.random(0d, 1d)
);
Pointf[] expectedTranslatedPoints = {
originalPoints[0].copy().add(randomTranslation),
originalPoints[1].copy().add(randomTranslation),
originalPoints[2].copy().add(randomTranslation),
originalPoints[3].copy().add(randomTranslation)
};

Polygon2D polygon2D = new Polygon2D(originalPoints);
polygon2D.translate(randomTranslation);
Pointf[] actualTranslatedPoints = polygon2D.getPoints();

assertArrayEquals(expectedTranslatedPoints, actualTranslatedPoints, "The actual Pointf array, which has been translated, should match the expected Pointf array.");
}

@Test
public void checkPolygon2DRotation_shouldMatchExpected() {
Pointf[] originalPoints = DrawUtil.createBox(Pointf.origin, 5f);
float randomRotationInDegrees = (float) Maths.random(0d, 1d);
float randomRotationInRadians = (float) Math.toRadians(randomRotationInDegrees);
float cosOfRotation = (float) Math.cos(randomRotationInRadians);
float sinOfRotation = (float) Math.sin(randomRotationInRadians);

Pointf[] expectedRotatedPoints = {
new Pointf(
originalPoints[0].x * cosOfRotation - originalPoints[0].y * sinOfRotation,
originalPoints[0].y * cosOfRotation + originalPoints[0].x * sinOfRotation
),
new Pointf(
originalPoints[1].x * cosOfRotation - originalPoints[1].y * sinOfRotation,
originalPoints[1].y * cosOfRotation + originalPoints[1].x * sinOfRotation
),
new Pointf(
originalPoints[2].x * cosOfRotation - originalPoints[2].y * sinOfRotation,
originalPoints[2].y * cosOfRotation + originalPoints[2].x * sinOfRotation
),
new Pointf(
originalPoints[3].x * cosOfRotation - originalPoints[3].y * sinOfRotation,
originalPoints[3].y * cosOfRotation + originalPoints[3].x * sinOfRotation
)
};

Polygon2D polygon2D = new Polygon2D(originalPoints);
polygon2D.rotate(randomRotationInDegrees, Pointf.origin);
Pointf[] actualRotatedPoints = polygon2D.getPoints();

assertArrayEquals(expectedRotatedPoints, actualRotatedPoints, "The actual Pointf array, which has been rotated, should match the expected Pointf array.");
}

@Test
public void checkPolygon2DScaling_atOrigin_shouldMatchExpected() {
Pointf[] originalPoints = DrawUtil.createBox(Pointf.origin, 5f);
Pointf randomScaling = new Pointf(
(float) Maths.random(0d, 1d),
(float) Maths.random(0d, 1d)
);

Polygon2D polygon2D = new Polygon2D(originalPoints);
Pointf[] expectedScaledPoints = {
originalPoints[0].copy().multiply(Pointf.add(randomScaling, polygon2D.getScale())),
originalPoints[1].copy().multiply(Pointf.add(randomScaling, polygon2D.getScale())),
originalPoints[2].copy().multiply(Pointf.add(randomScaling, polygon2D.getScale())),
originalPoints[3].copy().multiply(Pointf.add(randomScaling, polygon2D.getScale()))
};

polygon2D.scale(randomScaling, Pointf.origin);
Pointf[] actualScaledPoints = polygon2D.getPoints();

assertArrayEquals(expectedScaledPoints, actualScaledPoints, "The actual Pointf array, which has been scaled, should match the expected Pointf array.");
}
}

0 comments on commit d192617

Please sign in to comment.