static public Hsl FromHsl(double hue, double saturation, double luminosity)
        {
            var hsl = new Hsl
            {
                Hue        = hue,
                Saturation = saturation,
                Luminosity = luminosity
            };

            return(hsl);
        }
        public static Hsl FromAhsl(double alpha, double hue, double saturation, double luminosity)
        {
            var hsl = new Hsl
            {
                Alpha      = alpha,
                Hue        = hue,
                Saturation = saturation,
                Luminosity = luminosity
            };

            return(hsl);
        }
        public static Color FromHsl(Hsl hsl)
        {
            Func <double, double, double, double> hueToRgb = (c, t1, t2) =>
            {
                if (c < 0)
                {
                    c += 1.0;
                }
                if (c > 1)
                {
                    c -= 1.0;
                }
                if (6.0 * c < 1.0)
                {
                    return(t1 + (t2 - t1) * 6.0 * c);
                }
                if (2.0 * c < 1.0)
                {
                    return(t2);
                }
                if (3.0 * c < 2.0)
                {
                    return(t1 + (t2 - t1) * (2.0 / 3.0 - c) * 6.0);
                }
                return(t1);
            };

            int alpha = (int)Math.Round(hsl.Alpha * 255.0);

            if (Math.Abs(hsl.Saturation) < Hsl.MaxHslColorPrecision)
            {
                var mono = (int)Math.Round(hsl.Luminosity * 255.0);
                return(Color.FromArgb(alpha, mono, mono, mono));
            }
            else
            {
                double t2 = hsl.Luminosity < 0.5
                                        ? hsl.Luminosity * (1.0 + hsl.Saturation)
                                        : (hsl.Luminosity + hsl.Saturation) - (hsl.Luminosity * hsl.Saturation);
                double t1 = 2.0 * hsl.Luminosity - t2;

                var r = (int)Math.Round(hueToRgb(hsl.Hue + 1.0 / 3.0, t1, t2) * 255.0);
                var g = (int)Math.Round(hueToRgb(hsl.Hue, t1, t2) * 255.0);
                var b = (int)Math.Round(hueToRgb(hsl.Hue - 1.0 / 3.0, t1, t2) * 255.0);

                return(Color.FromArgb(alpha, r, g, b));
            }
        }
        public static Hsl ToHsl(this Color color)
        {
            double r = (color.R / 255.0);
            double g = (color.G / 255.0);
            double b = (color.B / 255.0);

            double min   = Math.Min(Math.Min(r, g), b);
            double max   = Math.Max(Math.Max(r, g), b);
            double delta = max - min;

            Hsl hsl = new Hsl();

            hsl.Alpha      = color.A / 255.0;
            hsl.Luminosity = ((max + min) / 2.0);

            if (Math.Abs(delta) > Hsl.MaxHslColorPrecision)
            {
                if (hsl.Luminosity < 0.5)
                {
                    hsl.Saturation = (delta / (max + min));
                }
                else
                {
                    hsl.Saturation = (delta / (2.0 - max - min));
                }

                if (Math.Abs(r - max) < Hsl.MaxHslColorPrecision)
                {
                    hsl.Hue = (g - b) / delta + (g < b ? 6 : 0);
                }
                else if (Math.Abs(g - max) < Hsl.MaxHslColorPrecision)
                {
                    hsl.Hue = 2 + (b - r) / delta;
                }
                else
                {
                    hsl.Hue = 4 + (r - g) / delta;
                }
                hsl.Hue = hsl.Hue / 6.0;
            }

            return(hsl);
        }
 public static Color FromAhsl(double alpha, double hue, double saturation, double luminosity)
 {
     return(FromHsl(Hsl.FromAhsl(alpha, hue, saturation, luminosity)));
 }