예제 #1
0
        /// <summary>
        /// Normalizes the highest component to a value of max, the
        /// lowest component to a value of min, adjusts the other
        /// values accordingly. No effect on alpha.
        ///	Color (0.1, 0.8, 0.9) mapped as (0, 1) -> Color (0, 0.96, 1)
        ///	Color (0.1, 0.8, 0.9) mapped as (0.4, 0.6) -> (0.42, 0.56, 0.58)
        /// </summary>
        public static Color Normalize(Color color, float min = 0, float max = 1.0f)
        {
            float maxRGB = color.Max();
            float minRGB = color.Min();

            color.r = PMath.Map(color.r, minRGB, maxRGB, min, max);
            color.g = PMath.Map(color.g, minRGB, maxRGB, min, max);
            color.b = PMath.Map(color.b, minRGB, maxRGB, min, max);
            return(color);
        }
예제 #2
0
        public float Value(float a)
        {
            var xOff = PMath.Map(PMath.Cos(a), -1, 1, CenterX, Diameter + CenterX);
            var yOff = PMath.Map(PMath.Sin(a), -1, 1, CenterY, Diameter + CenterY);

            SetNoiseType(NoiseType.PerlinFractal);
            SetInterp(Interp.Quintic);
            SetFractalType(FractalType.RigidMulti);
            SetFractalLacunarity(3);

            SetFrequency(0.1f);

            var r = GetNoise(xOff, yOff);

            return(PMath.Map(r, -0.5f, 0.5f, Min, Max));
        }
예제 #3
0
        public void Map_ClampsOutOfBoundValues()
        {
            //  arrange
            float r = 1;  // scale 0,1 -> scale 4,3
            float g = 5;  // scale 10,5 -> scale 0,1
            float b = -7; // scale -10,0 -> scale 10,0

            //  act
            r = PMath.Map(r, 0, 0.5f, 3, 5);
            g = PMath.Map(g, 0, 1, 3, 9);
            b = PMath.Map(b, 0, 15, 2, 99);

            //	assert
            Assert.AreEqual(5, r);
            Assert.AreEqual(9, g);
            Assert.AreEqual(2, b);
        }
예제 #4
0
        public void Map_ConvertsNegativeRanges()
        {
            //  arrange
            float r = -1;    // scale 0,1 -> scale 4,3
            float g = -7.5f; // scale 10,5 -> scale 0,1
            float b = -7;    // scale -10,0 -> scale 10,0

            //  act
            r = PMath.Map(r, -10, 0, 0, 10);
            g = PMath.Map(g, -10, -5, 0, 10);
            b = PMath.Map(b, -7, 3, 1, 10);

            //	assert
            Assert.AreEqual(9, r);
            Assert.AreEqual(5, g);
            Assert.AreEqual(1, b);
        }
예제 #5
0
        public void Map_IgnoresIncorrectMinMaxOrder()
        {
            //  arrange
            float r = 0.65f; // scale 0,1 -> scale 4,3
            float g = 7.5f;  // scale 10,5 -> scale 0,1
            float b = 7;     // scale -10,0 -> scale 10,0

            //  act
            r = PMath.Map(r, 0, 1, 4, 3);
            g = PMath.Map(g, 10, 5, 0, 1);
            b = PMath.Map(b, 10, 0, 1, 0);

            //  assert
            Assert.AreEqual(3.65f, r);
            Assert.AreEqual(0.5f, g);
            Assert.AreEqual(0.7f, b);
        }
예제 #6
0
        public void Map_ReturnsShiftedValue()
        {
            //  arrange
            float r = 1;  // scale 0,1 -> scale 3,4
            float g = 5;  // scale 1,10 -> scale 11,20
            float b = -7; // scale -10,0 -> scale -5,5

            //  act
            r = PMath.Map(r, 0, 1, 3, 4);
            g = PMath.Map(g, 1, 10, 11, 20);
            b = PMath.Map(b, -10, 0, -5, 5);

            //  assert
            Assert.AreEqual(4, r);
            Assert.AreEqual(15, g);
            Assert.AreEqual(-2, b);
        }
