コード例 #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
ファイル: FluidSimulator.cs プロジェクト: maoap1/grcis-1
        //--- Public methods ---

        public FluidSimulator(Progress prog, RandomJames _rnd = null)
        {
            // particles:
            particles       = null;
            activeParticles = 0;
            TotalSpawned    = 0L;

            // boundaries:
            walls = null;
            xMin  = 0.0;
            xMax  = 3.0;
            yMin  = 0.0;
            yMax  = 1.0;
            InitWalls();

            progress = prog;

            // random generator:
            rnd = _rnd;
            if (rnd == null)
            {
                rnd = new RandomJames();
                rnd.Randomize();
            }
        }
コード例 #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
 public SamplingState(RectangleLightSource src, RandomJames _rnd)
 {
     source = src;
     rnd    = _rnd;
     permU  = new RandomJames.Permutation();
     permV  = new RandomJames.Permutation();
     rank   = total = 0;
 }
コード例 #5
0
        // Put more TLS data here..

        /// <summary>
        /// Cold init of the thread data.
        /// </summary>
        public static void InitThreadData()
        {
            if (rnd == null)
            {
                rnd = new RandomJames(System.Threading.Thread.CurrentThread.GetHashCode() ^ DateTime.Now.Ticks);
            }

            // Put TLS data init here..
        }
コード例 #6
0
ファイル: Marbles.cs プロジェクト: Woprok/grcis
        public MarblesWorld(string param)
        {
            rnd       = new RandomJames(144);
            MyMarbles = new List <SphereObject>();

            Frames  = 0;
            Time    = 0.0;
            Running = false;
        }
コード例 #7
0
ファイル: Program.cs プロジェクト: maoap1/grcis-1
        static public void Generate()
        {
            wasGenerated = true;

            // !!!{{ TODO - generate and draw maze in SVG format

            string fileName = CmdOptions.options.outputFileName;

            if (string.IsNullOrEmpty(fileName))
            {
                fileName = CmdOptions.options.html ? "out.html" : "out.svg";
            }
            string outFn = Path.Combine(CmdOptions.options.outDir, fileName);

            // SVG output:
            using (StreamWriter wri = new StreamWriter(outFn))
            {
                if (CmdOptions.options.html)
                {
                    wri.WriteLine("<!DOCTYPE html>");
                    wri.WriteLine("<meta charset=\"utf-8\">");
                    wri.WriteLine($"<title>SVG test ({CmdOptions.options.name})</title>");
                    wri.WriteLine(string.Format(CultureInfo.InvariantCulture, "<svg width=\"{0:f0}\" height=\"{1:f0}\">",
                                                CmdOptions.options.width, CmdOptions.options.height));
                }
                else
                {
                    wri.WriteLine(string.Format(CultureInfo.InvariantCulture, "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"{0:f0}\" height=\"{1:f0}\">",
                                                CmdOptions.options.width, CmdOptions.options.height));
                }

                List <Vector2> workList = new List <Vector2>();
                RandomJames    rnd      = new RandomJames();
                if (CmdOptions.options.seed > 0L)
                {
                    rnd.Reset(CmdOptions.options.seed);
                }
                else
                {
                    rnd.Randomize();
                }

                for (int i = 0; i < CmdOptions.options.columns; i++)
                {
                    workList.Add(new Vector2(rnd.RandomFloat(0.0f, (float)CmdOptions.options.width),
                                             rnd.RandomFloat(0.0f, (float)CmdOptions.options.height)));
                }

                drawCurve(wri, workList, 0, 0, string.Format("#{0:X2}{0:X2}{0:X2}", 0));

                wri.WriteLine("</svg>");

                // !!!}}
            }
        }
コード例 #8
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;
                }
            }
        }
コード例 #9
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 virtual void RenderPixel(int x, int y, double[] color, RandomJames rnd)
        {
            ImageFunction.GetSample(x + 0.5, y + 0.5, color);

            // gamma-encoding:
            if (Gamma > 0.001)
            {                               // gamma-encoding and clamping
                double g = 1.0 / Gamma;
                for (int b = 0; b < color.Length; b++)
                {
                    color[b] = Arith.Clamp(Math.Pow(color[b], g), 0.0, 1.0);
                }
            }
            // else: no gamma, no clamping (for HDRI)
        }
        /// <summary>
        /// Computes one image sample. Internal integration support.
        /// </summary>
        /// <param name="x">Horizontal coordinate.</param>
        /// <param name="y">Vertical coordinate.</param>
        /// <param name="rank">Rank of this sample, 0 <= rank < total (for integration).</param>
        /// <param name="total">Total number of samples (for integration).</param>
        /// <param name="rnd">Global (per-thread) instance of the random generator.</param>
        /// <param name="color">Computed sample color.</param>
        /// <returns>Hash-value used for adaptive subsampling.</returns>
        public override long GetSample(double x, double y, int rank, int total, RandomJames rnd, double[] color)
        {
            // initial color = black
            Array.Clear(color, 0, color.Length);

            Vector3d p0, p1;

            if (!scene.Camera.GetRay(x, y, rank, total, rnd, out p0, out p1))
            {
                return(11L);
            }

            long hash = shade(0, 1.0, ref p0, ref p1, rank, total, rnd, color);

            return(hash);
        }
