Ejemplo n.º 1
0
        /// <summary>
        /// </summary>
        /// <param name="controls"></param>
        /// <param name="numColors"></param>
        /// <param name="extrapolationType"></param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException"><paramref name="source" /> or <paramref name="selector" /> is null.</exception>
        /// <exception cref="ArgumentException"><paramref name="red" />, <paramref name="green" />, or <paramref name="blue" /> is less than 0 or greater than 255.</exception>
        /// <exception cref="OverflowException">The number of elements in <paramref name="source" /> is larger than <see cref="F:System.Int32.MaxValue" />.</exception>
        /// <exception cref="InvalidOperationException"><paramref name="source" /> contains no elements.</exception>
        /// <exception cref="Exception">A delegate callback throws an exception.</exception>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="count" /> is less than 0.-or-<paramref name="start" /> + <paramref name="count" /> -1 is larger than <see cref="F:System.Int32.MaxValue" />.</exception>
        public static RgbValue[] GenerateColorPalette(Tuple <double, Color>[] controls, int numColors,
                                                      MathUtilities.ExtrapolationType extrapolationType = MathUtilities.ExtrapolationType.None)
        {
            var palette          = new RgbValue[numColors];
            var controlCount     = controls.Length;
            var oneOverNumColors = 1.0 / numColors;

            double[] red = new double[controlCount],
            green = new double[controlCount],
            blue  = new double[controlCount],
            xs    = new double[controlCount];
            for (var i = 0; i < controlCount; ++i)
            {
                red[i]   = controls[i].Item2.R;
                green[i] = controls[i].Item2.G;
                blue[i]  = controls[i].Item2.B;
                xs[i]    = controls[i].Item1;
            }
            var channelSplines = new[]
            {
                MathUtilities.CreateInterpolant(xs, red, extrapolationType),
                MathUtilities.CreateInterpolant(xs, green, extrapolationType),
                MathUtilities.CreateInterpolant(xs, blue, extrapolationType)
            };

            for (var i = 0; i < numColors; ++i)
            {
                var arg = i * oneOverNumColors;
                palette[i]       = new RgbValue();
                palette[i].red   = MathUtilities.Clamp((int)channelSplines[0](arg), 0, 255);
                palette[i].green = MathUtilities.Clamp((int)channelSplines[1](arg), 0, 255);
                palette[i].blue  = MathUtilities.Clamp((int)channelSplines[2](arg), 0, 255);
            }
            return(palette);
        }
Ejemplo n.º 2
0
        public static RgbValue[] LoadPalette(string path)
        {
            List <RgbValue> pallete = new List <RgbValue>();

            using (StreamReader palleteData = new StreamReader(path))
            {
                while (!palleteData.EndOfStream)
                {
                    try
                    {
                        string palleteString = palleteData.ReadLine();
                        if (string.IsNullOrWhiteSpace(palleteString))
                        {
                            continue;
                        }

                        string[] palleteTokens =
                            palleteString.Split(new char[1] {
                            ' '
                        }, StringSplitOptions.RemoveEmptyEntries);
                        int      r     = int.Parse(palleteTokens[0]);
                        int      g     = int.Parse(palleteTokens[1]);
                        int      b     = int.Parse(palleteTokens[2]);
                        RgbValue color = new RgbValue(r, g, b);
                        pallete.Add(color);
                    }
                    catch (FormatException)
                    {
                    }
                }

                return(pallete.ToArray());
            }
        }
Ejemplo n.º 3
0
        public static RgbValue LerpColors(RgbValue a, RgbValue b, double alpha)
        {
            // Initialize final color
            RgbValue c = new RgbValue();

            // Linear interpolate red, green, and blue values.
            c.red = (int)Lerp(a.red, b.red, alpha);

            c.green = (int)Lerp(a.green, b.green, alpha);

            c.blue = (int)Lerp(a.blue, b.blue, alpha);

            return(c);
        }
Ejemplo n.º 4
0
        public static double FindPaletteColorLocation(RgbValue[] palette, RgbValue color)
        {
            var locationOfPaletteColorClosestToBlack = 0.0;
            var distanceOfPaletteColorClosestToBlack = EuclideanDistance(palette[0], color);

            for (var i = 1; i < palette.Length; ++i)
            {
                var distanceOfCurrentColorFromBlack = EuclideanDistance(palette[i], color);
                if (Math.Abs(distanceOfCurrentColorFromBlack) < MathUtilities.Tolerance)
                {
                    break;
                }
                if (distanceOfCurrentColorFromBlack < distanceOfPaletteColorClosestToBlack)
                {
                    locationOfPaletteColorClosestToBlack = i;
                    distanceOfPaletteColorClosestToBlack = distanceOfCurrentColorFromBlack;
                }
            }
            return(locationOfPaletteColorClosestToBlack / palette.Length);
        }
Ejemplo n.º 5
0
        private static double EuclideanDistance(RgbValue a, RgbValue b)
        {
            double dR = a.red - b.red, dG = a.green - b.green, dB = a.blue - b.blue;

            return(Math.Sqrt(dR * dR + dG * dG + dB * dB));
        }
Ejemplo n.º 6
0
 /// <summary>
 /// The following code was decompiled by JetBrains dotTrace.
 /// I have subsequently made a couple of micro optimizations,
 /// but it otherwise is equivalent to the DrawMandelbrot code
 /// above.
 /// </summary>
 /// <param name="startX"></param>
 /// <param name="startY"></param>
 /// <param name="width"></param>
 /// <param name="height"></param>
 /// <param name="realStart"></param>
 /// <param name="imaginaryStart"></param>
 /// <param name="maxIterations"></param>
 /// <param name="realScale"></param>
 /// <param name="imaginaryScale"></param>
 /// <param name="scan"></param>
 /// <param name="palette"></param>
 /// <param name="gradient"></param>
 /// <param name="image"></param>
 /// <param name="colors"></param>
 /// <param name="bailoutSquared"></param>
 /// <param name="halfOverLogBailout"></param>
 /// <param name="logBase"></param>
 /// <param name="logMinIterations"></param>
 /// <param name="root"></param>
 /// <param name="rootMinIterations"></param>
 /// <param name="indexScale"></param>
 /// <param name="indexWeight"></param>
 /// <param name="useSqrt"></param>
 /// <param name="maxIterationColor"></param>
 private static void DrawMandelbrotDC(
     int startX,
     int startY,
     int width,
     int height,
     double realStart,
     double imaginaryStart,
     int maxIterations,
     double realScale,
     double imaginaryScale,
     int scan,
     RgbValue[] palette,
     Gradient gradient,
     byte[] image,
     int colors,
     double bailoutSquared,
     double halfOverLogBailout,
     double logBase,
     double logMinIterations,
     double root,
     double rootMinIterations,
     double indexScale,
     double indexWeight,
     bool useSqrt,
     Color maxIterationColor)
 {
     for (int index1 = 0; index1 < height; ++index1)
     {
         for (int index2 = 0; index2 < width; ++index2)
         {
             double num1 = 0.0;
             double num2 = 0.0;
             double num3 = 0.0;
             double num4 = 0.0;
             double d    = 0.0;
             double num5 = (double)index2 * realScale + realStart;
             double num6 = (double)index1 * imaginaryScale + imaginaryStart;
             int    num7;
             double num1num1 = 0.0;
             double num3num3 = 0.0;
             for (num7 = 0; d < bailoutSquared && num7 < maxIterations; ++num7)
             {
                 double num8  = num1num1 - num3num3 + num5;
                 double num9  = 2.0 * num1 * num3 + num6;
                 double num10 = num8 - num1;
                 double num11 = num9 - num3;
                 if (num10 * num10 < 1E-20 && num11 * num11 < 1E-20)
                 {
                     num7 = maxIterations;
                     break;
                 }
                 double num12 = num8 - num2;
                 double num13 = num9 - num4;
                 if (num12 * num12 < 1E-20 && num13 * num13 < 1E-20)
                 {
                     num7 = maxIterations;
                     break;
                 }
                 num2     = num1;
                 num4     = num3;
                 num1     = num8;
                 num3     = num9;
                 num1num1 = num1 * num1;
                 num3num3 = num3 * num3;
                 d        = num1num1 + num3num3; // save num1*num1, num3*num3, used above
             }
             double num14 = Math.Log(Math.Log(d) * halfOverLogBailout) * Mandelbrot.OneOverLog2;
             double num15 = indexScale * ((double)(num7 + 1) - indexWeight * num14);
             if (useSqrt)
             {
                 num15 = Math.Sqrt(num15) - rootMinIterations;
             }
             else if (gradient.RootIndex)
             {
                 num15 = Math.Pow(num15, root) - rootMinIterations;
             }
             if (gradient.LogIndex)
             {
                 num15 = Math.Log(num15, logBase) - logMinIterations;
             }
             double index3 = MathUtilities.NormalizeIndex(num15, colors);
             int    index4 = MathUtilities.PreparePaletteIndex(index3, colors, gradient);
             byte   num16;
             byte   num17;
             byte   num18;
             if (num7 >= maxIterations)
             {
                 num16 = maxIterationColor.R;
                 num17 = maxIterationColor.G;
                 num18 = maxIterationColor.B;
             }
             else
             {
                 RgbValue rgbValue = RgbValue.LerpColors(palette[index4], palette[(index4 + 1) % colors], index3 - (double)(long)index3);
                 num16 = (byte)rgbValue.red;
                 num17 = (byte)rgbValue.green;
                 num18 = (byte)rgbValue.blue;
             }
             int index5 = 3 * ((startY + index1) * scan + (startX + index2));
             image[index5]     = num18;
             image[index5 + 1] = num17;
             image[index5 + 2] = num16;
         }
     }
 }
