package nodebox.graphics; import org.junit.Test; import java.util.List; import static junit.framework.TestCase.*; import static nodebox.graphics.GraphicsTestUtils.assertPointEquals; public class GeometryTest { @Test public void testBounds() { Path r1 = new Path(); r1.rect(10, 20, 30, 40); Geometry g1 = new Geometry(); g1.add(r1); assertEquals(Rect.centeredRect(10, 20, 30, 40), g1.getBounds()); } @Test public void testTransformedBounds() { Path r1 = new Path(); r1.rect(10, 20, 30, 40); Transform t = new Transform(); t.translate(200, 300); r1.transform(t); Geometry g = new Geometry(); g.add(r1); assertEquals(Rect.centeredRect(210, 320, 30, 40), g.getBounds()); } /** * Check the bounds for an empty path. */ @Test public void testEmptyBounds() { assertEquals(new Rect(), new Geometry().getBounds()); Path p1 = new Path(); p1.rect(100, 200, 30, 40); Geometry g1 = new Geometry(); g1.add(p1); Rect r = Rect.centeredRect(100, 200, 30, 40); assertEquals(r, g1.getBounds()); Path p2 = new Path(); Geometry g2 = new Geometry(); g2.add(p1); g2.add(p2); assertEquals(r, g2.getBounds()); } /** * Check if a contour is empty. */ @Test public void testIsEmpty() { Geometry g1 = new Geometry(); assertTrue(g1.isEmpty()); Geometry g2 = new Geometry(); // Adding even an empty path makes the geometry not empty. g2.add(new Path()); assertFalse(g2.isEmpty()); } @Test public void testTransformedElements() { Path r1 = new Path(); r1.rect(10, 20, 30, 40); Path r2 = new Path(); r2.rect(10, 120, 30, 40); Geometry g = new Geometry(); g.add(r1); g.add(r2); Rect rect1 = Rect.centeredRect(10, 20, 30, 40); Rect rect2 = Rect.centeredRect(10, 120, 30, 40); assertEquals(rect1.united(rect2), g.getBounds()); } /** * Geometry added to the group is not cloned. Test if you can still change * the original geometry. */ @Test public void testAdd() { Path p = new Path(); p.rect(10, 20, 30, 40); Geometry g = new Geometry(); g.add(p); p.transform(Transform.translated(5, 7)); // Since the path is in the group and not cloned, // the bounds of the group will be those of the translated path. assertEquals(Rect.centeredRect(15, 27, 30, 40), g.getBounds()); } @Test public void testTranslatePointsOfGroup() { Path p1 = new Path(); Path p2 = new Path(); p1.rect(10, 20, 30, 40); p2.rect(40, 20, 30, 40); Geometry g = new Geometry(); g.add(p1); g.add(p2); assertEquals(Rect.centeredRect((40 - 10) / 2 + 10, 20, 60, 40), g.getBounds()); Transform t = Transform.translated(5, 7); Geometry g2 = t.map(g); assertEquals(Rect.centeredRect(30, 27, 60, 40), g2.getBounds()); } @Test public void testColors() { Path p1 = new Path(); Path p2 = new Path(); p1.rect(0, 0, 100, 100); p2.rect(150, 150, 100, 100); Geometry g = new Geometry(); g.add(p1); g.add(p2); assertEquals(2, g.size()); // Each path has 4 points. assertEquals(8, g.getPointCount()); Color red = new Color(1, 0, 0); g.setFill(red); assertEquals(red, p1.getFillColor()); assertEquals(red, p2.getFillColor()); } @Test public void testMakePoints() { // Create a continuous line from 0,0 to 100,0. // The line is composed of one path from 0-50 // and another path with two contours, from 50-75 and 75-100. Path p1 = new Path(); p1.line(0, 0, 50, 0); Path p2 = new Path(); p2.line(50, 0, 75, 0); p2.line(75, 0, 100, 0); Geometry g = new Geometry(); g.add(p1); g.add(p2); assertEquals(100.0, g.getLength()); Point[] points = g.makePoints(5); assertPointEquals(0, 0, points[0]); assertPointEquals(25, 0, points[1]); assertPointEquals(50, 0, points[2]); assertPointEquals(75, 0, points[3]); assertPointEquals(100, 0, points[4]); // Achieve the same result using resampleByAmount. Geometry resampledGeometry = g.resampleByAmount(5, false); List<Point> resampledPoints = resampledGeometry.getPoints(); assertPointEquals(0, 0, resampledPoints.get(0)); assertPointEquals(25, 0, resampledPoints.get(1)); assertPointEquals(50, 0, resampledPoints.get(2)); assertPointEquals(75, 0, resampledPoints.get(3)); assertPointEquals(100, 0, resampledPoints.get(4)); } /** * Group uses a path length cache to speed up pointAt, makePoints and resample operations. * Check if the cache is properly invalidated. */ @Test public void testCacheInvalidation() { Geometry g = new Geometry(); assertEquals(0.0, g.getLength()); Path p1 = new Path(); p1.line(0, 0, 50, 0); g.add(p1); assertEquals(50.0, g.getLength()); // Change the Path after it was added to the Geometry. p1.line(50, 0, 75, 0); // This change is not detected by the Geometry, and thus the length is not updated. assertEquals(50.0, g.getLength()); // Manually invalidate the group. g.invalidate(); // This time, the length is correct. assertEquals(75.0, g.getLength()); } @Test public void testLength() { Geometry g = new Geometry(); Path p1 = new Path(); p1.line(0, 0, 100, 0); Path p2 = new Path(); p2.line(0, 100, 100, 100); g.add(p1); g.add(p2); assertEquals(200.0, g.getLength()); } }