Exemplo n.º 1
0
        static void GradientColour(double z, Gradient grad, out double r, out double g, out double b, out double a)
        {
            r = g = b = a = 0;
            if (grad == null)
            {
                return;
            }

            z = Math.Min(1.0, Math.Max(0.0, z));
            var seg = GetSegmentAt(grad, z);

            double middle, factor = 0;
            double seglen = seg.right - seg.left;

            if (seglen < double.Epsilon)
            {
                middle = 0.5;
                z      = 0.5;
            }
            else
            {
                middle = (seg.middle - seg.left) / seglen;
                z      = (z - seg.left) / seglen;
            }

            switch (seg.type)
            {
            case GradType.Linear:
                factor = CalcLinearFactor(middle, z);
                break;

            case GradType.Curved:
                if (middle < double.Epsilon)
                {
                    middle = double.Epsilon;
                }
                factor = Math.Pow(z, Math.Log(0.5) / Math.Log(middle));
                break;

            case GradType.Sine:
                z      = CalcLinearFactor(middle, z);
                factor = (Math.Sin((-Math.PI / 2.0) + Math.PI * z) + 1.0) / 2.0;
                break;

            case GradType.SphereInc:
                z      = CalcLinearFactor(middle, z) - 1.0;
                factor = Math.Sqrt(1.0 - z * z);
                break;

            case GradType.SphereDec:
                z      = CalcLinearFactor(middle, z);
                factor = 1.0 - Math.Sqrt(1.0 - z * z);
                break;

            default:
                throw new ArgumentException("Corrupt gradient");
            }

            a = seg.a0 + (seg.a1 - seg.a0) * factor;

            if (seg.color == GradColor.RGB)
            {
                r = seg.r0 + (seg.r1 - seg.r0) * factor;
                g = seg.g0 + (seg.g1 - seg.g0) * factor;
                b = seg.b0 + (seg.b1 - seg.b0) * factor;
            }
            else
            {
                double h0, s0, v0;
                ColorHelpers.RGBtoHSV(seg.r0, seg.g0, seg.b0, out h0, out s0, out v0);
                double h1, s1, v1;
                ColorHelpers.RGBtoHSV(seg.r1, seg.g1, seg.b1, out h1, out s1, out v1);
                s0 = s0 + (s1 - s0) * factor;
                v0 = v0 + (v1 - v0) * factor;

                switch (seg.color)
                {
                case GradColor.HSVccw:
                    if (h0 < h1)
                    {
                        h0 = h0 + (h1 - h0) * factor;
                    }
                    else
                    {
                        h0 = h0 + (1.0 - (h0 - h1)) * factor;
                        if (h0 > 1.0)
                        {
                            h0 -= 1.0;
                        }
                    }
                    break;

                case GradColor.HSVcw:
                    if (h1 < h0)
                    {
                        h0 = h0 - (h0 - h1) * factor;
                    }
                    else
                    {
                        h0 = h0 - (1.0 - (h1 - h0)) * factor;
                        if (h0 < 0.0)
                        {
                            h0 += 1.0;
                        }
                    }
                    break;

                default:
                    throw new ArgumentException("unknown colour model");
                }
                ColorHelpers.HSVtoRGB(h0, s0, v0, out r, out g, out b);
            }
        }
Exemplo n.º 2
0
        static GradSegment ParseSeg(string line)
        {
            int           element = 0;
            StringBuilder chunk   = new StringBuilder();
            double        num     = double.NaN;
            GradSegment   seg     = new GradSegment();

            line += " ";

            foreach (char c in line)
            {
                if (!char.IsWhiteSpace(c))
                {
                    chunk.Append(c);
                    continue;
                }

                double.TryParse(chunk.ToString(), out num);
                if (double.IsInfinity(num) || double.IsNaN(num))
                {
                    throw new ArgumentOutOfRangeException("unexpected value found");
                }

                switch (element)
                {
                case 00: seg.left = num; break;

                case 01: seg.middle = num; break;

                case 02: seg.right = num; break;

                case 03: seg.r0 = num; break;

                case 04: seg.g0 = num; break;

                case 05: seg.b0 = num; break;

                case 06: seg.a0 = num; break;

                case 07: seg.r1 = num; break;

                case 08: seg.g1 = num; break;

                case 09: seg.b1 = num; break;

                case 10: seg.a1 = num; break;

                case 11: seg.type = (GradType)((int)num); break;

                case 12: seg.color = (GradColor)((int)num); break;
                }
                chunk.Clear();
                element++;
            }

            if (seg.color == GradColor.HSVshort || seg.color == GradColor.HSVlong)
            {
                double h0, s0, v0, h1, s1, v1;
                ColorHelpers.RGBtoHSV(seg.r0, seg.g0, seg.b0, out h0, out s0, out v0);
                ColorHelpers.RGBtoHSV(seg.r1, seg.g1, seg.b1, out h1, out s1, out v1);
                seg.color = GradHSVType(seg.color, h0, h1);
            }
            if (!Enum.IsDefined(typeof(GradColor), seg.color))
            {
                throw new ArgumentOutOfRangeException("unknown colour model");
            }
            return(seg);
        }