コード例 #11
0
ファイル: Marbles.cs プロジェクト: maoap1/grcis-1
        public MarblesWorld(string param)
        {
            // {{ Parse 'param' if you need..

            // }}

            rnd        = new RandomJames(144);
            centers    = new List <Vector3>();
            radii      = new List <float>();
            velocities = new List <Vector3>();
            colors     = new List <Color>();

            Frames  = 0;
            Time    = 0.0;
            Running = false;
        }
コード例 #12
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;
            }
        }
        /// <summary>
        /// Recursive shading function - computes color contribution of the given ray (shot from the
        /// origin 'p0' into direction vector 'p1''). Recursion is stopped
        /// by a hybrid method: 'importance' and 'level' are checked.
        /// Internal integration support.
        /// </summary>
        /// <param name="level">Current recursion depth.</param>
        /// <param name="importance">Importance of the current ray.</param>
        /// <param name="p0">Ray origin.</param>
        /// <param name="p1">Ray direction vector.</param>
        /// <param name="rank">Rank of this sample, 0 <= rank < total (for integration).</param>
        /// <param name="total">Total number of samples (for integration).</param>
        /// <param name="rnd">Global (per-thread) instance of the random generator.</param>
        /// <param name="color">Result color.</param>
        /// <returns>Hash-value (ray sub-signature) used for adaptive subsampling.</returns>
        protected virtual long shade(int level, double importance, ref Vector3d p0, ref Vector3d p1,
                                     int rank, int total, RandomJames rnd, double[] color)
        {
            int bands = color.Length;
            LinkedList <Intersection> intersections = scene.Intersectable.Intersect(p0, p1);

            Intersection.countRays++;
            Intersection i = Intersection.FirstIntersection(intersections, ref p1);
            int          b;

            if (i == null)      // no intersection -> background color
            {
                Array.Copy(scene.BackgroundColor, color, bands);
                return(1L);
            }

            // there was at least one intersection
            i.Complete();

            // hash code for adaptive supersampling:
            long hash = i.Solid.GetHashCode();

            // apply all the textures fist..
            if (i.Textures != null)
            {
                foreach (ITexture tex in i.Textures)
                {
                    hash = hash * HASH_TEXTURE + tex.Apply(i, rank, total, rnd);
                }
            }

            p1 = -p1; // viewing vector
            p1.Normalize();

            if (scene.Sources == null || scene.Sources.Count < 1)
            {
                // no light sources at all
                Array.Copy(i.SurfaceColor, color, bands);
            }
            else
            {
                // apply the reflectance model for each source
                i.Material       = (IMaterial)i.Material.Clone();
                i.Material.Color = i.SurfaceColor;
                Array.Clear(color, 0, bands);

                foreach (ILightSource source in scene.Sources)
                {
                    Vector3d dir;
                    double[] intensity = source.GetIntensity(i, rank, total, rnd, out dir);
                    if (intensity != null)
                    {
                        if (DoShadows && !dir.Equals(Vector3d.Zero))
                        {
                            intersections = scene.Intersectable.Intersect(i.CoordWorld, dir);
                            Intersection.countRays++;
                            Intersection si = Intersection.FirstIntersection(intersections, ref dir);
                            // Better shadow testing: intersection between 0.0 and 1.0 kills the lighting
                            if (si != null && !si.Far(1.0, ref dir))
                            {
                                continue;
                            }
                        }

                        double[] reflection = i.ReflectanceModel.ColorReflection(i, dir, p1, ReflectionComponent.ALL);
                        if (reflection != null)
                        {
                            for (b = 0; b < bands; b++)
                            {
                                color[b] += intensity[b] * reflection[b];
                            }
                            hash = hash * HASH_LIGHT + source.GetHashCode();
                        }
                    }
                }
            }

            // check the recursion depth:
            if (level++ >= MaxLevel ||
                !DoReflections && !DoRefractions)
            {
                return(hash);               // no further recursion
            }
            Vector3d r;
            double   maxK;

            double[] comp = new double[bands];
            double   newImportance;

            if (DoReflections)              // trying to shoot a reflected ray..
            {
                Geometry.SpecularReflection(ref i.Normal, ref p1, out r);
                double[] ks = i.ReflectanceModel.ColorReflection(i, p1, r, ReflectionComponent.SPECULAR_REFLECTION);
                if (ks != null)
                {
                    maxK = ks[0];
                    for (b = 1; b < bands; b++)
                    {
                        if (ks[b] > maxK)
                        {
                            maxK = ks[b];
                        }
                    }

                    newImportance = importance * maxK;
                    if (newImportance >= MinImportance) // do compute the reflected ray
                    {
                        hash += HASH_REFLECT * shade(level, newImportance, ref i.CoordWorld, ref r, rank, total, rnd, comp);
                        for (b = 0; b < bands; b++)
                        {
                            color[b] += ks[b] * comp[b];
                        }
                    }
                }
            }

            if (DoRefractions)                 // trying to shoot a refracted ray..
            {
                maxK          = i.Material.Kt; // simple solution, no influence of reflectance model yet
                newImportance = importance * maxK;
                if (newImportance < MinImportance)
                {
                    return(hash);
                }

                // refracted ray:
                if ((r = Geometry.SpecularRefraction(i.Normal, i.Material.n, p1)) == null)
                {
                    return(hash);
                }

                hash += HASH_REFRACT * shade(level, newImportance, ref i.CoordWorld, ref r, rank, total, rnd, comp);
                for (b = 0; b < bands; b++)
                {
                    color[b] += maxK * comp[b];
                }
            }

            return(hash);
        }
