eu.mihosoft.vrl.v3d.ext.quickhull3d.QuickHull3DTest Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of JavaCad Show documentation
Show all versions of JavaCad Show documentation
A Java based CSG Cad library
/** * Copyright John E. Lloyd, 2004. All rights reserved. Permission to use, * copy, modify and redistribute is granted, provided that this copyright * notice is retained and the author is given credit whenever appropriate. * * This software is distributed "as is", without any warranty, including * any implied warranty of merchantability or fitness for a particular * use. The author assumes no responsibility for, and shall not be liable * for, any special, indirect, or consequential damages, or any damages * whatsoever, arising out of or in connection with the use of this * software. */ package eu.mihosoft.vrl.v3d.ext.quickhull3d; import java.util.*; import java.io.*; // TODO: Auto-generated Javadoc /** * Testing class for QuickHull3D. Running the command * * java quickhull3d.QuickHull3DTest * * will cause QuickHull3D to be tested on a number of randomly * choosen input sets, with degenerate points added near * the edges and vertics of the convex hull. * * The command * * java quickhull3d.QuickHull3DTest -timing * * will cause timing information to be produced instead. * * @author John E. Lloyd, Fall 2004 */ class QuickHull3DTest { /** The Constant DOUBLE_PREC. */ static private final double DOUBLE_PREC = 2.2204460492503131e-16; /** The triangulate. */ static boolean triangulate = false; /** The do testing. */ static boolean doTesting = true; /** The do timing. */ static boolean doTiming = false; /** The debug enable. */ static boolean debugEnable = false; /** The Constant NO_DEGENERACY. */ static final int NO_DEGENERACY = 0; /** The Constant EDGE_DEGENERACY. */ static final int EDGE_DEGENERACY = 1; /** The Constant VERTEX_DEGENERACY. */ static final int VERTEX_DEGENERACY = 2; /** The rand. */ Random rand; // random number generator /** The test rotation. */ static boolean testRotation = true; /** The degeneracy test. */ static int degeneracyTest = VERTEX_DEGENERACY; /** The eps scale. */ static double epsScale = 2.0; /** * Creates a testing object. */ public QuickHull3DTest() { rand = new Random(); rand.setSeed (0x1234); } /** * Returns true if two face index sets are equal, * modulo a cyclical permuation. * * @param indices1 index set for first face * @param indices2 index set for second face * @return true if the index sets are equivalent */ public boolean faceIndicesEqual (int[] indices1, int[] indices2) { if (indices1.length != indices2.length) { return false; } int len = indices1.length; int j; for (j=0; j
points whose x, y, and * z values are randomly chosen within a given range. * * @param num number of points to produce * @param range coordinate values will lie between -range and range * @return array of coordinate values */ public double[] randomPoints (int num, double range) { double[] coords = new double[num*3]; for (int i=0; inum num randomly * chosen points which are degenerate which respect * to the specified dimensionality. * * @param num number of points to produce * @param dimen dimensionality of degeneracy: 0 = coincident, * 1 = colinear, 2 = coplaner. * @return array of coordinate values */ public double[] randomDegeneratePoints (int num, int dimen) { double[] coords= new double[num*3]; Point3d pnt = new Point3d(); Point3d base = new Point3d(); base.setRandom (-1, 1, rand); double tol = DOUBLE_PREC; if (dimen == 0) { for (int i=0; i num points whose x, y, and * z values are randomly chosen to lie within a sphere. * * @param num number of points to produce * @param radius radius of the sphere * @return array of coordinate values */ public double[] randomSphericalPoints (int num, double radius) { double[] coords = new double[num*3]; Point3d pnt = new Point3d(); for (int i=0; i num points whose x, y, and * z values are each randomly chosen to lie within a specified * range, and then clipped to a maximum absolute * value. This means a large number of points * may lie on the surface of cube, which is useful * for creating degenerate convex hull situations. * * @param num number of points to produce * @param range coordinate values will lie between -range and * range, before clipping * @param max maximum absolute value to which the coordinates * are clipped * @return array of coordinate values */ public double[] randomCubedPoints (int num, double range, double max) { double[] coords = new double[num*3]; for (int i=0; i max) { x = max; } else if (x < -max) { x = -max; } coords[i*3+k] = x; } } return coords; } /** * Shuffle coords. * * @param coords the coords * @return the double[] */ private double[] shuffleCoords (double[] coords) { int num = coords.length/3; for (int i=0; i Passed to System.out if all is well. */ public void explicitAndRandomTests() { try { double[] coords = null; System.out.println ( "Testing degenerate input ..."); for (int dimen=0; dimen<3; dimen++) { for (int i=0; i<10; i++) { coords = randomDegeneratePoints (10, dimen); if (dimen == 0) { testException ( coords, "Input points appear to be coincident"); } else if (dimen == 1) { testException ( coords, "Input points appear to be colinear"); } else if (dimen == 2) { testException ( coords, "Input points appear to be coplanar"); } } } System.out.println ( "Explicit tests ..."); // test cases furnished by Mariano Zelke, Berlin coords = new double[] { 21, 0, 0, 0, 21, 0, 0, 0, 0, 18, 2, 6, 1, 18, 5, 2, 1, 3, 14, 3, 10, 4, 14, 14, 3, 4, 10, 10, 6, 12, 5, 10, 15, }; test (coords, null); coords = new double[] { 0.0 , 0.0 , 0.0, 21.0, 0.0 , 0.0, 0.0 , 21.0, 0.0, 2.0 , 1.0 , 2.0, 17.0, 2.0 , 3.0, 1.0 , 19.0, 6.0, 4.0 , 3.0 , 5.0, 13.0, 4.0 , 5.0, 3.0 , 15.0, 8.0, 6.0 , 5.0 , 6.0, 9.0 , 6.0 , 11.0, }; test (coords, null); System.out.println ( "Testing 20 to 200 random points ..."); for (int n=20; n<200; n+=10) { // System.out.println (n); for (int i=0; i<10; i++) { coords = randomPoints (n, 1.0); test (coords, null); } } System.out.println ( "Testing 20 to 200 random points in a sphere ..."); for (int n=20; n<200; n+=10) { // System.out.println (n); for (int i=0; i<10; i++) { coords = randomSphericalPoints (n, 1.0); test (coords, null); } } System.out.println ( "Testing 20 to 200 random points clipped to a cube ..."); for (int n=20; n<200; n+=10) { // System.out.println (n); for (int i=0; i<10; i++) { coords = randomCubedPoints (n, 1.0, 0.5); test (coords, null); } } System.out.println ( "Testing 8 to 1000 randomly shuffled points on a grid ..."); for (int n=2; n<=10; n++) { // System.out.println (n*n*n); for (int i=0; i<10; i++) { coords = randomGridPoints (n, 4.0); test (coords, null); } } } catch (Exception e) { e.printStackTrace(); System.exit(1); } System.out.println ("\nPassed\n"); } /** * Runs timing tests on QuickHull3D, and prints * the results to System.out. */ public void timingTests() { long t0, t1; int n = 10; QuickHull3D hull = new QuickHull3D (); System.out.println ("warming up ... "); for (int i=0; i<2; i++) { double[] coords = randomSphericalPoints (10000, 1.0); hull.build (coords); } int cnt = 10; for (int i=0; i<4; i++) { n *= 10; double[] coords = randomSphericalPoints (n, 1.0); t0 = System.currentTimeMillis(); for (int k=0; k Passed if all is well. * Otherwise, an error message and stack trace * are printed. * * If the option -timing
is supplied, * then timing information is produced instead. * * @param args the arguments */ public static void main (String[] args) { QuickHull3DTest tester = new QuickHull3DTest(); for (int i=0; i