package com.revolsys.geometry.test.old.geom; import java.io.IOException; import com.revolsys.geometry.model.Geometry; import com.revolsys.geometry.model.GeometryFactory; import com.revolsys.geometry.model.Point; import com.revolsys.geometry.model.impl.PointDoubleXY; import com.revolsys.geometry.model.util.AffineTransformation; import com.revolsys.geometry.model.util.NoninvertibleTransformationException; import com.revolsys.geometry.wkb.ParseException; import junit.framework.TestCase; /** * @author Martin Davis * */ public class AffineTransformationTest extends TestCase { static GeometryFactory geometryFactory = GeometryFactory.DEFAULT_3D; public AffineTransformationTest(final String name) { super(name); } void checkTransformation(final AffineTransformation trans0, final AffineTransformation trans1) { final double[] m0 = trans0.getMatrixEntries(); final double[] m1 = trans1.getMatrixEntries(); for (int i = 0; i < m0.length; i++) { assertEquals(m0[i], m1[i], 0.000005); } } /** * Checks that a transformation produces the expected result * @param x the input pt x * @param y the input pt y * @param trans the transformation * @param xp the expected output x * @param yp the expected output y */ void checkTransformation(final double x, final double y, final AffineTransformation trans, final double xp, final double yp) { final Point p = new PointDoubleXY(x, y); final Point p2 = trans.transform(p); assertEquals(xp, p2.getX(), .00005); assertEquals(yp, p2.getY(), .00005); // if the transformation is invertible, test the inverse try { final AffineTransformation invTrans = trans.getInverse(); final Point pInv = invTrans.transform(p2); assertEquals(x, pInv.getX(), .00005); assertEquals(y, pInv.getY(), .00005); final double det = trans.getDeterminant(); final double detInv = invTrans.getDeterminant(); assertEquals(det, 1.0 / detInv, .00005); } catch (final NoninvertibleTransformationException ex) { } } void checkTransformation(final String geomStr) throws IOException, ParseException, NoninvertibleTransformationException { final Geometry geom = geometryFactory.geometry(geomStr); final AffineTransformation trans = AffineTransformation.rotationInstance(Math.PI / 2); final AffineTransformation inv = trans.getInverse(); final Geometry transGeom = trans.transform(geom); final Geometry invGeom = inv.transform(transGeom); // check if transformed geometry is equal to original final boolean isEqual = geom.equalsExact(invGeom, 0.0005); assertTrue(isEqual); } public void testCompose1() { final AffineTransformation t0 = AffineTransformation.translationInstance(10, 0); t0.rotate(Math.PI / 2); t0.translate(0, -10); final AffineTransformation t1 = AffineTransformation.translationInstance(0, 0); t1.rotate(Math.PI / 2); checkTransformation(t0, t1); } public void testCompose2() { final AffineTransformation t0 = AffineTransformation.reflectionInstance(0, 0, 1, 0); t0.reflect(0, 0, 0, -1); final AffineTransformation t1 = AffineTransformation.rotationInstance(Math.PI); checkTransformation(t0, t1); } public void testCompose3() { final AffineTransformation t0 = AffineTransformation.reflectionInstance(0, 10, 10, 0); t0.translate(-10, -10); final AffineTransformation t1 = AffineTransformation.reflectionInstance(0, 0, -1, 1); checkTransformation(t0, t1); } public void testComposeRotation1() { final AffineTransformation t0 = AffineTransformation.rotationInstance(1, 10, 10); final AffineTransformation t1 = AffineTransformation.translationInstance(-10, -10); t1.rotate(1); t1.translate(10, 10); checkTransformation(t0, t1); } public void testGeometryCollection() throws IOException, ParseException, NoninvertibleTransformationException { checkTransformation( "GEOMETRYCOLLECTION ( POINT ( 1 1), LINESTRING (0 0, 10 10), POLYGON ((0 0, 100 0, 100 100, 0 100, 0 0)))"); } public void testLineString() throws IOException, ParseException, NoninvertibleTransformationException { checkTransformation("LINESTRING (1 2, 10 20, 100 200)"); } public void testMultiLineString() throws IOException, ParseException, NoninvertibleTransformationException { checkTransformation("MULTILINESTRING ((0 0, 1 10), (10 10, 20 30), (123 123, 456 789))"); } public void testMultiPoint() throws IOException, ParseException, NoninvertibleTransformationException { checkTransformation("MULTIPOINT (0 0, 1 4, 100 200)"); } public void testMultiPolygon() throws IOException, ParseException, NoninvertibleTransformationException { checkTransformation( "MULTIPOLYGON ( ((0 0, 100 0, 100 100, 0 100, 0 0), (1 1, 1 10, 10 10, 10 1, 1 1)), ((200 200, 200 250, 250 250, 250 200, 200 200)))"); } public void testNestedGeometryCollection() throws IOException, ParseException, NoninvertibleTransformationException { checkTransformation( "GEOMETRYCOLLECTION ( POINT (20 20), GEOMETRYCOLLECTION ( POINT ( 1 1), LINESTRING (0 0, 10 10), POLYGON ((0 0, 100 0, 100 100, 0 100, 0 0))) )"); } public void testPolygon() throws IOException, ParseException, NoninvertibleTransformationException { checkTransformation("POLYGON ((0 0, 100 0, 100 100, 0 100, 0 0))"); } public void testPolygonWithHole() throws IOException, ParseException, NoninvertibleTransformationException { checkTransformation( "POLYGON ((0 0, 100 0, 100 100, 0 100, 0 0), (1 1, 1 10, 10 10, 10 1, 1 1))"); } public void testReflectXY1() throws IOException, ParseException { final AffineTransformation t = AffineTransformation.reflectionInstance(1, 1); checkTransformation(10, 0, t, 0, 10); checkTransformation(0, 10, t, 10, 0); checkTransformation(-10, -10, t, -10, -10); checkTransformation(-3, -4, t, -4, -3); } public void testReflectXY2() throws IOException, ParseException { final AffineTransformation t = AffineTransformation.reflectionInstance(1, -1); checkTransformation(10, 0, t, 0, -10); checkTransformation(0, 10, t, -10, 0); checkTransformation(-10, -10, t, 10, 10); checkTransformation(-3, -4, t, 4, 3); } public void testReflectXYXY1() throws IOException, ParseException { final AffineTransformation t = AffineTransformation.reflectionInstance(0, 5, 5, 0); checkTransformation(5, 0, t, 5, 0); checkTransformation(0, 0, t, 5, 5); checkTransformation(-10, -10, t, 15, 15); } public void testRotate1() throws IOException, ParseException { final AffineTransformation t = AffineTransformation.rotationInstance(Math.PI / 2); checkTransformation(10, 0, t, 0, 10); checkTransformation(0, 10, t, -10, 0); checkTransformation(-10, -10, t, 10, -10); } public void testRotateAroundPoint1() throws IOException, ParseException { final AffineTransformation t = AffineTransformation.rotationInstance(Math.PI / 2, 1, 1); checkTransformation(1, 1, t, 1, 1); checkTransformation(10, 0, t, 2, 10); checkTransformation(0, 10, t, -8, 0); checkTransformation(-10, -10, t, 12, -10); } public void testScale1() throws IOException, ParseException { final AffineTransformation t = AffineTransformation.scaleInstance(2, 3); checkTransformation(10, 0, t, 20, 0); checkTransformation(0, 10, t, 0, 30); checkTransformation(-10, -10, t, -20, -30); } public void testShear1() throws IOException, ParseException { final AffineTransformation t = AffineTransformation.shearInstance(2, 3); checkTransformation(10, 0, t, 10, 30); } public void testTranslate1() throws IOException, ParseException { final AffineTransformation t = AffineTransformation.translationInstance(2, 3); checkTransformation(1, 0, t, 3, 3); checkTransformation(0, 0, t, 2, 3); checkTransformation(-10, -5, t, -8, -2); } public void testTranslateRotate1() throws IOException, ParseException { final AffineTransformation t = AffineTransformation.translationInstance(3, 3) .rotate(Math.PI / 2); checkTransformation(10, 0, t, -3, 13); checkTransformation(-10, -10, t, 7, -7); } }