コード例 #14
0
        /// <summary>
        /// Returns intensity (incl. color) of the source contribution to the given scene point.
        /// Internal integration support.
        /// </summary>
        /// <param name="intersection">Scene point (only world coordinates and normal vector are needed).</param>
        /// <param name="rank">Rank of this sample, 0 <= rank < total (for integration).</param>
        /// <param name="total">Total number of samples (for integration).</param>
        /// <param name="rnd">Global (per-thread) instance of the random generator.</param>
        /// <param name="dir">Direction to the source is set here (zero vector for omnidirectional source). Not normalized!</param>
        /// <returns>Intensity vector in current color space or null if the point is not lit.</returns>
        public override double[] GetIntensity(Intersection intersection, int rank, int total, RandomJames rnd, out Vector3d dir)
        {
            if (rnd == null)
            {
                return(GetIntensity(intersection, out dir));
            }

            SamplingState ss;

            lock ( states )
            {
                if (!states.TryGetValue(rnd.GetHashCode(), out ss))
                {
                    ss = new SamplingState(this, rnd);
                    states.Add(rnd.GetHashCode(), ss);
                }
            }

            // generate a [new] sample:
            ss.generateSample(rank, total);
            dir = ss.sample - intersection.CoordWorld;
            if (Vector3d.Dot(dir, intersection.Normal) <= 0.0)
            {
                return(null);
            }

            if (Dim == null || Dim.Length < 3)
            {
                return(intensity);
            }

            double dist    = dir.Length;
            double dimCoef = 1.0 / (Dim[0] + dist * (Dim[1] + dist * Dim[2]));
            int    bands   = intensity.Length;

            double[] result = new double[bands];
            for (int i = 0; i < bands; i++)
            {
                result[i] = intensity[i] * dimCoef;
            }

            return(result);
        }
コード例 #15
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);

            // !!!}}
        }
コード例 #16
0
 /// <summary>
 /// Returns intensity (incl. color) of the source contribution to the given scene point.
 /// Internal integration support.
 /// </summary>
 /// <param name="intersection">Scene point (only world coordinates and normal vector are needed).</param>
 /// <param name="rank">Rank of this sample, 0 <= rank < total (for integration).</param>
 /// <param name="total">Total number of samples (for integration).</param>
 /// <param name="rnd">Global (per-thread) instance of the random generator.</param>
 /// <param name="dir">Direction to the source is set here (zero vector for omnidirectional source).</param>
 /// <returns>Intensity vector in current color space or null if the point is not lit.</returns>
 public double[] GetIntensity(Intersection intersection, int rank, int total, RandomJames rnd, out Vector3d dir)
 {
     return(GetIntensity(intersection, out dir));
 }
コード例 #17
0
 /// <summary>
 /// Ray-generator. Internal integration support.
 /// </summary>
 /// <param name="x">Origin position within a viewport (horizontal coordinate).</param>
 /// <param name="y">Origin position within a viewport (vertical coordinate).</param>
 /// <param name="rank">Rank of this ray, 0 <= rank < total (for integration).</param>
 /// <param name="total">Total number of rays (for integration).</param>
 /// <param name="rnd">Global (per-thread) instance of the random generator.</param>
 /// <param name="p0">Ray origin.</param>
 /// <param name="p1">Ray direction vector.</param>
 /// <returns>True if the ray (viewport position) is valid.</returns>
 public bool GetRay(double x, double y, int rank, int total, RandomJames rnd, out Vector3d p0, out Vector3d p1)
 {
     return(GetRay(x, y, out p0, out p1));
 }
