private static void DrawFieldSprtDoIt(byte[] pixels, double[] ink, bool[] blocked, int size, byte[] colorZFront, byte[] colorZBack, AxisFor pixelX, AxisFor pixelY, AxisFor pixelZ)
        {
            List<Mapping_2D_1D> flattened = new List<Mapping_2D_1D>();

            // Setup the pixel array
            //for (int y2D = pixelY.Start; pixelY.IsPos ? y2D <= pixelY.Stop : y2D >= pixelY.Stop; y2D += pixelY.Increment)
            foreach (int y2D in pixelY.Iterate())
            {
                int offsetY = pixelY.GetValueForOffset(y2D) * size;

                //for (int x2D = pixelX.Start; pixelX.IsPos ? x2D <= pixelX.Stop : x2D >= pixelX.Stop; x2D += pixelX.Increment)
                foreach (int x2D in pixelX.Iterate())
                {
                    int offset = offsetY + pixelX.GetValueForOffset(x2D);

                    flattened.Add(new Mapping_2D_1D(x2D, y2D, offset));
                }
            }

            // Each pixel of the output bitmap can be added up independently, so employ some threading
            flattened.AsParallel().ForAll(o =>
                {
                    //TODO: Color is 6.5 times slower than byte array
                    List<byte[]> colorColumn = new List<byte[]>();

                    for (int z2D = pixelZ.Start; pixelZ.IsPos ? z2D <= pixelZ.Stop : z2D >= pixelZ.Stop; z2D += pixelZ.Increment)
                    {
                        int x = -1, y = -1, z = -1;
                        pixelX.Set3DIndex(ref x, ref y, ref z, o.X);
                        pixelY.Set3DIndex(ref x, ref y, ref z, o.Y);
                        pixelZ.Set3DIndex(ref x, ref y, ref z, z2D);

                        int index = FluidField3D.Get1DIndex(x, y, z, size);
                        if (blocked[index])
                        {
                            // Blocked cells are all white, so save the overlay method a bit of work, and throw out everything behind this
                            colorColumn.Clear();
                            colorColumn.Add(new byte[] { 255, 255, 255, 255 });
                            continue;
                        }

                        double inkCell = ink[index];

                        if (Math1D.IsNearZero(inkCell))
                        {
                            continue;
                        }

                        byte[] depthColor = UtilityWPF.AlphaBlend(colorZBack, colorZFront, UtilityCore.GetScaledValue_Capped(0, 1, 0, size - 1, z));

                        int alpha = Convert.ToInt32(Math.Round(inkCell * 255));
                        if (alpha < 0)
                        {
                            alpha = 0;
                        }
                        else if (alpha > 255)
                        {
                            alpha = 255;
                        }

                        colorColumn.Add(new byte[] { Convert.ToByte(alpha), depthColor[1], depthColor[2], depthColor[3] });
                    }

                    byte[] color = colorColumn.Count > 0 ? UtilityWPF.OverlayColors(colorColumn) : new byte[] { 0, 0, 0, 0 };

                    pixels[o.Offset1D * 4 + 0] = color[3];   // Blue
                    pixels[o.Offset1D * 4 + 1] = color[2];     // Green
                    pixels[o.Offset1D * 4 + 2] = color[1];     // Red
                    pixels[o.Offset1D * 4 + 3] = color[0];   // Alpha
                });
        }
        private static Task<Tuple<int, int, int>[]> GetDelaunayResults_FixedSet_Power(int maxPoints, int numRunsPerPointCount, double brainIORatio, Func<Point3D> getRandomPoint)
        {
            const int LINEARTO = 15;
            const int NONLINEARSAMPLES = 15;

            List<int> samplePoints = new List<int>();

            // The first set should increment by 1
            samplePoints.AddRange(Enumerable.Range(1, Math.Min(LINEARTO, maxPoints)));

            // The second set should increment faster and faster
            if (maxPoints > LINEARTO)
            {
                double step = 1d / NONLINEARSAMPLES;
                double current = step;

                while (current <= 1d)
                {
                    double percent = Math.Pow(current, 2);
                    current += step;

                    int samplePoint = LINEARTO + (percent * (maxPoints - LINEARTO)).ToInt_Round();

                    if (!samplePoints.Contains(samplePoint))
                    {
                        samplePoints.Add(samplePoint);
                    }
                }
            }

            return Task.Run(() => samplePoints.
                AsParallel().
                SelectMany(o => GetDelaunayResults_Run(o, numRunsPerPointCount, brainIORatio, getRandomPoint)).
                ToArray());
        }