Click here to Skip to main content
15,886,816 members
Articles / Desktop Programming / Windows Forms

Visualization of the 2D Voronoi Diagram and the Delaunay Triangulation

Rate me:
Please Sign up or sign in to vote.
4.64/5 (17 votes)
18 Nov 2008CPOL 90.7K   3.4K   38  
An add-on for the Fortune's algorithm.
using System;
using System.Collections;
using Voronoi.Data;

namespace Voronoi.Mathematics
{
	/// <summary>
	/// A vector class, implementing all interesting features of vectors
	/// </summary>
	public class Vector : IEnumerable, IComparable
	{
		/// <summary>
		/// Global precision for any calculation
		/// </summary>
		public static int Precision = 10;
		double[] data;
		public object Tag=null;
		/// <summary>
		/// Build a new vector
		/// </summary>
		/// <param name="dim">The dimension</param>
		public Vector(int dim)
		{
			data = new double[dim];
		}
		/// <summary>
		/// Build a new vector
		/// </summary>
		/// <param name="X">The elements of the vector</param>
		public Vector(params double[] X)
		{
			data = new double[X.Length];
			X.CopyTo(data,0);
		}
		/// <summary>
		/// Build a new vector as a copy of an existing one
		/// </summary>
		/// <param name="O">The existing vector</param>
		public Vector(Vector O)
			: this(O.data)
		{}
		/// <summary>
		/// Build a new vector from a string
		/// </summary>
		/// <param name="S">A string, as produced by ToString</param>
		public Vector(string S)
		{
			if(S[0]!='(' || S[S.Length-1]!=')')
				throw new Exception("Formatfehler!");
			string[] P = MathTools.HighLevelSplit(S.Substring(1,S.Length-2),';');
			data = new double[P.Length];
			int i;
			for(i=0;i<data.Length;i++)
			{
				data[i] = Convert.ToDouble(P[i]);
			}
		}
		/// <summary>
		/// Gets or sets the value of the vector at the given index
		/// </summary>
		public double this [int i]
		{
			get
			{
				return data[i];
			}
			set
			{
				data[i] = Math.Round(value,Precision);
			}
		}

		/// <summary>
		/// The dimension of the vector
		/// </summary>
		public int Dim
		{
			get
			{
				return data.Length;
			}
		}

		/// <summary>
		/// The squared length of the vector
		/// </summary>
		public double SquaredLength
		{
			get
			{
				return this*this;
			}
		}

		/// <summary>
		/// The sum of all elements in the vector
		/// </summary>
		public double ElementSum
		{
			get
			{
				int i;
				double E = 0;
				for(i=0;i<Dim;i++)
					E+=data[i];
				return E;
			}
		}
		/// <summary>
		/// Reset all elements with ransom values from the given range
		/// </summary>
		/// <param name="Min">Min</param>
		/// <param name="Max">Max</param>
		public void Randomize(double Min, double Max)
		{
			int i;
			for(i=0;i<data.Length;i++)
			{
				this[i] = Min + (Max-Min)*MathTools.R.NextDouble();
			}
		}
		/// <summary>
		/// Reset all elements with ransom values from the given range
		/// </summary>
		/// <param name="MinMax">MinMax[0] - Min
		/// MinMax[1] - Max</param>
		public void Randomize(Vector[] MinMax)
		{
			int i;
			for(i=0;i<data.Length;i++)
			{
				this[i] = MinMax[0][i] + (MinMax[1][i]-MinMax[0][i])*MathTools.R.NextDouble();
			}
		}
		/// <summary>
		/// Scale all elements by r
		/// </summary>
		/// <param name="r">The scalar</param>
		public void Multiply(double r)
		{
			int i;
			for(i=0;i<data.Length;i++)
			{
				this[i] *= r;
			}
		}
		/// <summary>
		/// Add another vector
		/// </summary>
		/// <param name="V">V</param>
		public void Add(Vector V)
		{
			int i;
			for(i=0;i<data.Length;i++)
			{
				this[i] += V[i];
			}
		}
		/// <summary>
		/// Add a constant to all elements
		/// </summary>
		/// <param name="d">The constant</param>
		public void Add(double d)
		{
			int i;
			for(i=0;i<data.Length;i++)
			{
				this[i] += d;
			}
		}
		IEnumerator IEnumerable.GetEnumerator()
		{
			return data.GetEnumerator();
		}