コード例 #18
0
        public static void Draw(Canvas c, string param)
        {
            int depthOfRecursion = 6;
            int borderWidth      = ((c.Height + c.Width) / (20 * depthOfRecursion) == 0) ? 1 : (c.Height + c.Width) / (20 * depthOfRecursion);

            int         numOfCircles = 1000;
            RandomJames rnd          = new RandomJames();
            long        seed;

            if (long.TryParse(param, NumberStyles.Number, CultureInfo.InvariantCulture, out seed))
            {
                rnd.Reset(seed);
            }

            // naming parameters like RandomJames.Reset(long ijkl), i love it :D
            RecursiveMondrian(rnd, c, new Rect()
            {
                x0 = 0, x1 = c.Width, y0 = 0, y1 = c.Height
            }, borderWidth, 0, depthOfRecursion, numOfCircles);



            // {{ TODO: put your drawing code here

            //  int wq = c.Width  / 4;
            //  int hq = c.Height / 4;
            //  int minq = Math.Min(wq, hq);
            //  double t;
            //  int i, j;
            //  double x, y, r;
            //  RandomJames rnd = new RandomJames();

            //  c.Clear(Color.Black);

            //  // Example of even simpler passing of a numeric value through string param.
            //  long seed;
            //  if (long.TryParse(param, NumberStyles.Number, CultureInfo.InvariantCulture, out seed))
            //    rnd.Reset(seed);

            //  // 1st quadrant - anti-aliased disks in a spiral.
            //  c.SetAntiAlias(true);
            //  const int MAX_DISK = 30;
            //  for (i = 0, t = 0.0; i < MAX_DISK; i++, t += 0.65)
            //  {
            //    r = 5.0 + i * (minq * 0.7 - 5.0) / MAX_DISK;
            //    c.SetColor(Color.FromArgb(i * 255 / MAX_DISK, 255, 255 - i * 255 / MAX_DISK));
            //    c.FillDisc((float)(wq + r * Math.Sin(t)), (float)(hq + r * Math.Cos(t)), (float)(r * 0.3));
            //  }

            //  // 2nd quadrant - anti-aliased random dots in a heart shape..
            //  const int MAX_RND_DOTS = 1000;
            //  double xx, yy, tmp;

            //  for (i = 0; i < MAX_RND_DOTS; i++)
            //  {
            //    // This is called "Rejection Sampling"
            //    do
            //    {
            //      x = rnd.RandomDouble(-1.5, 1.5);
            //      y = rnd.RandomDouble(-1.0, 1.5);
            //      xx = x * x;
            //      yy = y * y;
            //      tmp = xx + yy - 1.0;
            //    } while (tmp * tmp * tmp - xx * yy * y > 0.0);

            //    c.SetColor(Color.FromArgb(rnd.RandomInteger(200, 255),
            //                              rnd.RandomInteger(120, 220),
            //                              rnd.RandomInteger(120, 220)));
            //    c.FillDisc(3.1f * wq + 0.8f * minq * (float)x,
            //               1.2f * hq - 0.8f * minq * (float)y,
            //               rnd.RandomFloat(1.0f, minq * 0.03f));
            //  }

            //  // 4th quadrant - CGG logo.
            //  c.SetColor(COLORS[0]);
            //  for (i = 0; i < DISC_DATA.Length / 3; i++)
            //  {
            //    x = DISC_DATA[i, 0];
            //    y = DISC_DATA[i, 1];
            //    r = DISC_DATA[i, 2];
            //    if (i == FIRST_COLOR)
            //      c.SetColor(COLORS[1]);

            //    c.FillDisc(3.0f * wq + (float)((x - 85.0) * 0.018 * minq),
            //               3.0f * hq + (float)((y - 65.0) * 0.018 * minq),
            //               (float)(r * 0.018 * minq));
            //  }

            //  // 3rd quadrant - disk grid.
            //  const int DISKS = 12;
            //  for (j = 0; j < DISKS; j++)
            //    for (i = 0; i < DISKS; i++)
            //    {
            //      c.SetColor(((i ^ j) & 1) == 0 ? Color.White : Color.Blue);
            //      c.FillDisc(wq + (i - DISKS / 2) * (wq * 1.8f / DISKS),
            //                 3 * hq + (j - DISKS / 2) * (hq * 1.7f / DISKS),
            //                 (((i ^ j) & 15) + 1.0f) / DISKS * minq * 0.08f);
            //    }

            //  // }}
        }