예제 #7
0
        public void Map_ReturnsExpandedValue()
        {
            //  arrange
            float r = 0.9f; // scale 0,1 -> scale 0,10
            float g = 5;    // scale 1,10 -> scale 1,100
            float b = 2;    // scale -10,0 -> scale 1,10

            //  act
            r = PMath.Map(r, 0, 1, 0, 10);
            g = PMath.Map(g, 0, 10, 0, 100);
            b = PMath.Map(b, 0, 3, 0, 9);

            //  assert
            Assert.AreEqual(9, r, "r: " + TestHelper.ShowVariables(9, r));
            Assert.AreEqual(50, g, "g: " + TestHelper.ShowVariables(50, g));
            Assert.AreEqual(6, b, "b: " + TestHelper.ShowVariables(6, b));
        }
예제 #8
0
        public void Map_ReturnsCompressedValue()
        {
            //	prereq
            Approx_Works();

            //  arrange
            float r = 1;
            float g = 5;
            float b = 7;

            //  act
            r = PMath.Map(r, 0, 1, 0, 0.5f);    // scale 0,1 -> scale 0,0.5
            g = PMath.Map(g, 1, 10, 0.1f, 1);   // scale 1,10 -> scale 0.1,1
            b = PMath.Map(b, 1, 10, 0.5f, 5);   // scale -10,0 -> scale 1,5

            //  assert
            Assert.IsTrue(PMath.Approx(0.5f, r, 1), "r: " + TestHelper.ShowVariables(0.5f, r));
            Assert.IsTrue(PMath.Approx(0.5f, g, 1), "g: " + TestHelper.ShowVariables(0.5f, g));
            Assert.IsTrue(PMath.Approx(3.5f, b, 1), "b: " + TestHelper.ShowVariables(3.5f, b));
        }
예제 #9
0
        public PColor Convert(PColor i)
        {
            i.G -= (int)(i.R * 0.67f);
            i.G  = (int)PMath.Clamp(i.G, 0, 255);

            i.B -= (int)(i.R * 0.33f);
            i.B  = (int)PMath.Clamp(i.B, 0, 255);

            i.R = 0;

            RgbToHls(i.R, i.G, i.B, out var h, out var l, out var s);

            //h = PMath.Clamp((float)h, 70, 300);
            //h = PMath.Map((float)h, 0, 360, 20, 280);
            l = PMath.Clamp((float)l, 0f, 0.3f);
            //l = PMath.Map((float)l, 0f, 0.3f, 0f, 1f);

            HlsToRgb(h, l, s, out i.R, out i.G, out i.B);

            return(new PColor((int)PMath.Map(i.R, 0, 255, 0, i.G + i.B), i.G, i.B));
        }
