All Downloads are FREE. Search and download functionalities are using the official Maven repository.

eu.mihosoft.vrl.v3d.ext.quickhull3d.QuickHull3DTest Maven / Gradle / Ivy

There is a newer version: 2.0.0
Show newest version
/**
  * 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; jnum 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 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; inum 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; inum 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; iPassed 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; kPassed 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




© 2015 - 2024 Weber Informatics LLC | Privacy Policy