Click here to Skip to main content
15,885,951 members
Articles / Desktop Programming / WPF

Equation Calculator with Graphing

Rate me:
Please Sign up or sign in to vote.
4.92/5 (69 votes)
25 Nov 2010CPOL9 min read 132.7K   4.2K   158  
Equation Calculator with Graphing
using System;
using System.Collections.Generic;
using System.Windows.Media;

namespace CommonTools
{
	public struct HSLColor 
	{
		double m_hue;
		double m_saturation;
		double m_lightness;
		// http://en.wikipedia.org/wiki/HSL_color_space

		public double Hue
		{
			get { return m_hue; }
			set { m_hue = value; }
		}
		public double Saturation
		{
			get { return m_saturation; }
			set { m_saturation = value; }
		}
		public double Lightness
		{
			get { return m_lightness; }
			set
			{ 
				m_lightness = value;
				if (m_lightness < 0)
					m_lightness = 0;
				if (m_lightness > 1)
					m_lightness = 1;
			}
		}
		public HSLColor(double hue, double saturation, double lightness)
		{
			m_hue = Math.Min(360, hue);
			m_saturation = Math.Min(1, saturation);
			m_lightness = Math.Min(1, lightness);
			m_avg = 0;
		}
		public HSLColor(Color color)
		{
			m_hue = 0;
			m_saturation = 1;
			m_lightness = 1;
			m_avg = 0;
			FromRGB(color);
		}
		public Color Color
		{
			get { return ToRGB(); }
			set { FromRGB(value); }
		}

		double m_avg;
		public double Avg {get { return m_avg; }}
		void FromRGB(Color cc)
		{
			double r = (double)cc.R / 255d;
			double g = (double)cc.G / 255d;
			double b = (double)cc.B / 255d;
			m_avg = (r*g*b)/3;
			
			double min = Math.Min(Math.Min(r, g), b);
			double max = Math.Max(Math.Max(r, g), b);
			// calulate hue according formula given in
			// "Conversion from RGB to HSL or HSV"
			m_hue = 0;
			if (min != max)
			{
				if (r == max && g >= b)
				{
					m_hue = 60 * ((g - b) / (max - min)) + 0;
				}
				else
				if (r == max && g < b)
				{
					m_hue = 60 * ((g - b) / (max - min)) + 360;
				}
				else
				if (g == max)
				{
					m_hue = 60 * ((b - r) / (max - min)) + 120;
				}
				else
				if (b == max)
				{
					m_hue = 60 * ((r - g) / (max - min)) + 240;
				}
			}
			// find lightness
			m_lightness = (min+max)/2;

			// find saturation
			if (m_lightness == 0 ||min == max)
				m_saturation = 0;
			else
			if (m_lightness > 0 && m_lightness <= 0.5)
				m_saturation = (max-min)/(2*m_lightness);
			else
			if (m_lightness > 0.5)
				m_saturation = (max-min)/(2-2*m_lightness);
		}
		Color ToRGB()
		{
			// convert to RGB according to
			// "Conversion from HSL to RGB"

			double r = m_lightness;
			double g = m_lightness;
			double b = m_lightness;
			if (m_saturation == 0)
				return Color.FromArgb(255, (byte)(r*255), (byte)(g*255), (byte)(b*255));

			double q = 0;
			if (m_lightness < 0.5)
				q = m_lightness * (1 + m_saturation);
			else
				q = m_lightness + m_saturation - (m_lightness * m_saturation);
			double p = 2 * m_lightness - q;
			double hk = m_hue / 360;

			// r,g,b colors
			double[] tc = new double[3] { hk + (1d/3d), hk, hk-(1d/3d)};
			double[] colors = new double[3] {0, 0, 0};

			for (int color = 0; color < colors.Length; color++)
			{
				if (tc[color] < 0)
					tc[color] += 1;
				if (tc[color] > 1)
					tc[color] -= 1;

				if (tc[color] < (1d/6d))
					colors[color] = p + ((q-p)*6*tc[color]);
				else
				if (tc[color] >= (1d/6d) && tc[color] < (1d/2d))
					colors[color] = q;
				else
				if (tc[color] >= (1d/2d) && tc[color] < (2d/3d))
					colors[color] = p + ((q-p)*6*(2d/3d - tc[color]));
				else
					colors[color] = p;

				colors[color] *= 255; // convert to value expected by Color
			}
			return Color.FromArgb(255, (byte)colors[0], (byte)colors[1], (byte)colors[2]);
		}

		public static bool operator != (HSLColor left, HSLColor right)
		{
			return !(left == right);
		}
		public static bool operator == (HSLColor left, HSLColor right)
		{
			return (left.Hue == right.Hue && 
					left.Lightness == right.Lightness && 
					left.Saturation == right.Saturation);
		}
		public override bool Equals(object obj)
		{
			return base.Equals(obj);
		}
		public override int GetHashCode()
		{
			return base.GetHashCode();
		}
		public override string ToString()
		{
			string s = string.Format("HSL({0:f2}, {1:f2}, {2:f2})", Hue, Saturation, Lightness);
			return s;
		}
	}
}

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 (Senior)
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions