コード例 #1
0
        /// <summary>
        /// CDF-based sampling.
        /// </summary>
        /// <param name="random">[0,1] uniform random value.</param>
        /// <param name="rnd">Optional random generator instance. If provided, internal randomization is possible.</param>
        public virtual void GetSample(out double x, out double y, double random, RandomJames rnd = null)
        {
            if (cdf == null)
            {
                CollectCdf();
            }

            // CDF-based importance sampling:
            int    ia = 0;
            int    ib = cdfRes - 1;
            double a  = 0.0;
            double b  = 1.0;

            do
            {
                int    ip = (ia + ib) >> 1;
                double p  = cdf[ip];
                if (p < random)
                {
                    ia = ip;
                    a  = p;
                }
                else
                {
                    ib = ip;
                    b  = p;
                }
            }while (ia + 1 < ib);

            int ix = ia / resolution;
            int iy = ia % resolution;

            x = (ix + (rnd == null ? 0.5 : rnd.UniformNumber())) * pixel;
            y = (iy + (rnd == null ? 0.5 : rnd.UniformNumber())) * pixel;
        }
コード例 #2
0
        /// <summary>
        /// Renders the single pixel of an image.
        /// </summary>
        /// <param name="x">Horizontal coordinate.</param>
        /// <param name="y">Vertical coordinate.</param>
        /// <param name="color">Computed pixel color.</param>
        /// <param name="rnd">Shared random generator.</param>
        public override void RenderPixel(int x, int y, double[] color, RandomJames rnd)
        {
            Debug.Assert(color != null);
            Debug.Assert(rnd != null);

            int bands = color.Length;
            int b;

            Array.Clear(color, 0, bands);
            double[] tmp = new double[bands];

            int    i, j, ord;
            double step = 1.0 / superXY;
            double amplitude = Jittering * step;
            double origin = 0.5 * (step - amplitude);
            double x0, y0;

            for (j = ord = 0, y0 = y + origin; j++ < superXY; y0 += step)
            {
                for (i = 0, x0 = x + origin; i++ < superXY; x0 += step)
                {
                    ImageFunction.GetSample(x0 + amplitude * rnd.UniformNumber(),
                                            y0 + amplitude * rnd.UniformNumber(),
                                            ord++, Supersampling, rnd, tmp);
                    for (b = 0; b < bands; b++)
                    {
                        color[b] += tmp[b];
                    }
                }
            }

            double mul = step / superXY;

            if (Gamma > 0.001)
            {                               // gamma-encoding and clamping
                double g = 1.0 / Gamma;
                for (b = 0; b < bands; b++)
                {
                    color[b] = Arith.Clamp(Math.Pow(color[b] * mul, g), 0.0, 1.0);
                }
            }
            else                            // no gamma, no clamping (for HDRI)
            {
                for (b = 0; b < bands; b++)
                {
                    color[b] *= mul;
                }
            }
        }
コード例 #3
0
ファイル: RasterDrawing.cs プロジェクト: maoap1/grcis-1
        /// <summary>
        /// Allocate large enough colormap..
        /// </summary>
        public static void AssertColors(int num)
        {
            int i;

            if (debugColors == null ||
                debugColors.Count < num)
            {
                debugColors = new List <Color>(num);
                RandomJames rnd = new RandomJames();
                for (i = 0; i < num; i++)
                {
                    int R = rnd.RandomInteger(0, 255);
                    int G = rnd.RandomInteger(0, 255);
                    int B = rnd.RandomInteger(0, 255);
                    if (R >= 128 && G >= 128 && B >= 128)
                    {
                        if (rnd.UniformNumber() > 0.5)
                        {
                            R -= 128;
                        }
                        else
                        {
                            G -= 128;
                        }
                    }
                    debugColors.Add(Color.FromArgb(R, G, B));
                }
            }
        }
コード例 #4
0
ファイル: RasterImage.cs プロジェクト: maoap1/grcis-1
        /// <summary>
        /// CDF-based sampling.
        /// </summary>
        /// <param name="x">Output horizontal coordinate from the [0.0,width) range.</param>
        /// <param name="y">Output vertical coordinate from the [0.0,height) range.</param>
        /// <param name="random">[0,1] uniform random value.</param>
        /// <param name="rnd">Optional random generator instance. If provided, internal randomization is possible.</param>
        public void GetSample(out double x, out double y, double random, RandomJames rnd = null)
        {
            if (cdf == null)
            {
                PrepareCdf();
            }

            // CDF-based importance sampling:
            int    ia = 0;
            int    ib = width * height;
            double a  = 0.0;
            double b  = 1.0;

            do
            {
                int    ip = (ia + ib) >> 1;
                double p  = cdf[ip];
                if (p < random)
                {
                    ia = ip;
                    a  = p;
                }
                else
                {
                    ib = ip;
                    b  = p;
                }
            }while (ia + 1 < ib);

            y = ia / width;
            x = ia % width;

            if (rnd != null)
            {
                x += rnd.UniformNumber();
                y += rnd.UniformNumber();
            }
            else
            {
                x += 0.5;
                y += 0.5;
            }
        }
コード例 #5
0
            public void generateSample(int r, int t)
            {
                if (t > 1)
                {
                    if (r == rank &&
                        t == total)
                    {
                        return;
                    }

                    int uCell, vCell;
                    if (t != total || r < rank) // [re-]initialization
                    {
                        total = t;
                        uCell = rnd.PermutationFirst(total, ref permU);
                        vCell = rnd.PermutationFirst(total, ref permV);
                    }
                    else
                    {
                        uCell = Math.Max(rnd.PermutationNext(ref permU), 0);
                        vCell = Math.Max(rnd.PermutationNext(ref permV), 0);
                    }

                    rank = r;

                    // point sample will be placed into [ uCell, vCell ] cell:
                    u = (uCell + rnd.UniformNumber()) / total;
                    v = (vCell + rnd.UniformNumber()) / total;
                }
                else
                {
                    u = rnd.UniformNumber();
                    v = rnd.UniformNumber();
                }

                // TODO: do something like:
                sample = source.position + u * source.width + v * source.height;
            }
コード例 #6
0
ファイル: FluidSimulator.cs プロジェクト: maoap1/grcis-1
        int ActivateParticles(int nMax)
        {
            int nCount = Math.Min(nMax, particles.Count - activeParticles);

            if (nCount < 1)
            {
                return(0);
            }

            TotalSpawned += nCount;

            int nCountToDo = nCount;

            double fJitterRange = 0.1 / nCountToDo;

            foreach (var par in particles)
            {
                if (nCountToDo <= 0)
                {
                    break;
                }
                else
                if (!par.active)
                {
                    par.active = true;
                    par.x      = xMin + 0.0001;
                    //par.y = yMin + 0.1 * rnd.UniformNumber() + 0.45;
                    par.y  = 0.45 + fJitterRange * (rnd.UniformNumber() + nCountToDo - 1.0);
                    par.fx = 0.0;
                    par.fy = 0.0;
                    par.m  = ParticleMass;
                    par.vx = 0.0;
                    par.vy = 0.0;

                    nCountToDo--;
                }
            }

            activeParticles += nCount;

            return(nCount);
        }
コード例 #7
0
        /// <summary>
        /// Converts the given image into B/W (1bpp) output suitable for high-resolution printer.
        /// </summary>
        /// <param name="input">Input image.</param>
        /// <param name="output">Output (1bpp) image.</param>
        /// <param name="oWidth">Default output image width in pixels.</param>
        /// <param name="oHeight">Default output image height in pixels.</param>
        /// <param name="param">Set of optional text parameters.</param>
        /// <returns>Number of dots printed.</returns>
        public static long TransformImage(Bitmap input, out Bitmap output, int oWidth, int oHeight, string param)
        {
            // !!!{{ TODO: write your own image dithering code here

            int  iWidth  = input.Width;
            int  iHeight = input.Height;
            long dots    = 0L;

            // custom parameters from the text-field:
            double randomness             = 0.0;
            double dot                    = 0.0;
            double gamma                  = 0.0;
            bool   sampling               = false;
            Dictionary <string, string> p = Util.ParseKeyValueList(param);

            if (p.Count > 0)
            {
                double scale = 0.0;

                // scale=<float-number>
                if (Util.TryParse(p, "scale", ref scale) &&
                    scale > 0.01)
                {
                    oWidth  = (int)(iWidth * scale);
                    oHeight = (int)(iHeight * scale);
                }

                // rnd=<float-number>
                if (Util.TryParse(p, "rnd", ref randomness))
                {
                    randomness = Arith.Clamp(randomness, 0.0, 1.0);
                }

                // dot=<float-number>
                if (Util.TryParse(p, "dot", ref dot))
                {
                    dot = Math.Max(dot, 0.0);
                }

                // gamma=<float-number>
                if (Util.TryParse(p, "gamma", ref gamma))
                {
                    gamma = Math.Max(gamma, 0.0);
                }

                // sampling=<bool>
                Util.TryParse(p, "sampling", ref sampling);
            }

            // create output 1bpp Bitmap
            output = new Bitmap(oWidth, oHeight, PixelFormat.Format1bppIndexed);
            float dx = (iWidth - 1.0f) / (oWidth - 1.0f);
            float dy = (iHeight - 1.0f) / (oHeight - 1.0f);

            // set the B/W palette (0 .. black, 1 .. white):
            ColorPalette pal = output.Palette;

            pal.Entries[0] = Color.Black;
            pal.Entries[1] = Color.White;
            output.Palette = pal;

            int         x, y;
            float       fx, fy;
            RandomJames rnd = new RandomJames();

            // convert pixel data (fast memory-mapped code):
            PixelFormat iFormat = input.PixelFormat;

            if (!PixelFormat.Format24bppRgb.Equals(iFormat) &&
                !PixelFormat.Format32bppArgb.Equals(iFormat) &&
                !PixelFormat.Format32bppPArgb.Equals(iFormat) &&
                !PixelFormat.Format32bppRgb.Equals(iFormat))
            {
                iFormat = PixelFormat.Format24bppRgb;
            }

            BitmapData dataOut = output.LockBits(new Rectangle(0, 0, oWidth, oHeight), ImageLockMode.WriteOnly, output.PixelFormat);

            unsafe
            {
                byte *optr;

                // A. placing reasonable number of random dots on the paper
                if (sampling)
                {
                    dot = Math.Max(dot, 1.0);

                    // clear output image:
                    optr = (byte *)dataOut.Scan0;
                    for (x = 0; x++ < oHeight * dataOut.Stride;)
                    {
                        *optr++ = 255;
                    }

                    // create grayscale image able to sample points from itself:
                    FloatImage fi = new FloatImage(input);
                    fi = fi.GrayImage(true, gamma);
                    fi.PrepareCdf();

                    // sample 'dots' random dots:
                    dots = (long)(1.2 * oWidth * oHeight / (dot * dot));
                    double xx, yy;
                    for (long i = 0; i++ < dots;)
                    {
                        fi.GetSample(out xx, out yy, rnd.UniformNumber(), rnd);
                        xx = oWidth * (xx / iWidth);
                        yy = oHeight * (yy / iHeight);
                        Dot1bpp((int)xx, (int)yy, dot, dataOut);
                    }
                }
                else
                {
                    BitmapData dataIn = input.LockBits(new Rectangle(0, 0, iWidth, iHeight), ImageLockMode.ReadOnly, iFormat);

                    // B. random screen using dots bigger than 1px
                    if (dot > 0.0)
                    {
                        // clear output image:
                        optr = (byte *)dataOut.Scan0;
                        for (x = 0; x++ < oHeight * dataOut.Stride;)
                        {
                            *optr++ = 255;
                        }

                        int dI = Image.GetPixelFormatSize(iFormat) / 8;

                        for (y = 0, fy = 0.0f; y < oHeight; y++, fy += dy)
                        {
                            if (!Form1.cont)
                            {
                                break;
                            }

                            for (x = 0, fx = 0.0f; x < oWidth; x++, fx += dx)
                            {
                                float gray = GetGray(fx, fy, dataIn, dI);
                                if (gamma > 0.0)
                                {
                                    gray = (float)Math.Pow(gray, gamma);
                                }

                                float threshold = (float)(0.5 - randomness * (rnd.UniformNumber() - 0.5));
                                if (gray < threshold)
                                {
                                    dots++;
                                    Dot1bpp(x, y, dot, dataOut);
                                }
                            }
                        }
                    }
                    else

                    // C. random screen using individual pixels
                    {
                        int buffer;
                        int dI = Image.GetPixelFormatSize(iFormat) / 8;

                        for (y = 0, fy = 0.0f; y < oHeight; y++, fy += dy)
                        {
                            if (!Form1.cont)
                            {
                                break;
                            }

                            optr   = (byte *)dataOut.Scan0 + y * dataOut.Stride;
                            buffer = 0;

                            for (x = 0, fx = 0.0f; x < oWidth; fx += dx)
                            {
                                float gray = GetGray(fx, fy, dataIn, dI);
                                if (gamma > 0.0)
                                {
                                    gray = (float)Math.Pow(gray, gamma);
                                }

                                float threshold = (float)(0.5 - randomness * (rnd.UniformNumber() - 0.5));
                                buffer += buffer;
                                if (gray >= threshold)
                                {
                                    buffer++;
                                }
                                else
                                {
                                    dots++;
                                }

                                if ((++x & 7) == 0)
                                {
                                    *optr++ = (byte)buffer;
                                    buffer = 0;
                                }
                            }

                            // finish the last byte of the scanline:
                            if ((x & 7) != 0)
                            {
                                while ((x++ & 7) != 0)
                                {
                                    buffer += buffer;
                                }
                                *optr = (byte)buffer;
                            }
                        }
                    }
                    input.UnlockBits(dataIn);
                }

                output.UnlockBits(dataOut);
            }

            return(dots);

            // !!!}}
        }