コード例 #19
0
        /// <summary>
        /// Renders the given rectangle into the given raster image.
        /// Has to be re-entrant since this code is started in multiple parallel threads.
        /// </summary>
        /// <param name="image">Pre-initialized raster image.</param>
        /// <param name="sel">Selector for this working thread.</param>
        /// <param name="rnd">Thread-specific random generator.</param>
        public virtual void RenderRectangle(Bitmap image, int x1, int y1, int x2, int y2, ThreadSelector sel, RandomJames rnd)
        {
            bool lead = sel(0L);

            if (lead &&
                ProgressData != null)
            {
                lock ( ProgressData )
                {
                    ProgressData.Finished = 0.0f;
                    ProgressData.Message  = "";
                }
            }

            double[] color = new double[3]; // pixel color

            // run several phases of image rendering:
            int cell = 32;                  // cell size

            while (cell > 1 && cell > Adaptive)
            {
                cell >>= 1;
            }
            int initCell = cell;

            int   x, y;
            bool  xParity, yParity;
            float total   = (x2 - x1) * (y2 - y1);
            long  counter = 0L;
            long  units   = 0;

            do                              // do one phase
            {
                for (y = y1, yParity = false;
                     y < y2;                // one image row
                     y += cell, yParity = !yParity)
                {
                    for (x = x1, xParity = false;
                         x < x2;            // one image cell
                         x += cell, xParity = !xParity)
                    {
                        if (cell == initCell ||
                            xParity || yParity) // process the cell
                        {
                            if (!sel(counter++))
                            {
                                continue;
                            }

                            // determine sample color ..
                            RenderPixel(x, y, color, rnd);

                            if (Gamma <= 0.001)
                            {
                                for (int b = 0; b < color.Length; b++)
                                {
                                    color[b] = Arith.Clamp(color[b], 0.0, 1.0);
                                }
                            }

                            // .. and render it:
                            Color c = Color.FromArgb((int)(color[0] * 255.0),
                                                     (int)(color[1] * 255.0),
                                                     (int)(color[2] * 255.0));
                            lock ( image )
                            {
                                if (cell == 1)
                                {
                                    image.SetPixel(x, y, c);
                                }
                                else
                                {
                                    int xMax = x + cell;
                                    if (xMax > x2)
                                    {
                                        xMax = x2;
                                    }
                                    int yMax = y + cell;
                                    if (yMax > y2)
                                    {
                                        yMax = y2;
                                    }
                                    for (int iy = y; iy < yMax; iy++)
                                    {
                                        for (int ix = x; ix < xMax; ix++)
                                        {
                                            image.SetPixel(ix, iy, c);
                                        }
                                    }
                                }
                            }

                            if ((++units & 63L) == 0L &&
                                ProgressData != null)
                            {
                                lock ( ProgressData )
                                {
                                    if (!ProgressData.Continue)
                                    {
                                        return;
                                    }
                                    if (lead)
                                    {
                                        ProgressData.Finished = counter / total;
                                        ProgressData.Sync(image);
                                    }
                                }
                            }
                        }
                    }
                }
            }while ((cell >>= 1) > 0);    // do one phase
        }
コード例 #20
0
 /// <summary>
 /// Renders the given rectangle into the given raster image.
 /// </summary>
 /// <param name="image">Pre-initialized raster image.</param>
 /// <param name="rnd">Shared random generator.</param>
 public virtual void RenderRectangle(Bitmap image, int x1, int y1, int x2, int y2, RandomJames rnd)
 {
     RenderRectangle(image, x1, y1, x2, y2, (n) => true, rnd);
 }
コード例 #21
0
 /// <summary>
 /// Apply the relevant value-modulation in the given Intersection instance.
 /// Internal integration support.
 /// </summary>
 /// <param name="inter">Data object to modify.</param>
 /// <param name="rank">Rank of this sample, 0 <= rank < total (for integration).</param>
 /// <param name="total">Total number of samples (for integration).</param>
 /// <param name="rnd">Global (per-thread) instance of the random generator.</param>
 /// <returns>Hash value (texture signature) for adaptive subsampling.</returns>
 public long Apply(Intersection inter, int rank, int total, RandomJames rnd)
 {
     return(Apply(inter));
 }