		/// <summary>
		/// Convert the vector into a reconstructable string representation
		/// </summary>
		/// <returns>A string from which the vector can be rebuilt</returns>
		public override string ToString()
		{
			string S = "(";
			int i;
			for(i=0;i<data.Length;i++)
			{
				S += data[i].ToString("G4");
				if(i<data.Length-1)
					S+=";";
			}
			S+=")";
			return S;
		}

		/// <summary>
		/// Compares this vector with another one
		/// </summary>
		/// <param name="obj"></param>
		/// <returns></returns>
		public override bool Equals(object obj)
		{
			Vector B = obj as Vector;
			if(B==null || data.Length != B.data.Length)
				return false;
			int i;
			for(i=0;i<data.Length;i++)
			{
				if(/*!data[i].Equals(B.data[i]) && */Math.Abs(data[i]-B.data[i])>1e-10)
					return false;
			}
			return true;
		}

		/// <summary>
		/// Retrieves a hashcode that is dependent on the elements
		/// </summary>
		/// <returns>The hashcode</returns>
		public override int GetHashCode()
		{
			int Erg = 0;
			foreach(double D in data)
				Erg = Erg ^ Math.Round(D,Precision).GetHashCode();
			return Erg;
		}

		/// <summary>
		/// Subtract two vectors
		/// </summary>
		public static Vector operator - (Vector A, Vector B)
		{
			if(A.Dim!=B.Dim)
				throw new Exception("Vectors of different dimension!");
			Vector Erg = new Vector(A.Dim);
			int i;
			for(i=0;i<A.Dim;i++)
				Erg[i]=A[i]-B[i];
			return Erg;
		}

		/// <summary>
		/// Add two vectors
		/// </summary>
		public static Vector operator + (Vector A, Vector B)
		{
			if(A.Dim!=B.Dim)
				throw new Exception("Vectors of different dimension!");
			Vector Erg = new Vector(A.Dim);
			int i;
			for(i=0;i<A.Dim;i++)
				Erg[i]=A[i]+B[i];
			return Erg;
		}

		/// <summary>
		/// Get the scalar product of two vectors
		/// </summary>
		public static double operator * (Vector A, Vector B)
		{
			if(A.Dim!=B.Dim)
				throw new Exception("Vectors of different dimension!");
			double Erg = 0;
			int i;
			for(i=0;i<A.Dim;i++)
				Erg+=A[i]*B[i];
			return Erg;
		}

		/// <summary>
		/// Scale one vector
		/// </summary>
		public static Vector operator * (Vector A, double B)
		{
			Vector Erg = new Vector(A.Dim);
			int i;
			for(i=0;i<A.Dim;i++)
				Erg[i]=A[i]*B;
			return Erg;
		}

		/// <summary>
		/// Scale one vector
		/// </summary>
		public static Vector operator * (double A, Vector B)
		{
			return B*A;
		}
		/// <summary>
		/// Interprete the vector as a double-array
		/// </summary>
		public static explicit operator double[](Vector A)
		{
			return A.data;
		}
		/// <summary>
		/// Get the distance of two vectors
		/// </summary>
		public static double Dist(Vector V1, Vector V2)
		{
			if(V1.Dim != V2.Dim)
				return -1;
			int i;
			double E = 0,D;
			for(i=0;i<V1.Dim;i++)
			{
				D=(V1[i]-V2[i]);
				E+=D*D;
			}
			return E;

		}

		/// <summary>
		/// Compare two vectors
		/// </summary>
		public int CompareTo(object obj)
		{
			Vector A = this;
			Vector B = obj as Vector;
			if(A==null || B==null)
				return 0;
			double Al,Bl;
			Al = A.SquaredLength;
			Bl = B.SquaredLength;
			if(Al>Bl)
				return 1;
			if(Al<Bl)
				return -1;
			int i;
			for(i=0;i<A.Dim;i++)
			{
				if(A[i]>B[i])
					return 1;
				if(A[i]<B[i])
					return -1;
			}
			return 0;
		}
		/// <summary>
		/// Get a copy of one vector
		/// </summary>
		/// <returns></returns>
		public virtual Vector Clone()
		{
			return new Vector(data);
		}
	}

}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
Russian Federation Russian Federation
Hello! My name is Maxim Subbotin.

Now I work in sphere of web-development. I'm interesting researches in SEO field.
If you interesting, you can see this tool:

KeywordCompetitor

Comments and Discussions