Click here to Skip to main content
15,896,118 members
Articles / Desktop Programming / WPF

OpenWPFChart: Assembling Charts from Components. Part II - Controls

Rate me:
Please Sign up or sign in to vote.
4.90/5 (14 votes)
26 Mar 2009CPOL10 min read 70.2K   2.2K   52  
Chart controls composed from Chart Parts
// Ported from "Numerical Recipes in C, 2-nd Edition" to C# 3.0.
// Chapter 5.4 Complex Arithmetic
// file Complex.cs
// <revision>$Id: Complex.cs 18093 2009-03-16 04:15:06Z unknown $</revision>

using System;
using System.Globalization; // For CultureInfo

namespace NumericalRecipes
{

	/// <summary>
	/// Complex Number
	/// </summary>
	/// <exclude />
	public struct Complex
	{
		/// <summary>
		/// Zero (0, 0) Complex Number.
		/// </summary>
		public static readonly Complex Zero = new Complex();

		#region Constructors
		/// <summary>
		/// Initializes a new instance of the <see cref="Complex"/> struct.
		/// </summary>
		/// <param name="re">The re.</param>
		/// <param name="im">The im.</param>
		/// <overloads>This method has two overloads</overloads>
		public Complex(double re, double im)
		{
			this.re = re;
			this.im = im;
		}
		/// <summary>
		/// Initializes a new instance of the <see cref="Complex"/> struct.
		/// </summary>
		/// <param name="re">The re.</param>
		public Complex(double re) : this(re, 0d)
		{
		}
		#endregion Constructors

		private double re;
		/// <summary>
		/// Gets or sets the Real part of the Complex value.
		/// </summary>
		/// <value/>
		public double Real
		{
			get { return re; }
		}

		private double im;
		/// <summary>
		/// Gets or sets the Imaginary part of the Complex value.
		/// </summary>
		/// <value/>
		public double Imaginary
		{
			get { return im; }
		}

		#region Object overrides
		/// <inheritdoc />
		public override bool Equals(object obj)
		{
			if (obj == null || obj.GetType() != typeof(Complex))
				return false;
			Complex c = (Complex)obj;
			if (re == c.Real && im == c.Imaginary)
				return true;
			return false;
		}

		/// <inheritdoc />
		public override int GetHashCode()
		{
			return re.GetHashCode() ^ im.GetHashCode();
		}

		/// <inheritdoc />
		public override string ToString()
		{
			if (im == 0.0)
				return re.ToString(CultureInfo.CurrentCulture);
			if (re == 0.0)
				return string.Format(CultureInfo.CurrentCulture, "{0}i{1}", im < 0.0 ? "-" : "+", Math.Abs(im));
			return string.Format(CultureInfo.CurrentCulture, "{0}{1}i{2}", re, im < 0.0 ? "-" : "+", Math.Abs(im));
		}
		#endregion Object overrides

		#region Operators
		/// <summary>
		/// Implements the operator -.
		/// </summary>
		/// <param name="value">The value.</param>
		/// <returns>The result of the operator.</returns>
		public static Complex operator-(Complex value)
		{
			return Negate(value);
		}
		/// <summary>
		/// Implements the operator +.
		/// </summary>
		/// <param name="first">The first.</param>
		/// <param name="second">The second.</param>
		/// <returns>The result of the operator.</returns>
		public static Complex operator+(Complex first, Complex second)
		{
			return Add(first, second);
		}
		/// <summary>
		/// Implements the operator -.
		/// </summary>
		/// <param name="first">The first.</param>
		/// <param name="second">The second.</param>
		/// <returns>The result of the operator.</returns>
		public static Complex operator-(Complex first, Complex second)
		{
			return Subtract(first, second);
		}
		/// <summary>
		/// Implements the operator *.
		/// </summary>
		/// <param name="first">The first.</param>
		/// <param name="second">The second.</param>
		/// <returns>The result of the operator.</returns>
		public static Complex operator*(Complex first, Complex second)
		{
			return Multiply(first, second);
		}
		/// <summary>
		/// Implements the operator *.
		/// </summary>
		/// <param name="first">The first.</param>
		/// <param name="second">The second.</param>
		/// <returns>The result of the operator.</returns>
		public static Complex operator*(double first, Complex second)
		{
			return Multiply(first, second);
		}
		/// <summary>
		/// Implements the operator /.
		/// </summary>
		/// <param name="dividend">The dividend.</param>
		/// <param name="divisor">The divisor.</param>
		/// <returns>The result of the operator.</returns>
		public static Complex operator/(Complex dividend, Complex divisor)
		{
			return Divide(dividend, divisor);
		}
		/// <summary>
		/// Implements the operator ==.
		/// </summary>
		/// <param name="first">The first.</param>
		/// <param name="second">The second.</param>
		/// <returns>The result of the operator.</returns>
		public static bool operator==(Complex first, Complex second)
		{
			return Equals(first, second);
		}
		/// <summary>
		/// Implements the operator !=.
		/// </summary>
		/// <param name="first">The first.</param>
		/// <param name="second">The second.</param>
		/// <returns>The result of the operator.</returns>
		public static bool operator!=(Complex first, Complex second)
		{
			return !(first == second);
		}
		#endregion Operators

