/*
* $Id$
*
* Copyright (C) 2010-2013 Stephane GALLAND.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* This program is free software; you can redistribute it and/or modify
*/
package org.arakhne.afc.math.geometry.d3.continuous;
import static org.junit.Assert.fail;
import java.math.BigDecimal;
import java.util.Random;
import org.arakhne.afc.math.geometry.d2.Tuple2D;
import org.arakhne.afc.math.geometry.d3.Tuple3D;
import org.junit.After;
import org.junit.Before;
import org.junit.ComparisonFailure;
import org.junit.Test;
/**
* @author $Author: sgalland$
* @version $FullVersion$
* @mavengroupid $GroupId$
* @mavenartifactid $ArtifactId$
*/
@SuppressWarnings("all")
public abstract class AbstractShape3fTestCase<T extends Shape3F> {
/** Is the rectangular shape to test.
*/
protected T r;
/** Precision of the floating point number epsilon-tests.
*/
protected final static int DEFAULT_DECIMAL_COUNT = 8;
private int decimalPrecision = DEFAULT_DECIMAL_COUNT;
/** Random number sequence.
*/
protected final Random random = new Random();
/** Test if the actual value is equal to the expected value with
* a distance of epsilon.
*
* @param expected
* @param actual
*/
protected void assertEpsilonEquals(double expected, double actual) {
assertEpsilonEquals(null, expected, actual);
}
/** Test if the actual value is not equal to the expected value with
* a distance of epsilon.
*
* @param expected
* @param actual
*/
protected void assertNotEpsilonEquals(double expected, double actual) {
assertNotEpsilonEquals(null, expected, actual);
}
/** Test if the actual value is not equal to the expected value with
* a distance of epsilon.
*
* @param expected
* @param actual
*/
protected void assertNotEquals(int expected, int actual) {
assertNotEquals(null, expected, actual);
}
/** Test if the actual value is not equal to the expected value with
* a distance of epsilon.
*
* @param message
* @param expected
* @param actual
*/
protected void assertNotEquals(String message, int expected, int actual) {
if (expected==actual) {
fail((message==null ? "" : (message+": "))
+"same value, expecting not equal to:"+
expected);
}
}
/** Test if the actual value is not equal to the expected value with
* a distance of epsilon.
*
* @param message
* @param expected
* @param actual
*/
protected void assertNotEpsilonEquals(String message, Tuple3D<?> expected, Tuple3D<?> actual) {
if (isEpsilonEquals(expected.getX(), actual.getX(), false)) {
throw new ComparisonFailure(
(message==null ? "" : (message+": "))
+"not same x value",
expected.toString(),
actual.toString());
}
if (isEpsilonEquals(expected.getY(), actual.getY(), false)) {
throw new ComparisonFailure(
(message==null ? "" : (message+": "))
+"not same y value",
expected.toString(),
actual.toString());
}
if (isEpsilonEquals(expected.getZ(), actual.getZ(), false)) {
throw new ComparisonFailure(
(message==null ? "" : (message+": "))
+"not same z value",
expected.toString(),
actual.toString());
}
}
/** Test if the actual value is equal to the expected value with
* a distance of epsilon.
*
* @param expected
* @param actual
*/
protected void assertEpsilonEquals(Quaternion expected, Quaternion actual) {
assertEpsilonEquals(null, expected, actual);
}
/** Test if the actual value is not equal to the expected value with
* a distance of epsilon.
*
* @param expected
* @param actual
*/
protected void assertNotEpsilonEquals(Quaternion expected, Quaternion actual) {
assertNotEpsilonEquals(null, expected, actual);
}
/** Test if the actual value is equal to the expected value with
* a distance of epsilon.
*
* @param message
* @param expected
* @param actual
*/
protected void assertEpsilonEquals(String message, Quaternion expected, Quaternion actual) {
if (!isEpsilonEquals(expected.getX(), actual.getX())) {
throw new ComparisonFailure(
(message==null ? "" : (message+": "))
+"not same x value",
expected.toString(),
actual.toString());
}
if (!isEpsilonEquals(expected.getY(), actual.getY())) {
throw new ComparisonFailure(
(message==null ? "" : (message+": "))
+"not same y value",
expected.toString(),
actual.toString());
}
if (!isEpsilonEquals(expected.getZ(), actual.getZ())) {
throw new ComparisonFailure(
(message==null ? "" : (message+": "))
+"not same z value",
expected.toString(),
actual.toString());
}
if (!isEpsilonEquals(expected.getW(), actual.getW())) {
throw new ComparisonFailure(
(message==null ? "" : (message+": "))
+"not same w value",
expected.toString(),
actual.toString());
}
}
/** Test if the actual value is not equal to the expected value with
* a distance of epsilon.
*
* @param message
* @param expected
* @param actual
*/
protected void assertNotEpsilonEquals(String message, Quaternion expected, Quaternion actual) {
if (isEpsilonEquals(expected.getX(), actual.getX(), false)) {
throw new ComparisonFailure(
(message==null ? "" : (message+": "))
+"not same x value",
expected.toString(),
actual.toString());
}
if (isEpsilonEquals(expected.getY(), actual.getY(), false)) {
throw new ComparisonFailure(
(message==null ? "" : (message+": "))
+"not same y value",
expected.toString(),
actual.toString());
}
if (isEpsilonEquals(expected.getZ(), actual.getZ(), false)) {
throw new ComparisonFailure(
(message==null ? "" : (message+": "))
+"not same z value",
expected.toString(),
actual.toString());
}
if (isEpsilonEquals(expected.getW(), actual.getW(), false)) {
throw new ComparisonFailure(
(message==null ? "" : (message+": "))
+"not same w value",
expected.toString(),
actual.toString());
}
}
/** Test if the actual value is equal to the expected value with
* a distance of epsilon.
*
* @param message
* @param expected
* @param actual
*/
protected void assertEpsilonEquals(String message, Tuple3D<?> expected, Tuple3D<?> actual) {
if (!isEpsilonEquals(expected.getX(), actual.getX())) {
throw new ComparisonFailure(
(message==null ? "" : (message+": "))
+"not same x value",
expected.toString(),
actual.toString());
}
if (!isEpsilonEquals(expected.getY(), actual.getY())) {
throw new ComparisonFailure(
(message==null ? "" : (message+": "))
+"not same y value",
expected.toString(),
actual.toString());
}
if (!isEpsilonEquals(expected.getZ(), actual.getZ())) {
throw new ComparisonFailure(
(message==null ? "" : (message+": "))
+"not same z value",
expected.toString(),
actual.toString());
}
}
/** Replies if the actual value is equal to the expected value with
* a distance of epsilon.
*
* @param expected
* @param actual
* @return the test result.
*/
protected boolean isEpsilonEquals(Tuple3D<?> expected, Tuple3D<?> actual) {
return isEpsilonEquals(expected.getX(), actual.getX())
&& isEpsilonEquals(expected.getY(), actual.getY())
&& isEpsilonEquals(expected.getZ(), actual.getZ());
}
/** Test if the actual value is equal to the expected value with
* a distance of epsilon.
*
* @param message
* @param expected
* @param actual
*/
protected void assertEpsilonEquals(String message, double expected, double actual) {
if (isEpsilonEquals(expected,actual)) return;
fail((message==null ? "" : (message+": "))
+"not same double value, expected:"+
expected
+", actual:"+actual);
}
/** Test if the actual value is not equal to the expected value with
* a distance of epsilon.
*
* @param message
* @param expected
* @param actual
*/
protected void assertNotEpsilonEquals(String message, double expected, double actual) {
if (!isEpsilonEquals(expected,actual, false)) return;
fail((message==null ? "" : (message+": "))
+"same double value, unexpected:"+
expected
+", actual:"+actual);
}
/** Test if the actual value is equal to the expected value with
* a distance of epsilon.
*
* @param expected
* @param actual
*/
protected void assertEpsilonEquals(Tuple2D<?> expected, Tuple2D<?> actual) {
assertEpsilonEquals(null, expected, actual);
}
/** Test if the actual value is not equal to the expected value with
* a distance of epsilon.
*
* @param expected
* @param actual
*/
protected void assertNotEpsilonEquals(Tuple2D<?> expected, Tuple2D<?> actual) {
assertNotEpsilonEquals(null, expected, actual);
}
/** Test if the actual value is equal to the expected value with
* a distance of epsilon.
*
* @param message
* @param expected
* @param actual
*/
protected void assertEpsilonEquals(String message, Tuple2D<?> expected, Tuple2D<?> actual) {
if (!isEpsilonEquals(expected.getX(), actual.getX())) {
throw new ComparisonFailure(
(message==null ? "" : (message+": "))
+"not same x value",
expected.toString(),
actual.toString());
}
if (!isEpsilonEquals(expected.getY(), actual.getY())) {
throw new ComparisonFailure(
(message==null ? "" : (message+": "))
+"not same y value",
expected.toString(),
actual.toString());
}
}
/** Test if the actual value is not equal to the expected value with
* a distance of epsilon.
*
* @param message
* @param expected
* @param actual
*/
protected void assertNotEpsilonEquals(String message, Tuple2D<?> expected, Tuple2D<?> actual) {
if (isEpsilonEquals(expected.getX(), actual.getX(), false)) {
throw new ComparisonFailure(
(message==null ? "" : (message+": "))
+"not same x value",
expected.toString(),
actual.toString());
}
if (isEpsilonEquals(expected.getY(), actual.getY(), false)) {
throw new ComparisonFailure(
(message==null ? "" : (message+": "))
+"not same y value",
expected.toString(),
actual.toString());
}
}
/** Test if the actual value is equal to the expected value with
* a distance of epsilon.
*
* @param expected
* @param actual
*/
protected void assertEpsilonEquals(Tuple3D<?> expected, Tuple3D<?> actual) {
assertEpsilonEquals(null, expected, actual);
}
/** Test if the actual value is not equal to the expected value with
* a distance of epsilon.
*
* @param expected
* @param actual
*/
protected void assertNotEpsilonEquals(Tuple3D<?> expected, Tuple3D<?> actual) {
assertNotEpsilonEquals(null, expected, actual);
}
/** Replies if two values are equals at espilon.
*
* @param a
* @param b
* @param isNaNEqual indicates if the NaN value is equals to itself.
* @return <code>true</code> or <code>false</code>
*/
protected boolean isEpsilonEquals(double a, double b, boolean isNaNEqual) {
if (a==b) return true;
boolean nanA = Double.isNaN(a);
boolean nanB = Double.isNaN(b);
if (nanA || nanB) {
if (isNaNEqual) return nanA==nanB;
return false;
}
if (!Double.isInfinite(a) && !Double.isInfinite(a)
&& !Double.isNaN(a) && !Double.isNaN(b)) {
return isEpsilonEquals(new BigDecimal(a), new BigDecimal(b), this.decimalPrecision/2);
}
return false;
}
/** Replies if two values are equals at espilon.
*
* @param a
* @param b
* @return <code>true</code> or <code>false</code>
*/
protected boolean isEpsilonEquals(double a, double b) {
return isEpsilonEquals(a, b, true);
}
/** Replies if two values are equals at espilon.
*
* @param a
* @param b
* @return <code>true</code> or <code>false</code>
*/
protected boolean isEpsilonEquals(BigDecimal a, BigDecimal b) {
return isEpsilonEquals(a, b, this.decimalPrecision);
}
/** Replies if two values are equals at espilon.
*
* @param a
* @param b
* @param precision is the number of decimal digits to test.
* @return <code>true</code> or <code>false</code>
*/
protected static boolean isEpsilonEquals(BigDecimal a, BigDecimal b, int precision) {
BigDecimal ma = a.movePointRight(precision);
BigDecimal mb = b.movePointRight(precision);
BigDecimal aa = ma.setScale(0,BigDecimal.ROUND_HALF_UP);
BigDecimal bb = mb.setScale(0,BigDecimal.ROUND_HALF_UP);
if (aa.compareTo(bb)==0) return true;
aa = ma.setScale(0,BigDecimal.ROUND_DOWN);
bb = mb.setScale(0,BigDecimal.ROUND_DOWN);
return (aa.compareTo(bb)==0);
}
/**
* 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 isEpsilonEquals(double[] a, double[] 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;
}
/**
* @throws Exception
*/
@Before
public void setUp() throws Exception {
this.r = createShape();
}
/** Create the shape to test.
*
* @return the shape to test.
*/
protected abstract T createShape();
/**
* @throws Exception
*/
@After
public void tearDown() throws Exception {
this.r = null;
}
@Test
public abstract void testClone();
@Test
public abstract void distancePoint3D();
@Test
public abstract void containsPoint3D();
@Test
public abstract void testEquals();
@Test
public abstract void testHashCode();
@Test
public abstract void toBoundingBox();
@Test
public abstract void toBoundingBoxAlignedBox3x();
@Test
public abstract void distanceSquaredPoint3D();
@Test
public abstract void distanceL1Point3D();
@Test
public abstract void distanceLinfPoint3D();
@Test
public abstract void translateVector3D();
@Test
public abstract void translateDoubleDoubleDouble();
@Test
public abstract void containsDoubleDoubleDouble();
@Test
public abstract void intersectsAlignedBox3x();
@Test
public abstract void intersectsSphere3x();
@Test
public abstract void intersectsSegment3x();
@Test
public abstract void intersectsTriangle3x();
@Test
public abstract void intersectsCapsule3x();
@Test
public abstract void intersectsOrientedBox3x();
@Test
public abstract void intersectsAbstractPlane3D();
}