/**
 * SphericalLib.RandomPoint
 * 
 * SphericalLib is a .NET library to deal with geometry on the unit sphere.
 * It is intented to be used for complex survey footprint descriptions in
 * standalone applications as well as in web services and perhaps Yukon.
 * 
 * Written by Tamas Budavari (budavari@pha.jhu.edu)
 * See bottom of file for revision history
 * 
 * Current revision:
 *   ID:          $Id: RandomPoint.cs,v 1.1.1.1 2006/11/14 02:56:39 gupchup Exp $
 *   Revision:    $Revision: 1.1.1.1 $
 *   Date:        $Date: 2006/11/14 02:56:39 $
 */
using System;

namespace Spherical.IO
{
	/// <summary>
	/// Generate random points on the sky
	/// </summary>
    [CLSCompliant(true)]
	public class RandomPoint
	{
		private Random random;
		private int seed;
		private int counter;

		/// <summary>
		/// Create instance with seed from system clock
		/// </summary>
		public RandomPoint()
		{
			this.Init( (int) System.DateTime.Now.Ticks );
		}
		/// <summary>
		/// Create instance with a seed
		/// </summary>
		/// <param name="seed"></param>
		public RandomPoint(int seed)
		{
			this.Init(seed);
		}
		/// <summary>
		/// Init randomizer from a seed
		/// </summary>
		/// <param name="seed"></param>
		public void Init(int seed)
		{
			this.counter = 0;
			this.seed = seed;
			random = new Random(seed);
		}
		/// <summary>
		/// Get seed value
		/// </summary>
		public int Seed
		{
			get { return seed; }
		}
		/// <summary>
		/// Get number calls to random since initialized with seed
		/// </summary>
		public int Counter
		{
			get { return counter; }
		}
		/// <summary>
		/// Random point on unit sphere
		/// </summary>
		/// <returns></returns>
		public Cartesian Next()
		{
			double x,y,z;
			do 
			{
				x = 2*random.NextDouble()-1; counter++;
				y = 2*random.NextDouble()-1; counter++;
				z = 2*random.NextDouble()-1; counter++;
			}
			while (x*x+y*y+z*z>=1);

			return new Cartesian(x,y,z,true);
		}
		/// <summary>
		/// Random point in given constraint (all-sky keeps going until enough inside)
		/// </summary>
		/// <param name="halfSpace"></param>
		/// <returns></returns>
		public Cartesian Next(Halfspace halfSpace)
		{
			Cartesian p = Next();
			while(!halfSpace.Covers(p,0)) p = Next();
			return p;
		}
		/// <summary>
		/// Random point in given constraint (all-sky keeps going until enough inside)
		/// </summary>
		/// <param name="convex"></param>
		/// <returns></returns>
		public Cartesian Next(Convex convex)
		{
			Cartesian p = Next();
			while(!convex.Covers(p,0)) p = Next();
			return p;
		}
		/// <summary>
		/// Random point in given constraint (all-sky keeps going until enough inside)
		/// </summary>
		/// <param name="region"></param>
		/// <returns></returns>
		public Cartesian Next(Region region)
		{
			Cartesian p = Next();
			while(!region.Covers(p,0)) p = Next();
			return p;
		}

        public Cartesian NextSmart(Region region)
        {
            Cartesian p = Next();
            while(!region.SmartCovers(p,0)) p = Next();
            return p;
        }

		/// <summary>
		/// A number of random points in given constraint (all-sky keeps going until enough inside)
		/// </summary>
		/// <param name="num"></param>
		/// <returns></returns>
		public Cartesian[] NextArray(int num)
		{
			Cartesian[] list = new Cartesian[num];
			for (int i=0; i<num; i++)
				list[i] = Next();
			return list;
		}
		/// <summary>
		/// A number of random points in given constraint (all-sky keeps going until enough inside)
		/// </summary>
		/// <param name="num"></param>
		/// <param name="halfSpace"></param>
		/// <returns></returns>
		public Cartesian[] NextArray(int num, Halfspace halfSpace)
		{
			Cartesian[] list = new Cartesian[num];
			for (int i=0; i<num; i++)
				list[i] = Next(halfSpace);
			return list;
		}

		/// <summary>
		/// Revision from CVS
		/// </summary>
		public static string Revision
		{
			get	{ return "$Revision: 1.1.1.1 $"; }
		}

	}
}
#region Revision History
/* Revision History

        $Log: RandomPoint.cs,v $
        Revision 1.1.1.1  2006/11/14 02:56:39  gupchup
        no message

        Revision 1.3  2006/05/09 21:01:12  budavari
        Smart version of Next added

        Revision 1.2  2006/04/19 16:52:13  budavari
        EVerything is now CLS compliant

        Revision 1.1  2006/02/28 16:36:59  budavari
        Module has IO related classes

        Revision 1.1  2006/01/24 15:56:05  budavari
        Re-structured directory layout to accommodate more projects

        Revision 1.8  2005/12/01 22:34:57  budavari
        Area struct added and fully functional

        Revision 1.7  2005/11/30 20:50:28  budavari
        Cosmetics... #region specifications etc added

        Revision 1.6  2005/11/30 19:50:37  budavari
        Dilate() methods added. Also explicit tolerance required everywhere for clarity

        Revision 1.5  2005/11/30 15:31:58  budavari
        Header changes

        Revision 1.4  2005/11/15 22:20:20  budavari
        Using Generics - almost there

        Revision 1.3  2005/11/15 15:25:36  budavari
        Everything is a class, things are coming together for area computation, etc. Will moved to C# 2.0

        Revision 1.2  2005/11/03 15:22:01  budavari
        Fairly major revision to make sure the objects serialize to XML nicely:
          - Added separate containers of halfspaces and convexes
          - Customized XML output for compactness and friendly proxy interface
          - Implemented simple .Parse() methods taking cartesion representation

        Revision 1.1.1.1  2005/10/28 14:13:43  budavari
        Initial import of the SphericalLib library. It is pretty complete in terms
        of the classes but lacking the simplication and other advanced methods.
		
*/
#endregion