コード例 #22
0
        static void RecursiveMondrian(RandomJames rnd, Canvas c, Rect rect, int borderWidth, int depthOfRecursion, int maxDepth, int maxDots)
        {
            if (depthOfRecursion >= maxDepth)
            {
                goto FILL;
            }

            int  divisionLine;
            Rect DivisionLine;
            Rect Splitted1;
            Rect Splitted2;

            if (depthOfRecursion % 2 == 0)
            {
                // Vertical split
                if (rect.x1 - rect.x0 <= borderWidth * 4)
                {
                    goto FILL;
                }

                divisionLine = rnd.RandomInteger(rect.x0 + borderWidth * 2, rect.x1 - borderWidth * 2);
                DivisionLine = new Rect()
                {
                    x0 = divisionLine - (borderWidth / 2),
                    x1 = divisionLine + (borderWidth / 2),
                    y0 = rect.y0,
                    y1 = rect.y1
                };


                Splitted1 = new Rect()
                {
                    x0 = rect.x0,
                    x1 = DivisionLine.x0 - 1,
                    y0 = rect.y0,
                    y1 = rect.y1
                };
                Splitted2 = new Rect()
                {
                    x0 = DivisionLine.x1 + 1,
                    x1 = rect.x1,
                    y0 = rect.y0,
                    y1 = rect.y1
                };
            }
            else
            {
                // Horizontal split
                if (rect.y1 - rect.y0 <= borderWidth * 4)
                {
                    goto FILL;
                }
                divisionLine = rnd.RandomInteger(rect.y0 + borderWidth * 2, rect.y1 - borderWidth * 2);
                DivisionLine = new Rect()
                {
                    x0 = rect.x0,
                    x1 = rect.x1,
                    y0 = divisionLine - (borderWidth / 2),
                    y1 = divisionLine + (borderWidth / 2)
                };
                Splitted1 = new Rect()
                {
                    x0 = rect.x0,
                    x1 = rect.x1,
                    y0 = rect.y0,
                    y1 = DivisionLine.y0 - 1
                };
                Splitted2 = new Rect()
                {
                    x0 = rect.x0,
                    x1 = rect.x1,
                    y0 = DivisionLine.y1 + 1,
                    y1 = rect.y1
                };
            }
            // Filling Division line
            for (int i = 0; i < maxDots; i++)
            {
                int x = rnd.RandomInteger(DivisionLine.x0, DivisionLine.x1);
                int y = rnd.RandomInteger(DivisionLine.y0, DivisionLine.y1);
                c.SetColor(Color.Black);
                c.FillDisc((float)x, (float)y, (float)rnd.RandomInteger(1, borderWidth / 4));
            }

            RecursiveMondrian(rnd, c, Splitted1, borderWidth, depthOfRecursion + 1, maxDepth, maxDots);
            RecursiveMondrian(rnd, c, Splitted2, borderWidth, depthOfRecursion + 1, maxDepth, maxDots);
            return;

FILL:

            int area = (rect.x1 - rect.x0) * (rect.y1 - rect.y0);
            var maxCircleRadius = Math.Sqrt((double)area / (Math.PI * Math.Log(area) * 8));

            //fill that rectangle with random color
            List <Color> colors = new List <Color>()
            {
                Color.White, Color.White, Color.White, Color.Red, Color.Blue, Color.Yellow
            };
            Color randomColor = colors[rnd.RandomInteger(0, colors.Count - 1)];

            for (int i = 0; i < maxDots; i++)
            {
                int x = rnd.RandomInteger(rect.x0, rect.x1);
                int y = rnd.RandomInteger(rect.y0, rect.y1);
                c.SetColor(randomColor);
                c.FillDisc((float)x, (float)y, (float)rnd.RandomDouble((maxCircleRadius / 2) * 0.25, maxCircleRadius / 2));
            }
        }