예제 #10
0
        public void Setup()
        {
            Console.Write("Enter video framerate: ");
            var framerate = Console.ReadLine();

            Console.Write("Enter total frame count: ");
            var frames = int.Parse(Console.ReadLine());

            Console.Write("Enter output video file name (no extension): ");
            var name = Console.ReadLine().Trim();

            Console.Write("Enter resolution separated by a comma (480,480): ");
            var res = Console.ReadLine().Split(',').ToList().ConvertAll(resPart => int.Parse(resPart)).ToArray();

            Console.Write("Enter mandelbrot power range (x in f(z)=z^x + c) separated by a comma (1,10): ");
            var range = Console.ReadLine().Split(',').ToList().ConvertAll(rangePart => int.Parse(rangePart)).ToArray();
            var s     = Stopwatch.StartNew();

            Console.WriteLine("Generation is starting, please wait...");
            var done = 0;

            var items  = Enumerable.Range(0, frames).ToArray();
            var chunks = items
                         .Select((s2, i) => new { Value = s2, Index = i })
                         .GroupBy(x => x.Index / 10)
                         .Select(grp => grp.Select(x => x.Value).ToArray()).ToList();

            var threads = new List <Thread>();

            for (var t = 0; t < Environment.ProcessorCount - 1; t++)
            {
                var t2     = t;
                var thread = new Thread(() =>
                {
                    start:;
                    if (chunks.Count == 0)
                    {
                        goto exit;
                    }

                    var assignedChunk = chunks[0];
                    chunks.RemoveAt(0);
                    foreach (var a in assignedChunk)
                    {
                        var pow   = PMath.Map(a, 1, frames, range[0], range[1]);
                        var Image = new PSprite(res[0], res[1]);

                        var pixels = Image.Art.GetPixels();
                        for (var y = 0; y < Image.Height; y++)
                        {
                            for (var x = 0; x < Image.Width; x++)
                            {
                                var xTarget = 4f;
                                var yTarget = (xTarget / Image.Width) * Image.Height;

                                var x2 = (x / (Image.Width / (xTarget))) - (xTarget / 2);
                                var y2 = (y / (Image.Height / (yTarget))) - (yTarget / 2);

                                var c         = new Complex(x2, y2);
                                var z         = Complex.Zero;
                                var max       = -1f;
                                var maxWasHit = false;
                                for (var i = 0; i < maxDepth; i++)
                                {
                                    z = (Complex.Pow(z, pow)) + c;
                                    if ((z.Real * z.Real) + (z.Imaginary * z.Imaginary) > 16 && max == -1f)
                                    {
                                        max       = i;
                                        maxWasHit = true;
                                        break;
                                    }
                                }

                                var color = PColor.Black;

                                if (maxWasHit)
                                {
                                    var floorMax = (int)Math.Floor(max);
                                    var c1       = pallet[floorMax % pallet.Length];
                                    var c2       = pallet[(floorMax + 1) % pallet.Length];
                                    color        = PColor.Lerp(c1, c2, 0.5f);
                                }

                                var pos = ((y * Image.Width) + x) * 4;

                                pixels[pos]     = (byte)(color.R);
                                pixels[pos + 1] = (byte)(color.G);
                                pixels[pos + 2] = (byte)(color.B);
                                pixels[pos + 3] = 255;
                            }
                        }
                        Image.Art.SetPixels(pixels);
                        Image.Save(folder + a.ToString("000000") + ".png");
                        var percent           = (done / (float)frames);
                        var remaining         = (1f - percent) * 100;
                        var secondsPerPercent = s.Elapsed.TotalSeconds / (percent * 100f);
                        var minutesRemaining  = ((secondsPerPercent * remaining) / 60f);
                        var estimatedTime     = DateTime.Now.AddMinutes(done == 0 ? 0 : minutesRemaining);
                        Console.WriteLine("Progress: " + done + "/" + frames + "  " + (percent * 100f).ToString("0.00") +
                                          "%   Estimated completion time: " + estimatedTime);
                        done++;
                    }
                    goto start;
                    exit:;
                })
                {
                    Name     = "Mandelbrot: Core " + (t + 1),
                    Priority = ThreadPriority.AboveNormal,
                };
                threads.Add(thread);
                thread.Start();
            }
            ;

            var info = new ProcessStartInfo()
            {
                FileName         = "ffmpeg",
                Arguments        = string.Format(" -framerate {0} -i %06d.png -c:v libx264 -r {0} {1}.mp4", framerate, name),
                WorkingDirectory = folder,
            };

            var activeThreads = 1;

            do
            {
                Console.Title = "Active thread count: " + activeThreads;
                activeThreads = threads.Where(t => t.IsAlive).Count();
                Thread.Sleep(1000);
                Title(activeThreads);
            }while (activeThreads > 0);

            Console.Title = "Active thread count: 0";

            var p = Process.Start(info);

            p.WaitForExit();

            Console.WriteLine(@"Saved as " + folder + "out.mp4");
            Console.ReadLine();
            Close();
        }