Example #1
0
        private void RenderFunction()
        {
            int w  = this.imageBuffer.Width - 2;
            int h  = this.imageBuffer.Height - 2;
            int cx = this.imageBuffer.Width / 2;
            int cy = this.imageBuffer.Height / 2;

            double[, ,] points = new double[h, w, 4];

            for (int y = 1; y <= h; y++)
            {
                double py = this.originY + (double)(y - cy) / this.unitPixels;
                for (int x = 1; x <= w; x++)
                {
                    double px = this.originX + (double)(cx - x) / this.unitPixels;
                    points[y - 1, x - 1, 0] = px;
                    points[y - 1, x - 1, 1] = py;
                    points[y - 1, x - 1, 2] = px;
                    points[y - 1, x - 1, 3] = py;
                }
            }

            int done  = 0;
            int max   = w + h;
            int total = Environment.ProcessorCount * 8;

            Parallel.For(0, total, (i) =>
            {
                int dh = (h + total - h % total) / total;
                int dw = (w + total - w % total) / total;

                int starty = 1 + i * dh;
                int endy   = Math.Min(h + 1, starty + dh);
                int startx = 1 + i * dw;
                int endx   = Math.Min(w + 1, startx + dw);
                int loops  = (endy - starty + 1) + (endx - startx + 1);

                for (int y = starty; y < endy; y++)
                {
                    double py                 = this.originY + (double)(y - cy) / this.unitPixels;
                    RawExpression efx         = this.function.Apply("y", py).Simplify();
                    RawExpression edfx        = efx.Different("x").Simplify();
                    Func <double, double> fx  = efx.Compile("x");
                    Func <double, double> dfx = edfx.Compile("x");

                    for (int x = 1; x <= w; x++)
                    {
                        points[y - 1, x - 1, 0] = fx.Solve(dfx, points[y - 1, x - 1, 0]);
                    }

                    int current = Interlocked.Increment(ref done);
                    if (current % 10 == 0)
                    {
                        UpdateMessage(current.ToString() + "/" + max.ToString());
                    }
                }

                for (int x = startx; x < endx; x++)
                {
                    double px                 = this.originX + (double)(cx - x) / this.unitPixels;
                    RawExpression efy         = this.function.Apply("x", px).Simplify();
                    RawExpression edfy        = efy.Different("y").Simplify();
                    Func <double, double> fy  = efy.Compile("y");
                    Func <double, double> dfy = edfy.Compile("y");

                    for (int y = 1; y <= h; y++)
                    {
                        points[y - 1, x - 1, 3] = fy.Solve(dfy, points[y - 1, x - 1, 3]);
                    }

                    int current = Interlocked.Increment(ref done);
                    if (current % 10 == 0)
                    {
                        UpdateMessage(current.ToString() + "/" + max.ToString());
                    }
                }
            });

            UpdateMessage("Rendering...");

            BitmapData data = this.imageBuffer.LockBits(new Rectangle(0, 0, this.imageBuffer.Width, this.imageBuffer.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

            for (int y = 1; y <= h; y++)
            {
                for (int x = 1; x <= w; x++)
                {
                    double x1 = points[y - 1, x - 1, 0];
                    double y1 = points[y - 1, x - 1, 1];
                    double x2 = points[y - 1, x - 1, 2];
                    double y2 = points[y - 1, x - 1, 3];

                    if (!double.IsInfinity(x1) && !double.IsNaN(x1))
                    {
                        Fill(data, x1, y1, cx, cy, w, h);
                    }
                    if (!double.IsInfinity(y2) && !double.IsNaN(y2))
                    {
                        Fill(data, x2, y2, cx, cy, w, h);
                    }
                }
            }
            this.imageBuffer.UnlockBits(data);

            UpdateMessage("(Ready)");
        }