コード例 #23
0
ファイル: Circles.cs プロジェクト: maoap1/grcis-1
        /// <summary>
        /// Draw the image into the initialized Canvas object.
        /// </summary>
        /// <param name="c">Canvas ready for your drawing.</param>
        /// <param name="param">Optional string parameter from the form.</param>
        public static void Draw(Canvas c, string param)
        {
            // {{ TODO: put your drawing code here

            int         wq   = c.Width / 4;
            int         hq   = c.Height / 4;
            int         minq = Math.Min(wq, hq);
            double      t;
            int         i, j;
            double      x, y, r;
            RandomJames rnd = new RandomJames();

            c.Clear(Color.Black);

            // Example of even simpler passing of a numeric value through string param.
            long seed;

            if (long.TryParse(param, NumberStyles.Number, CultureInfo.InvariantCulture, out seed))
            {
                rnd.Reset(seed);
            }

            // 1st quadrant - anti-aliased disks in a spiral.
            c.SetAntiAlias(true);
            const int MAX_DISK = 30;

            for (i = 0, t = 0.0; i < MAX_DISK; i++, t += 0.65)
            {
                r = 5.0 + i * (minq * 0.7 - 5.0) / MAX_DISK;
                c.SetColor(Color.FromArgb(i * 255 / MAX_DISK, 255, 255 - i * 255 / MAX_DISK));
                c.FillDisc((float)(wq + r * Math.Sin(t)), (float)(hq + r * Math.Cos(t)), (float)(r * 0.3));
            }

            // 2nd quadrant - anti-aliased random dots in a heart shape..
            const int MAX_RND_DOTS = 1000;
            double    xx, yy, tmp;

            for (i = 0; i < MAX_RND_DOTS; i++)
            {
                // This is called "Rejection Sampling"
                do
                {
                    x   = rnd.RandomDouble(-1.5, 1.5);
                    y   = rnd.RandomDouble(-1.0, 1.5);
                    xx  = x * x;
                    yy  = y * y;
                    tmp = xx + yy - 1.0;
                } while (tmp * tmp * tmp - xx * yy * y > 0.0);

                c.SetColor(Color.FromArgb(rnd.RandomInteger(200, 255),
                                          rnd.RandomInteger(120, 220),
                                          rnd.RandomInteger(120, 220)));
                c.FillDisc(3.1f * wq + 0.8f * minq * (float)x,
                           1.2f * hq - 0.8f * minq * (float)y,
                           rnd.RandomFloat(1.0f, minq * 0.03f));
            }

            // 4th quadrant - CGG logo.
            c.SetColor(COLORS[0]);
            for (i = 0; i < DISC_DATA.Length / 3; i++)
            {
                x = DISC_DATA[i, 0];
                y = DISC_DATA[i, 1];
                r = DISC_DATA[i, 2];
                if (i == FIRST_COLOR)
                {
                    c.SetColor(COLORS[1]);
                }

                c.FillDisc(3.0f * wq + (float)((x - 85.0) * 0.018 * minq),
                           3.0f * hq + (float)((y - 65.0) * 0.018 * minq),
                           (float)(r * 0.018 * minq));
            }

            // 3rd quadrant - disk grid.
            const int DISKS = 12;

            for (j = 0; j < DISKS; j++)
            {
                for (i = 0; i < DISKS; i++)
                {
                    c.SetColor(((i ^ j) & 1) == 0 ? Color.White : Color.Blue);
                    c.FillDisc(wq + (i - DISKS / 2) * (wq * 1.8f / DISKS),
                               3 * hq + (j - DISKS / 2) * (hq * 1.7f / DISKS),
                               (((i ^ j) & 15) + 1.0f) / DISKS * minq * 0.08f);
                }
            }

            // }}
        }
コード例 #24
0
ファイル: RayCastingRender.cs プロジェクト: srypous/PG1Grcis
        /// <summary>
        /// Computes one image sample. Internal integration support.
        /// </summary>
        /// <param name="x">Horizontal coordinate.</param>
        /// <param name="y">Vertical coordinate.</param>
        /// <param name="rank">Rank of this sample, 0 <= rank < total (for integration).</param>
        /// <param name="total">Total number of samples (for integration).</param>
        /// <param name="rnd">Global (per-thread) instance of the random generator.</param>
        /// <param name="color">Computed sample color.</param>
        /// <returns>Hash-value used for adaptive subsampling.</returns>
        public virtual long GetSample(double x, double y, int rank, int total, RandomJames rnd, double[] color)
        {
            Vector3d p0, p1;
            int      bands = color.Length;

            if (!scene.Camera.GetRay(x, y, rank, total, rnd, out p0, out p1))
            {
                Array.Clear(color, 0, bands);              // invalid ray -> black color
                return(1L);
            }

            LinkedList <Intersection> intersections = scene.Intersectable.Intersect(p0, p1);

            Intersection.countRays++;
            Intersection i = Intersection.FirstIntersection(intersections, ref p1);

            if (i == null)        // no intersection -> background color
            {
                Array.Copy(scene.BackgroundColor, color, bands);
                return(0L);
            }

            // there was at least one intersection
            i.Complete();

            // hash code for adaptive supersampling:
            long hash = i.Solid.GetHashCode();

            // apply all the textures fist..
            if (i.Textures != null)
            {
                foreach (ITexture tex in i.Textures)
                {
                    hash = hash * HASH_TEXTURE + tex.Apply(i, rank, total, rnd);
                }
            }

            // terminate if light sources are missing
            if (scene.Sources == null || scene.Sources.Count < 1)
            {
                Array.Copy(i.SurfaceColor, color, bands);
                return(hash);
            }

            // .. else apply the reflectance model for each source
            p1 = -p1;
            p1.Normalize();

            i.Material       = (IMaterial)i.Material.Clone();
            i.Material.Color = i.SurfaceColor;
            Array.Clear(color, 0, bands);

            foreach (ILightSource source in scene.Sources)
            {
                Vector3d dir;
                double[] intensity = source.GetIntensity(i, rank, total, rnd, out dir);
                if (intensity != null)
                {
                    double[] reflection = i.ReflectanceModel.ColorReflection(i, dir, p1, ReflectionComponent.ALL);
                    if (reflection != null)
                    {
                        for (int b = 0; b < bands; b++)
                        {
                            color[b] += intensity[b] * reflection[b];
                        }
                        hash = hash * HASH_LIGHT + source.GetHashCode();
                    }
                }
            }

            return(hash);
        }