Ejemplo n.º 7
0
        /// <summary>
        /// </summary>
        /// <param name="startX"></param>
        /// <param name="startY"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <param name="realStart"></param>
        /// <param name="imaginaryStart"></param>
        /// <param name="maxIterations"></param>
        /// <param name="realScale"></param>
        /// <param name="imaginaryScale"></param>
        /// <param name="scan"></param>
        /// <param name="palette"></param>
        /// <param name="gradient"></param>
        /// <param name="image"></param>
        /// <param name="colors"></param>
        /// <param name="bailoutSquared"></param>
        /// <param name="halfOverLogBailout"></param>
        /// <param name="logBase"></param>
        /// <param name="logMinIterations"></param>
        /// <param name="root"></param>
        /// <param name="rootMinIterations"></param>
        /// <param name="indexScale"></param>
        /// <param name="indexWeight"></param>
        /// <param name="useSqrt"></param>
        /// <param name="maxIterationColor"></param>
        private static void DrawMandelbrot(
            int startX, int startY,
            int width, int height,
            double realStart, double imaginaryStart,
            int maxIterations,
            double realScale, double imaginaryScale,
            int scan, RgbValue[] palette, Gradient gradient, byte[] image, int colors,
            double bailoutSquared, double halfOverLogBailout,
            double logBase, double logMinIterations,
            double root, double rootMinIterations,
            double indexScale, double indexWeight,
            bool useSqrt, Color maxIterationColor)
        {
            for (var py = 0; py < height; ++py)
            {
                for (var px = 0; px < width; ++px)
                {
                    double x = 0.0, xp = 0.0;    // x;
                    double y = 0.0, yp = 0.0;    // y;
                    var    modulusSquared = 0.0; // x * x + y * y;
                    var    x0             = px * realScale + realStart;
                    var    y0             = py * imaginaryScale + imaginaryStart;
                    var    iterations     = 0;
                    while (modulusSquared < bailoutSquared && iterations < maxIterations)
                    {
                        var    xtemp = x * x - y * y + x0;
                        var    ytemp = 2 * x * y + y0;
                        double dx    = xtemp - x,
                               dy    = ytemp - y,
                               dxp   = xtemp - xp,
                               dyp   = ytemp - yp;
                        if ((dx * dx < Epsilon && dy * dy < Epsilon) ||
                            (dxp * dxp < Epsilon && dyp * dyp < Epsilon))
                        {
                            iterations = maxIterations;
                            break;
                        }
                        xp             = x;
                        yp             = y;
                        x              = xtemp;
                        y              = ytemp;
                        modulusSquared = x * x + y * y;
                        ++iterations;
                    }
                    var smoothed = Math.Log(Math.Log(modulusSquared) * halfOverLogBailout) * OneOverLog2;
                    var index    = indexScale * (iterations + 1 - indexWeight * smoothed);
                    if (useSqrt)
                    {
                        index = Math.Sqrt(index) - rootMinIterations;
                    }
                    else if (gradient.RootIndex)
                    {
                        index = Math.Pow(index, root) - rootMinIterations;
                    }
                    if (gradient.LogIndex)
                    {
                        index = Math.Log(index, logBase) - logMinIterations;
                    }
                    index = MathUtilities.NormalizeIndex(index, colors);
                    var actualIndex = MathUtilities.PreparePaletteIndex(index, colors, gradient);

                    byte red, green, blue;
                    if (iterations >= maxIterations)
                    {
                        red   = maxIterationColor.R;
                        green = maxIterationColor.G;
                        blue  = maxIterationColor.B;
                    }
                    else
                    {
                        var outval = RgbValue.LerpColors(
                            palette[actualIndex],
                            palette[(actualIndex + 1) % colors],
                            index - (long)index);
                        //Palette.Lerp(
                        //    palette[actualIndex],
                        //    palette[(actualIndex + 1) % colors],
                        //    index - (long)index,
                        //    out red, out green, out blue);
                        red   = (byte)outval.red;
                        green = (byte)outval.green;
                        blue  = (byte)outval.blue;
                    }
                    var offset = BitDepthFor24BppRgb * ((startY + py) * scan + (startX + px));
                    image[offset]     = blue;
                    image[offset + 1] = green;
                    image[offset + 2] = red;
                }
            }
        }