/* * $Id$ * This file is a part of the Arakhne Foundation Classes, http://www.arakhne.org/afc * * Copyright (c) 2000-2012 Stephane GALLAND. * Copyright (c) 2005-10, Multiagent Team, Laboratoire Systemes et Transports, * Universite de Technologie de Belfort-Montbeliard. * Copyright (c) 2013-2016 The original authors, and other authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.arakhne.afc.math.geometry.d3.afp; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.fail; import java.awt.Color; import java.awt.Graphics2D; import java.awt.geom.Path2D; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.util.Arrays; import javax.imageio.ImageIO; import org.junit.After; import org.junit.Before; import org.junit.ComparisonFailure; import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.arakhne.afc.math.AbstractMathTestCase; import org.arakhne.afc.math.geometry.PathElementType; import org.arakhne.afc.math.geometry.PathWindingRule; import org.arakhne.afc.math.geometry.coordinatesystem.CoordinateSystem3DTestRule; import org.arakhne.afc.math.geometry.d3.Point3D; import org.arakhne.afc.math.geometry.d3.Vector3D; @SuppressWarnings("all") public abstract class AbstractShape3afpTest<T extends Shape3afp<?, ?, ?, ?, ?, ?>, B extends RectangularPrism3afp<?, ?, ?, ?, ?, B>> extends AbstractMathTestCase { @Rule public CoordinateSystem3DTestRule csTestRule = new CoordinateSystem3DTestRule(); /** Is the rectangular shape to test. */ protected T shape; /** Shape factory. */ protected TestShapeFactory3afp<? extends Point3D, ? extends Vector3D, B> factory; /** * @throws Exception */ @Before public void setUp() throws Exception { this.factory = createFactory(); this.shape = createShape(); } protected abstract TestShapeFactory3afp<? extends Point3D, ? extends Vector3D, B> createFactory(); /** Create the shape to test. * * @return the shape to test. */ protected abstract T createShape(); public final Segment3afp<?, ?, ?, ?, ?, B> createSegment(double x1, double y1, double z1, double x2, double y2, double z2) { return this.factory.createSegment(x1, y1, z1, x2, y2, z2); } public final B createRectangularPrism(double x, double y, double z, double width, double height, double depth) { return this.factory.createRectangularPrism(x, y, z, width, height, depth); } public final Sphere3afp<?, ?, ?, ?, ?, B> createSphere(double x, double y, double z, double radius) { return this.factory.createSphere(x, y, z, radius); } public final MultiShape3afp<?, ?, ?, ?, ?, ?, B> createMultiShape() { return this.factory.createMultiShape(); } public final Point3D createPoint(double x, double y, double z) { return this.factory.createPoint(x, y, z); } public final Vector3D createVector(double x, double y, double z) { return this.factory.createVector(x, y, z); } public final Path3afp<?, ?, ?, ?, ?, B> createPath() { return this.factory.createPath(null); } public final Path3afp<?, ?, ?, ?, ?, B> createPath(PathWindingRule rule) { return this.factory.createPath(rule); } public final Path3afp<?, ?, ?, ?, ?, B> createPolyline(double... coordinates) { Path3afp<?, ?, ?, ?, ?, B> path = createPath(); path.moveTo(coordinates[0], coordinates[1], coordinates[2]); for (int i = 3; i < coordinates.length; i += 3) { path.lineTo(coordinates[i], coordinates[i + 1], coordinates[i + 2]); } return path; } /** * @throws Exception */ @After public void tearDown() throws Exception { this.shape = null; } /** Assert is the given path iterator has a first element with the * given information. * * @param pi * @param type * @param coords */ protected void assertElement(PathIterator3afp<?> pi, PathElementType type, double... coords) { if (!pi.hasNext()) { fail("expected path element but the iterator is empty"); //$NON-NLS-1$ } PathElement3afp pe = pi.next(); if (!type.equals(pe.getType())) { throw new ComparisonFailure("not same element type.", type.name(), pe.getType().name()); //$NON-NLS-1$ } double[] c = new double[coords.length]; pe.toArray(c); if (!isEpsilonEquals(c, coords)) { throw new ComparisonFailure("not same coordinates.", //$NON-NLS-1$ Arrays.toString(coords), Arrays.toString(c)); } } /** * Replies if two arrays have the same values at epsilon. * * @param a * @param b * @return <code>true</code> if the two arrays are equal, otherwise * <code>false</code>. */ public boolean isEpsilonEquals(float[] a, float[] b) { if (a==b) return true; if (a==null && b!=null) return false; if (a!=null && b==null) return false; assert(a!=null && b!=null); if (a.length!=b.length) return false; for(int i=0; i<a.length; ++i) { if (!isEpsilonEquals(a[i], b[i])) return false; } return true; } /** * Replies if two arrays have the same values at epsilon. * * @param a * @param b * @return <code>true</code> if the two arrays are equal, otherwise * <code>false</code>. */ protected boolean isEquals(int[] a, int[] b) { if (a==b) return true; if (a==null && b!=null) return false; if (a!=null && b==null) return false; assert(a!=null && b!=null); if (a.length!=b.length) return false; for(int i=0; i<a.length; ++i) { if (a[i]!=b[i]) return false; } return true; } /** Assert is the given path iterator has no element. * * @param pi */ protected void assertNoElement(PathIterator3afp<?> pi) { if (pi.hasNext()) { fail("expected no path element but the iterator is not empty: " //$NON-NLS-1$ + pi.next()); } } @Test @Ignore public abstract void testClone(); @Test @Ignore public abstract void equalsObject(); @Test @Ignore public abstract void equalsObject_withPathIterator(); @Test @Ignore public abstract void equalsToPathIterator(); @Test @Ignore public abstract void equalsToShape(); @Test public abstract void isEmpty(); @Test public abstract void clear(); @Test @Ignore public abstract void containsPoint3D(); @Test @Ignore public abstract void getClosestPointTo(); @Test @Ignore public abstract void getFarthestPointTo(); @Test @Ignore public abstract void getDistance(); @Test @Ignore public abstract void getDistanceSquared(); @Test @Ignore public abstract void getDistanceL1(); @Test @Ignore public abstract void getDistanceLinf(); @Test @Ignore public abstract void setIT(); @Test @Ignore public abstract void getPathIterator(); @Test @Ignore public abstract void getPathIteratorTransform3D(); @Test @Ignore public abstract void createTransformedShape(); @Test @Ignore public abstract void translateVector3D(); @Test @Ignore public abstract void toBoundingBox(); @Test @Ignore public abstract void toBoundingBoxB(); @Test @Ignore public abstract void containsRectangularPrism3afp(); @Test @Ignore public abstract void intersectsRectangularPrism3afp(); @Test @Ignore public abstract void intersectsSphere3afp(); @Test @Ignore public abstract void intersectsSegment3afp(); @Test @Ignore public abstract void intersectsPath3afp(); @Test @Ignore public abstract void intersectsPathIterator3afp(); @Test @Ignore public abstract void translateDoubleDouble(); @Test @Ignore public abstract void containsDoubleDouble(); @Test public void getGeomFactory() { assertNotNull(this.shape.getGeomFactory()); } @Test @Ignore public abstract void intersectsShape3D(); @Test @Ignore public abstract void operator_addVector3D(); @Test @Ignore public abstract void operator_plusVector3D(); @Test @Ignore public abstract void operator_removeVector3D(); @Test @Ignore public abstract void operator_minusVector3D(); @Test @Ignore public abstract void operator_multiplyTransform3D(); @Test @Ignore public abstract void operator_andPoint3D(); @Test @Ignore public abstract void operator_andShape3D(); @Test @Ignore public abstract void operator_upToPoint3D(); /** Generate a bitmap containing the given Shape2D. * * @param shape. * @return the filename * @throws IOException Input/output exception */ public static File generateTestPicture(Shape3afp<?, ?, ?, ?, ?, ?> shape) throws IOException { File filename = File.createTempFile("testShape", ".png"); //$NON-NLS-1$ //$NON-NLS-2$ RectangularPrism3afp box = shape.toBoundingBox(); PathIterator3afp<?> iterator = shape.getPathIterator(); Path2D path = new Path2D.Double( iterator.getWindingRule() == PathWindingRule.NON_ZERO ? Path2D.WIND_NON_ZERO : Path2D.WIND_EVEN_ODD); while (iterator.hasNext()) { PathElement3afp element = iterator.next(); double tox = (element.getToX() - box.getMinX()) * 2.; double toy = (box.getMaxY() - (element.getToY() - box.getMinY())) * 2.; switch (element.getType()) { case LINE_TO: path.lineTo(tox, toy); break; case MOVE_TO: path.moveTo(tox, toy); break; case CLOSE: path.closePath(); break; case CURVE_TO: path.curveTo( (element.getCtrlX1() - box.getMinX()) * 2., (box.getMaxY() - (element.getCtrlY1() - box.getMinY())) * 2., (element.getCtrlX2() - box.getMinX()) * 2., (box.getMaxY() - (element.getCtrlY2() - box.getMinY())) * 2., tox, toy); break; case QUAD_TO: path.quadTo( (element.getCtrlX1() - box.getMinX()) * 2., (box.getMaxY() - (element.getCtrlY1() - box.getMinY())) * 2., tox, toy); break; case ARC_TO: throw new IllegalArgumentException(); default: } } BufferedImage image = new BufferedImage( (int) Math.floor(box.getWidth() * 2.) + 1, (int) Math.floor(box.getHeight() * 2.) + 1, BufferedImage.TYPE_INT_ARGB); Graphics2D g2d = (Graphics2D) image.getGraphics(); g2d.setColor(Color.BLACK); g2d.draw(path); ImageIO.write(image, "png", filename); //$NON-NLS-1$ return filename; } }