//===========================================================================//
// File:	angle.tst                                                           //
// Project: MUNGA           Brick: Math Library                              //
// Contents: Tests for angle classes                                         //
//---------------------------------------------------------------------------//
//   Date    Who  Modification                                               //
// --------  ---  ---------------------------------------------------------- //
// 11/19/94  JMA  Initial coding.                                            //
//---------------------------------------------------------------------------//
// Copyright (C) 1994-1995, Virtual World Entertainment, Inc.                //
// All Rights reserved worldwide                                             //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL               //
//===========================================================================//

#include "StuffHeaders.hpp"

//
//#############################################################################
//#############################################################################
//
bool
	Sphere::TestClass()
{
	SPEW((GROUP_STUFF_TEST, "Starting Sphere Test..."));

	for (int test_count=10; test_count <= 50; test_count+=10)
	{
		DynamicArrayOf<Point3D> points(test_count);
		int sphere_counts[6];
		int obb_counts[3];
		memset(sphere_counts, 0, sizeof(sphere_counts));
		memset(obb_counts, 0, sizeof(obb_counts));

		double sphere_bests_obb = 0.0;
		double obb_bests_sphere = 0.0;
		double sphere_worsts_obb = 0.0;
		double obb_worsts_sphere = 0.0;
		double best_obb_ratio = 1000000.0;
		double worst_obb_ratio = 0.0;

		int sphere_betters=0;
		int obb_betters=0;

		for (int test=0; test<5000; ++test)
		{
			for (int i=0; i<test_count; ++i)
			{
				points[i].x = Random::GetFraction()*200.0f - 100.0f;
				points[i].y = Random::GetFraction()*200.0f - 100.0f;
				points[i].z = Random::GetFraction()*200.0f - 100.0f;
			}
			Sphere sphere;
			sphere_counts[sphere.ComputeBounds(points)]++;
			Scalar s_volume = sphere.GetVolume();

			OBB obb;
			obb_counts[obb.ComputeBounds(points)]++;
			Scalar o_volume = obb.GetVolume();

			if (s_volume > o_volume)
			{
				++obb_betters;
				obb_bests_sphere += o_volume;
				sphere_worsts_obb += s_volume;
				if (o_volume/s_volume < best_obb_ratio)
					best_obb_ratio = o_volume/s_volume;
			}
			else
			{
				++sphere_betters;
				obb_worsts_sphere += o_volume;
				sphere_bests_obb += s_volume;
				if (o_volume/s_volume > worst_obb_ratio)
					worst_obb_ratio = o_volume/s_volume;
			}
		}
		SPEW(("jmalbert", "Point count = %d", test_count));
		SPEW(("jmalbert", ""));

		SPEW(("jmalbert", "Immediate chord sphere: %f", 100.0f*(float)sphere_counts[1]/test));
		SPEW(("jmalbert", "Immediate circumsphere: %f", 100.0f*(float)sphere_counts[2]/test));
		SPEW(("jmalbert", "Centroid sphere: %f", 100.0f*(float)sphere_counts[3]/test));
		SPEW(("jmalbert", "Grown chord sphere: %f", 100.0f*(float)sphere_counts[4]/test));
		SPEW(("jmalbert", "Grown circumsphere: %f", 100.0f*(float)sphere_counts[5]/test));
		SPEW(("jmalbert", ""));

		SPEW(("jmalbert", "Non-aligned obb: %f", 100.0f*(float)obb_counts[1]/test));
		SPEW(("jmalbert", "Axis-aligned obb: %f", 100.0f*(float)obb_counts[2]/test));
		SPEW(("jmalbert", ""));

		SPEW(("jmalbert", "Sphere selections: %f", 100.0f*(float)sphere_betters/test));
		SPEW(("jmalbert", "OBB selections: %f", 100.0f*(float)obb_betters/test));
		SPEW(("jmalbert", ""));

		if (sphere_worsts_obb>0.0)
			SPEW(("jmalbert", "OBB to Sphere volume ratio when better: %f", obb_bests_sphere / sphere_worsts_obb));
		if (sphere_bests_obb>0.0)
			SPEW(("jmalbert", "OBB to Sphere volume ratio when worse: %f", obb_worsts_sphere / sphere_bests_obb));

		SPEW(("jmalbert", "Best OBB to Sphere volume ratio: %f", best_obb_ratio));
		SPEW(("jmalbert", "Worst OBB to Sphere volume ratio: %f", worst_obb_ratio));
		SPEW(("jmalbert", ""));
	}
	return true;
}