		/// <summary>
		/// Negates the specified value.
		/// </summary>
		/// <param name="value">The value.</param>
		/// <returns></returns>
		public static Complex Negate(Complex value)
		{
			return new Complex(-value.Real, -value.Imaginary);
		}

		/// <summary>
		/// Sums up the first and the second arguments.
		/// </summary>
		/// <param name="first">The first item.</param>
		/// <param name="second">The second item.</param>
		/// <returns>The Sum.</returns>
		public static Complex Add(Complex first, Complex second)
		{
			return new Complex(first.Real + second.Real, first.Imaginary + second.Imaginary);
		}

		/// <summary>
		/// Subtracts the specified second argument from the first argument.
		/// </summary>
		/// <param name="first">The first item.</param>
		/// <param name="second">The second item.</param>
		/// <returns>The Difference.</returns>
		public static Complex Subtract(Complex first, Complex second)
		{
			return new Complex(first.Real - second.Real, first.Imaginary - second.Imaginary);
		}

		/// <summary>
		/// Multiplies the first and the second arguments.
		/// </summary>
		/// <param name="first">The first item.</param>
		/// <param name="second">The second item.</param>
		/// <returns>The Product.</returns>
		public static Complex Multiply(Complex first, Complex second)
		{
			return new Complex(first.Real * second.Real - first.Imaginary * second.Imaginary
				, first.Imaginary * second.Real + first.Real * second.Imaginary);
		}

		/// <summary>
		/// Multiplies the first and the second arguments.
		/// </summary>
		/// <param name="first">The first item.</param>
		/// <param name="second">The second item.</param>
		/// <returns>The Product.</returns>
		public static Complex Multiply(double first, Complex second)
		{
			return new Complex(second.Real * first, second.Imaginary * first);
		}

		/// <summary>
		/// Divides the specified dividend by the divisor.
		/// </summary>
		/// <param name="dividend">The dividend item.</param>
		/// <param name="divisor">The divisor item.</param>
		/// <returns>The Quotient.</returns>
		public static Complex Divide(Complex dividend, Complex divisor)
		{
			double div = divisor.Real * divisor.Real + divisor.Imaginary * divisor.Imaginary;
			return new Complex((dividend.Real * divisor.Real + dividend.Imaginary * divisor.Imaginary) / div, (dividend.Imaginary * divisor.Real - dividend.Real * divisor.Imaginary) / div);
		}

		/// <summary>
		/// Tests the specified arguments for equality.
		/// </summary>
		/// <param name="first">The first item.</param>
		/// <param name="second">The second item.</param>
		/// <returns></returns>
		public static bool Equals(Complex first, Complex second)
		{
			return first.Equals(second);
		}

		/// <summary>
		/// Gets the Conjugate value.
		/// </summary>
		/// <param name="value">The value.</param>
		/// <returns></returns>
		public static Complex Conjugate(Complex value)
		{
			return new Complex(value.Real, -value.Imaginary);
		}

		/// <summary>
		/// Gets the Absolute value.
		/// </summary>
		/// <param name="value">The value.</param>
		/// <returns></returns>
		public static double Abs(Complex value)
		{
			double x = Math.Abs(value.Real);
			double y = Math.Abs(value.Imaginary);
			double ans, temp;
			if (x == 0.0)
				ans = y;
			else if (y == 0.0)
				ans = x;
			else if (x > y)
			{
				temp = y / x;
				ans = x * Math.Sqrt(1.0 + temp * temp);
			}
			else
			{
				temp = x / y;
				ans = y * Math.Sqrt(1.0 + temp * temp);
			}
			return ans;
		}

		/// <summary>
		/// Gets the Square root value.
		/// </summary>
		/// <param name="value">The value.</param>
		/// <returns></returns>
		public static Complex Sqrt(Complex value)
		{
			if (value.Real == 0.0 && value.Imaginary == 0.0)
			{
				return new Complex();
			}
			else
			{
				double x = Math.Abs(value.Real);
				double y = Math.Abs(value.Imaginary);
				double w, r;
				if (x >= y)
				{
					r = y / x;
					w = Math.Sqrt(x) * Math.Sqrt(0.5 * (1.0 + Math.Sqrt(1.0 + r * r)));
				}
				else
				{
					r = x / y;
					w = Math.Sqrt(y) * Math.Sqrt(0.5 * (r + Math.Sqrt(1.0 + r * r)));
				}

				if (value.Real >= 0.0)
					return new Complex(w, value.Imaginary / (2.0 * w));
				else
				{
					double im = (value.Imaginary >= 0) ? w : -w;
					return new Complex(value.Imaginary / (2.0 * im), im);
				}
			}
		}
	}
}

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
Team Leader
Russian Federation Russian Federation
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions