Ejemplo n.º 1
0
        // this timer happens every millisecond. This is my workaround to
        // always get control back to the map-generating routine.
        private void timer1_Tick(object sender, EventArgs e)
        {
            if (!ImageComplete)
            {
                // record when you entered the loop
                DateTime TimeOfEntry = DateTime.Now;
                int      ElapsedTimeMs;
                // work on the map
                do
                {
                    // start the particle out at the current <x, y> coordinates
                    Particles[0].PositionX = ImageToParticleSpace(x);
                    Particles[0].PositionY = ImageToParticleSpace(y);
                    // set the moving particle's initial velocity.
                    Particles[0].VelocityX = RotationVelocityAmplitude * Math.Cos(RotationVelocityInitialPhase + RotationAngle * ImageNumber / Math.Max(1, Convert.ToDouble(RotationSamplePoints - 1)));
                    Particles[0].VelocityY = RotationVelocityAmplitude * Math.Sin(RotationVelocityInitialPhase + RotationAngle * ImageNumber / Math.Max(1, Convert.ToDouble(RotationSamplePoints - 1)));

                    // run the simulation until the moving particle hits one of the stationary particles
                    // have a timeout to prevent the programming from going in an endless loop
                    bool collision  = false;
                    int  iterations = 0;
                    while ((!collision) && (iterations < IterationsMax))
                    {
                        // check to see if the moving particle has collided with any of the others
                        foreach (Particle p in Particles.GetRange(1, Particles.Count - 1))
                        {
                            collision = Particle.CollisionCheck(Particles[0], p);
                            // if the particle collided, set the pixel to the appropriate color.
                            if (collision)
                            {
                                //Image.SetPixel(x, y, p.Color);
                                Image.SetPixel(x, y, ImageDefaultColor);
                                break;
                            }
                        }
                        // run the simulation for a little while
                        Particle.UpdateSingle(Particles[0], Particles.GetRange(1, Particles.Count - 1), IterationTimeStep);


                        iterations++;
                    }
                    // if our test particle did not collide with ANY target particles,
                    if (!collision)
                    {
                        // calculate the blended color of all particles
                        double ColorProA = 1;
                        double ColorSumR = 0;
                        double ColorSumG = 0;
                        double ColorSumB = 0;

                        foreach (Particle p in Particles.GetRange(1, Particles.Count - 1))
                        {
                            double dist_squared =
                                (Particles[0].PositionX - p.PositionX) * (Particles[0].PositionX - p.PositionX) +
                                (Particles[0].PositionY - p.PositionY) * (Particles[0].PositionY - p.PositionY);
                            double coloration_constant = 0.0001;
                            ColorProA *= (0xff - p.Color.A) / 0xff;
                            ColorSumR += Math.Pow(p.Color.R, 2) * (p.Color.A / 0xff) * coloration_constant / dist_squared;
                            ColorSumG += Math.Pow(p.Color.G, 2) * (p.Color.A / 0xff) * coloration_constant / dist_squared;
                            ColorSumB += Math.Pow(p.Color.B, 2) * (p.Color.A / 0xff) * coloration_constant / dist_squared;
                        }
                        ColorProA = (1 - ColorProA) * 0xff;
                        double ColorMax;
                        ColorMax = Math.Max(ColorSumR, ColorSumG);
                        ColorMax = Math.Max(ColorSumB, ColorMax);

                        // limit the maximum color intensity
                        if (ColorMax > 0xff)
                        {
                            ColorSumR *= 0xff / ColorMax;
                            ColorSumG *= 0xff / ColorMax;
                            ColorSumB *= 0xff / ColorMax;
                        }

                        // convert the color components to integers
                        int intR = Convert.ToInt32(ColorSumR);
                        int intG = Convert.ToInt32(ColorSumG);
                        int intB = Convert.ToInt32(ColorSumB);

                        Image.SetPixel(x, y, Color.FromArgb(0xff, intR, intG, intB));
                    }

                    // increment x and y
                    x++;
                    // if you have gotten to the right edge of the bitmap,
                    if (x >= ImageWidth)
                    {
                        x = 0;
                        y++;
                    }
                    // if you have completed the image, close it.
                    if (y >= ImageHeight)
                    {
                        // make a directory if it doesn't exist
                        Directory.CreateDirectory(OutputFileDirectory);
                        // save the image with date
                        Image.Save(OutputFileDirectory + OutputFileName + "_" + (DateTime.Now).ToString("yyyy-MM-ddTHH.mm.ss") + "_" + ImageNumber.ToString() + ".png", System.Drawing.Imaging.ImageFormat.Png);


                        y = 0;
                        //try
                        //{
                        //    SoundPlayer player = new SoundPlayer("gotmail.wav");
                        //    player.Play();
                        //}
                        //catch
                        //{
                        //    // oh well.
                        //}
                        ImageNumber++;
                        if (ImageNumber >= RotationSamplePoints)
                        {
                            ImageComplete  = true;
                            TimeRenderStop = DateTime.Now;
                        }
                    }
                    ElapsedTimeMs = (int)(DateTime.Now - TimeOfEntry).TotalMilliseconds;
                }
                // keep working on the map until you need to refresh the screen again
                while ((ElapsedTimeMs < this.ScreenRefreshPeriodMs) && !ImageComplete);

                Invalidate();
            }
        }