// Evenly distributes the colors provided between 0 and 1
        public ColorScale(IEnumerable <Color> colors)
        {
            if (colors == null)
            {
                throw new ArgumentNullException("colors");
            }

            int count = colors.Count();

            _stops = new ColorScaleStop[count];
            int index = 0;

            foreach (Color color in colors)
            {
                // Clean up floating point jaggies
                if (index == 0)
                {
                    _stops[index] = new ColorScaleStop(color, 0);
                }
                else if (index == count - 1)
                {
                    _stops[index] = new ColorScaleStop(color, 1);
                }
                else
                {
                    _stops[index] = new ColorScaleStop(color, (double)index * (1.0 / (double)(count - 1)));
                }
                index++;
            }
        }
        public ColorScale(ColorScale source)
        {
            if (source == null)
            {
                throw new ArgumentNullException("source");
            }

            _stops = new ColorScaleStop[source._stops.Length];
            for (int i = 0; i < _stops.Length; i++)
            {
                _stops[i] = new ColorScaleStop(source._stops[i]);
            }
        }
        public ColorScale(IEnumerable <ColorScaleStop> stops)
        {
            if (stops == null)
            {
                throw new ArgumentNullException("stops");
            }

            int count = stops.Count();

            _stops = new ColorScaleStop[count];
            int index = 0;

            foreach (ColorScaleStop stop in stops)
            {
                _stops[index] = new ColorScaleStop(stop);
                index++;
            }
        }
        public ColorScale Trim(double lowerBound, double upperBound, ColorScaleInterpolationMode mode = ColorScaleInterpolationMode.RGB)
        {
            if (lowerBound < 0 || upperBound > 1 || upperBound < lowerBound)
            {
                throw new ArgumentException("Invalid bounds");
            }
            if (lowerBound == upperBound)
            {
                return(new ColorScale(new Color[] { GetColor(lowerBound, mode) }));
            }
            List <ColorScaleStop> containedStops = new List <ColorScaleStop>(_stops.Length);

            for (int i = 0; i < _stops.Length; i++)
            {
                if (_stops[i].Position >= lowerBound && _stops[i].Position <= upperBound)
                {
                    containedStops.Add(_stops[i]);
                }
            }

            if (containedStops.Count == 0)
            {
                return(new ColorScale(new Color[] { GetColor(lowerBound, mode), GetColor(upperBound, mode) }));
            }

            if (containedStops.First().Position != lowerBound)
            {
                containedStops.Insert(0, new ColorScaleStop(GetColor(lowerBound, mode), lowerBound));
            }
            if (containedStops.Last().Position != upperBound)
            {
                containedStops.Add(new ColorScaleStop(GetColor(upperBound, mode), upperBound));
            }

            double range = upperBound - lowerBound;

            ColorScaleStop[] finalStops = new ColorScaleStop[containedStops.Count];
            for (int i = 0; i < finalStops.Length; i++)
            {
                double adjustedPosition = (containedStops[i].Position - lowerBound) / range;
                finalStops[i] = new ColorScaleStop(containedStops[i].Color, adjustedPosition);
            }
            return(new ColorScale(finalStops));
        }
 public ColorScaleStop(ColorScaleStop source)
 {
     Color    = source.Color;
     Position = source.Position;
 }