コード例 #25
0
        /// <summary>
        /// Draw single animation frame.
        /// </summary>
        /// <param name="c">Canvas to draw to.</param>
        /// <param name="time">Current time in seconds.</param>
        /// <param name="start">Start time (t0)</param>
        /// <param name="end">End time (for animation length normalization).</param>
        /// <param name="param">Optional string parameter from the form.</param>
        public static void DrawFrame(Canvas c, double time, double start, double end, string param)
        {
            // {{ TODO: put your drawing code here

            int    objects = 1200;
            long   seed    = 144;
            double speed   = 1.0;

            // Parse parameters.
            Dictionary <string, string> p = Util.ParseKeyValueList(param);

            if (p.Count > 0)
            {
                // objects=<int>
                if (Util.TryParse(p, "objects", ref objects))
                {
                    if (objects < 10)
                    {
                        objects = 10;
                    }
                }

                // seed=<long>
                Util.TryParse(p, "seed", ref seed);

                // speed=<double>
                Util.TryParse(p, "speed", ref speed);
            }

            int    wq   = c.Width / 4;
            int    hq   = c.Height / 4;
            int    minq = Math.Min(wq, hq);
            double t;
            int    i, j;
            double x, y, r;

            c.Clear(Color.Black);
            c.SetAntiAlias(true);

            // 1st quadrant - anti-aliased disks in a spiral.
            const int MAX_DISK = 30;

            for (i = 0, t = 0.0; i < MAX_DISK; i++, t += 0.65)
            {
                r = 5.0 + i * (minq * 0.7 - 5.0) / MAX_DISK;
                c.SetColor(Color.FromArgb((i * 255) / MAX_DISK, 255, 255 - (i * 255) / MAX_DISK));
                c.FillDisc((float)(wq + r * Math.Sin(t)), (float)(hq + r * Math.Cos(t)), (float)(r * 0.3));
            }

            // 2nd quadrant - anti-aliased random dots in a heart shape..
            RandomJames rnd = new RandomJames(seed + (long)((time - start) * 5));
            double      xx, yy, tmp;

            for (i = 0; i < objects; i++)
            {
                // This is called "Rejection Sampling"
                do
                {
                    x   = rnd.RandomDouble(-1.5, 1.5);
                    y   = rnd.RandomDouble(-1.0, 1.5);
                    xx  = x * x;
                    yy  = y * y;
                    tmp = xx + yy - 1.0;
                } while (tmp * tmp * tmp - xx * yy * y > 0.0);

                c.SetColor(Color.FromArgb(rnd.RandomInteger(200, 255),
                                          rnd.RandomInteger(120, 220),
                                          rnd.RandomInteger(120, 220)));
                c.FillDisc(3.1f * wq + 0.8f * minq * (float)x,
                           1.2f * hq - 0.8f * minq * (float)y,
                           rnd.RandomFloat(1.0f, minq * 0.03f));
            }

            // 4th quadrant - CGG logo.
            c.SetColor(COLORS[0]);
            for (i = 0; i < DISC_DATA.Length / 3; i++)
            {
                x = DISC_DATA[i, 0] - 65.0;
                y = DISC_DATA[i, 1] - 65.0;
                r = DISC_DATA[i, 2];
                if (i == FIRST_COLOR)
                {
                    c.SetColor(COLORS[1]);
                }

                t = 4.0 * speed * Math.PI * (time - start) / (end - start);
                double sina = Math.Sin(t);
                double cosa = Math.Cos(t);
                double nx   = cosa * x + sina * y;
                double ny   = -sina * x + cosa * y;

                c.FillDisc(3.0f * wq + (float)((nx - 20.0) * 0.018 * minq),
                           3.0f * hq + (float)(ny * 0.018 * minq),
                           (float)(r * 0.018 * minq));
            }

            // 3rd quadrant - jaggy disks.
            const int DISKS = 12;

            for (j = 0; j < DISKS; j++)
            {
                for (i = 0; i < DISKS; i++)
                {
                    c.SetColor(((i ^ j) & 1) == 0 ? Color.White : Color.Blue);
                    c.FillDisc(wq + (i - DISKS / 2) * (wq * 1.8f / DISKS),
                               3 * hq + (j - DISKS / 2) * (hq * 1.7f / DISKS),
                               (((i ^ j) & 15) + 1.0f) / DISKS * minq * 0.08f);
                }
            }

            // }}
        }