コード例 #1
0
        private void CreateFlowField()
        {
            t_flowField = new Engine.Calc.Vector[t_imageSource.Width, t_imageSource.Height];

            for (int y = 0; y < t_imageSource.Height; y++)
            {
                for (int x = 0; x < t_imageSource.Width; x++)
                {
                    // initialize vectors with basic to-the-right direction
                    t_flowField[x, y] = new Engine.Calc.Vector(1, 0);
                }
            }
        }
コード例 #2
0
ファイル: Extensions.cs プロジェクト: paint1master/Paintual
        /*public static Engine.Calc.Vector ExpressiveForce(this Engine.Effects.Particles.Attractor attractor,
         *  Engine.Effects.Particles.ForceParticle p)
         * {
         *  float G = 4f;
         *
         *  Engine.Calc.Vector relDistance = attractor.Distance(p);
         *
         *  float distance = relDistance.Norm; // Norm seems the magnitude in Processing
         *
         *  float force = G / distance;
         *
         *  force = Engine.Calc.Math.Sigmoid(force);
         *
         *  relDistance.Normalize();
         *  Engine.Calc.Vector.Multiply(relDistance, force);
         *
         *  return relDistance;
         * }*/

        /// <summary>
        ///
        /// </summary>
        /// <param name="attractor"></param>
        /// <param name="p"></param>
        /// <param name="G">The "Gravitational constant" of the force (suggested value 1.3)</param>
        /// <param name="expansion">Allows the force to be stronger or weaker on longer distances while remaining weak at very short distances.
        /// suggested value 2.8</param>
        /// <param name="direction">the direction of the force. positive makes the force attraction, negative makes the force repulsion. suggested value 0.5 or -0.5</param>
        /// <returns></returns>
        public static Engine.Calc.Vector ModularForce(this Engine.Effects.Particles.Attractor attractor,
                                                      Engine.Effects.Particles.ForceParticle p)
        {
            Engine.Calc.Vector relDistance = attractor.Distance(p);

            double distance = System.Math.Sqrt(relDistance.X * relDistance.X + relDistance.Y * relDistance.Y);

            double force = (attractor.Intensity * attractor.Force * distance) - 10d / System.Math.Pow(attractor.Expression, -1 * (distance / attractor.Force));

            relDistance.Normalize();

            relDistance *= force;

            return(relDistance);
        }
コード例 #3
0
        public void CalculateAveragePressure(Engine.Effects.Particles.FlowField flowField, int startX, int startY)
        {
            t_pressure = new Calc.Vector(0, 0);

            for (int y = 0; y < t_height; y++)
            {
                for (int x = 0; x < t_width; x++)
                {
                    Engine.Calc.Vector v = flowField.GetVector(x + startX, y + startY);
                    t_pressure += v;
                }
            }

            //t_pressure.Normalize(Calc.CalculationStyles.Accord);
        }
コード例 #4
0
ファイル: ParticlePen.cs プロジェクト: paint1master/Paintual
        /// <summary>
        ///
        /// </summary>
        /// <param name="x"></param>
        private int ParticleFlow()
        {
            Engine.Color.ColorVariance cv = new Color.ColorVariance(t_particles[0].Pixel);
            cv.SetFrequencies(500);
            cv.SetRanges(30);

            double life = 0;

            do
            {
                cv.Step();

                life = 0;

                for (int y = 0; y < t_particles.Length; y++)
                {
                    t_particles[y].Pixel = cv.ColorVariation;
                    t_particles[y].Draw(t_imageSource);

                    if (t_particles[y].Life < 0)
                    {
                        continue;
                    }

                    Engine.Calc.Vector pos = t_particles[y].Position;

                    if (pos.X < 0 || pos.X >= t_imageSource.Width)
                    {
                        t_particles[y].Die();
                        life += 0;
                        continue;
                    }

                    if (pos.Y < 0 || pos.Y >= t_imageSource.Height)
                    {
                        t_particles[y].Die();
                        life += 0;
                        continue;
                    }

                    t_particles[y].Move(t_flowField[(int)t_particles[y].Position.X, (int)t_particles[y].Position.Y]);
                    life += t_particles[y].Life;
                }
            } while (life > t_particleLife);

            return(0);
        }
コード例 #5
0
ファイル: Radial.cs プロジェクト: paint1master/Paintual
        /// <summary>
        ///
        /// </summary>
        private int ParticleFlow(int start, int end, Engine.Threading.ParamList lst)
        {
            Engine.Color.ColorVariance cv = new Color.ColorVariance(t_particles[0].Pixel);
            cv.SetFrequencies(500);
            cv.SetRanges(30);

            double life = 0;

            do
            {
                life = 0;

                for (int i = start; i < end; i++)
                {
                    t_particles[i].Pixel = cv.ColorVariation;
                    t_particles[i].Draw(t_imageProcessed);

                    if (t_particles[i].Life < 0)
                    {
                        continue;
                    }

                    Engine.Calc.Vector pos = t_particles[i].Position;

                    if (pos.X < 0 || pos.X >= t_imageProcessed.Width)
                    {
                        t_particles[i].Die();
                        continue;
                    }

                    if (pos.Y < 0 || pos.Y >= t_imageProcessed.Height)
                    {
                        t_particles[i].Die();
                        continue;
                    }

                    t_particles[i].Move(t_flowField[(int)t_particles[i].Position.X, (int)t_particles[i].Position.Y]);
                    life += t_particles[i].Life;
                }
            } while (life > t_particleLife);

            return(0);
        }
コード例 #6
0
ファイル: FluidPlane.cs プロジェクト: paint1master/Paintual
        public void VelocityFriction(double a, double b, double c)
        {
            // The force of pressure affects velocity

            for (int iterate = 0; iterate < 1; iterate++)
            {
                // NOTE: We include the border cells in global friction
                for (int x = 0; x < t_width; x++)
                {
                    for (int y = 0; y < t_height; y++)
                    {
                        int cell = CellOffset(x, y, t_width);

                        Engine.Calc.Vector v = new Engine.Calc.Vector(mp_xv0[cell], mp_yv0[cell]);

                        double len2 = v.MagnitudeSquared();
                        double len  = System.Math.Sqrt(len2);

                        if (len < 0.0f)
                        {
                            len = -len;
                        }

                        len -= m_dt * (a * len2 + b * len + c);

                        if (len < 0.0d)
                        {
                            len = 0.0d;
                        }

                        if (len < 0.0f)
                        {
                            len = 0.0f;
                        }

                        v.Normalize();
                        v.SetMagnitude(len);
                        mp_xv0[cell] = v.X;
                        mp_yv0[cell] = v.Y;
                    }
                }
            }
        }
コード例 #7
0
ファイル: GrainyPen.cs プロジェクト: paint1master/Paintual
        internal override void Draw(MousePoint p)
        {
            if (!t_skipper.Skip())
            {
                return;
            }

            if (t_imageSource.IsOutOfBounds(p.X, p.Y))
            {
                return;
            }

            Engine.Color.Cell col;
            t_colorVariance.Step();

            if (t_useColorFromImage)
            {
                col = t_imageSource.GetPixel(p.X, p.Y, PixelRetrievalOptions.ReturnEdgePixel);
                t_colorVariance.SetColor(col);
                col       = t_colorVariance.ColorVariation;
                col.Alpha = t_alpha;
            }
            else
            {
                col       = t_colorVariance.ColorVariation;
                col.Alpha = t_alpha;
            }

            // particles must follow the pen between each call to draw
            int[] delta          = MousePoint.Delta(t_previousPoint, p);
            Engine.Calc.Vector d = new Engine.Calc.Vector(delta[0], delta[1]);

            foreach (Engine.Effects.Particles.Obsolete.PixelParticle_O px in t_particles)
            {
                px.Move(d);

                px.Draw(t_imageSource, col);
            }

            t_previousPoint = p;
        }
コード例 #8
0
ファイル: ParticlePen.cs プロジェクト: paint1master/Paintual
        private int Threaded_CreateFlowField(int start, int end, Engine.Threading.ParamList paramList)
        {
            for (int y = start; y < end; y++)
            {
                for (int x = 0; x < t_imageSource.Width; x++)
                {
                    // initialize vectors with basic to-the-right direction
                    t_flowField[x, y] = new Engine.Calc.Vector(1, 0);

                    Engine.Color.Cell c     = t_imagePerlin.GetPixel(x, y, Surface.PixelRetrievalOptions.ReturnEdgePixel);
                    double            lum   = (double)Engine.Calc.Color.Luminance(c);
                    double            angle = (lum * 360 / 255);

                    double rad = angle * Engine.Calc.Math.DEG_TO_RAD;

                    t_flowField[x, y].X = (float)System.Math.Cos(rad);
                    t_flowField[x, y].Y = (float)System.Math.Sin(rad);
                }
            }

            return(0);
        }
コード例 #9
0
        public override void Move(Engine.Calc.Vector direction)
        {
            if (t_life <= 0)
            {
                // particle is dead
                return;
            }

            double previousX = t_position.X;
            double previousY = t_position.Y;

            Engine.Calc.Vector tempDir = direction + t_direction;

            t_position += tempDir;

            double deltaX = System.Math.Abs(t_position.X - previousX);
            double deltaY = System.Math.Abs(t_position.Y - previousY);

            double distance = System.Math.Sqrt(deltaX * deltaX + deltaY * deltaY);

            t_life -= distance;
        }
コード例 #10
0
        /// <summary>
        /// Draws a filled circle at the specified coordinates using the specified color.
        /// </summary>
        /// <param name="canvas">the target image onto which to draw a circle</param>
        /// <param name="position">where on the target image the center of the cicle is to be located.</param>
        /// <param name="size">the diameter of the circle to draw</param>
        /// <param name="color">the color of the circle line</param>
        /// <remarks>Implements the Bresenham's circle argorithm, most of the code found at : https://rosettacode.org/wiki/Bitmap/Midpoint_circle_algorithm#C.23 </remarks>
        public static void DrawCircle(Engine.Surface.Canvas canvas, Engine.Calc.Vector position, int size, Engine.Color.Cell color)
        {
            int centerX = (int)System.Math.Round(position.X);
            int centerY = (int)System.Math.Round(position.Y);

            int radius = (int)System.Math.Round((double)size / 2);

            int d = (5 - radius * 4) / 4;
            int x = 0;
            int y = radius;

            do
            {
                // ensure index is in range before setting (depends on your image implementation)
                // in this case we check if the pixel location is within the bounds of the image before setting the pixel

                canvas.SetPixel(color, centerX + x, centerY + y, Surface.PixelSetOptions.Ignore);
                canvas.SetPixel(color, centerX + x, centerY - y, Surface.PixelSetOptions.Ignore);
                canvas.SetPixel(color, centerX - x, centerY + y, Surface.PixelSetOptions.Ignore);
                canvas.SetPixel(color, centerX - x, centerY - y, Surface.PixelSetOptions.Ignore);
                canvas.SetPixel(color, centerX + y, centerY + x, Surface.PixelSetOptions.Ignore);
                canvas.SetPixel(color, centerX + y, centerY - x, Surface.PixelSetOptions.Ignore);
                canvas.SetPixel(color, centerX - y, centerY + x, Surface.PixelSetOptions.Ignore);
                canvas.SetPixel(color, centerX - y, centerY - x, Surface.PixelSetOptions.Ignore);

                if (d < 0)
                {
                    d += 2 * x + 1;
                }
                else
                {
                    d += 2 * (x - y) + 1;
                    y--;
                }
                x++;
            } while (x <= y);
        }
コード例 #11
0
ファイル: PressureGrid.cs プロジェクト: paint1master/Paintual
        private int Threaded_GetParticles(int start, int end, Threading.ParamList paramlist)
        {
            Engine.Effects.Code.Particles.AutonomousParticle[] particles = (Engine.Effects.Code.Particles.AutonomousParticle[])paramlist.Get("particles").Value;

            for (int x = start; x < end; x++)
            {
                for (int y = 0; y < t_cells.GetLength(1); y++)
                {
                    int offset = Engine.Surface.Ops.GetGridOffset(x, y, t_cells.GetLength(0), t_cells.GetLength(1));

                    particles[offset] = new Effects.Code.Particles.AutonomousParticle(new Engine.Calc.Vector((x * t_gridCellWidth) + (t_gridCellWidth / 2),
                                                                                                             (y * t_gridCellHeight) + (t_gridCellHeight / 2)));

                    Engine.Calc.Vector vel = t_cells[x, y].Pressure;
                    vel.Normalize();
                    vel.SetMagnitude(2);
                    particles[offset].Velocity = vel;

                    //t_cells[x, y].CalculateAveragePressure(t_flowField, x * t_gridCellWidth, y * t_gridCellHeight);
                }
            }

            return(0);
        }
コード例 #12
0
 public void Update()
 {
     t_position += t_velocity;
 }
コード例 #13
0
 /// <summary>
 /// Updates the position of the particule according to its own position, velocity, and the force (and location) of the
 /// specified attractor.
 /// </summary>
 /// <param name="attractor"></param>
 public void Update(Engine.Effects.Particles.Attractor attractor)
 {
     //t_acceleration = attractor.ExpressiveForce(this);
     t_acceleration = attractor.ModularForce(this);
     Update();
 }
コード例 #14
0
 public override void Move(Engine.Calc.Vector direction)
 {
     throw new InvalidOperationException("In ForceParticle.Move(), use any overload of the Update() method instead.");
 }
コード例 #15
0
ファイル: Extensions.cs プロジェクト: paint1master/Paintual
        public static Engine.Calc.Vector Distance(this Engine.Effects.Particles.Attractor attractor, Engine.Effects.Particles.BaseParticle p)
        {
            Engine.Calc.Vector distance = attractor.Position - p.Position;

            return(distance);
        }
コード例 #16
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="position"></param>
 /// <param name="G">The base value of the force of "gravity". G must be greater than 0. If not, value defaults to 0.1d.
 /// Suggested value 1.2d.</param>
 /// <param name="expression">A parameter that influences the intensity curve of the calculated gravity force. Cannot be less
 /// than 0. Sugested value 1.3d. The higher the value, the less intense the gravity curve is.</param>
 /// <param name="intensity">A positive value means attraction, a negative value means repulsion.</param>
 public Attractor(Engine.Calc.Vector position, double G, double expression, double intensity) : base(position)
 {
     Force      = G > 0 ? G : 0.1d;
     Expression = expression > 0 ? expression : 0.1d;
     Intensity  = intensity;
 }
コード例 #17
0
 public Attractor(Engine.Calc.Vector position, double G) : base(position)
 {
     Force = G;
 }
コード例 #18
0
 public Attractor(Engine.Calc.Vector position) : base(position)
 {
 }
コード例 #19
0
 public ForceParticle(Engine.Calc.Vector position) : base(position)
 {
     t_previousPoint = new Point((int)position.X, (int)position.Y);
 }
コード例 #20
0
 public ForceParticle(int x, int y, float velX, float velY)
 {
     t_previousPoint = new Point(x, y);
     t_position      = new Engine.Calc.Vector(x, y);
     t_velocity      = new Engine.Calc.Vector(velX, velY);
 }
コード例 #21
0
 public ForceParticle(Engine.Calc.Vector position, Engine.Calc.Vector velocity) : base(position)
 {
     t_previousPoint = new Point((int)position.X, (int)position.Y);
     t_velocity      = velocity;
 }
コード例 #22
0
 public PixelParticle_O(Engine.Color.Cell c, int x, int y) : this(c)
 {
     t_position = new Engine.Calc.Vector((float)x, (float)y);
 }
コード例 #23
0
 public PixelParticle_O(Engine.Color.Cell c, float x, float y) : this(c)
 {
     t_position = new Engine.Calc.Vector(x, y);
 }
コード例 #24
0
 public BaseParticle(Engine.Calc.Vector position)
 {
     t_position = new Engine.Calc.Vector(position.X, position.Y);
 }
コード例 #25
0
 public AutonomousParticle(Engine.Calc.Vector position) : base(position)
 {
     //t_position.Normalize(Calc.CalculationStyles.Accord);
     t_direction = new Calc.Vector(0, 0);
 }
コード例 #26
0
 public AutonomousParticle()
 {
     t_direction = new Calc.Vector(0, 0);
 }
コード例 #27
0
 public virtual void Move(Engine.Calc.Vector direction)
 {
     t_position += direction;
 }
コード例 #28
0
        private void SetField()
        {
            t_field = new List <List <Engine.Calc.Vector> >();

            for (int i = 0; i < t_imageSource.Width; i++)
            {
                t_field.Add(new List <Engine.Calc.Vector>());
            }

            double[] lums = new double[t_imageSource.Height * t_imageSource.Width];

            int[] reds   = new int[t_imageSource.Height * t_imageSource.Width];
            int[] greens = new int[t_imageSource.Height * t_imageSource.Width];
            int[] blues  = new int[t_imageSource.Height * t_imageSource.Width];

            int offset = 0;

            for (int y = 0; y < t_imageSource.Height; y++)
            {
                for (int x = 0; x < t_imageSource.Width; x++)
                {
                    Engine.Color.Cell c = t_imageSource.GetPixel(x, y, Surface.PixelRetrievalOptions.ReturnNeutralGray);
                    c.InArray(ref blues, ref greens, ref reds, offset);
                    offset++;
                }
            }

            Engine.EngineCppLibrary.Luminance s_luminance = (Engine.EngineCppLibrary.Luminance)Marshal.GetDelegateForFunctionPointer(
                Engine.EngineCppLibrary.Pointer_luminance,
                typeof(Engine.EngineCppLibrary.Luminance));

            s_luminance(t_imageSource.Height * t_imageSource.Width, blues, greens, reds, lums);

            offset = 0;

            for (int y = 0; y < t_imageSource.Height; y++)
            {
                for (int x = 0; x < t_imageSource.Width; x++)
                {
                    double lum = lums[offset];

                    /*
                     * surrounding cell config
                     *     0  1  2
                     *
                     *     7  x  3
                     *
                     *     6  5  4
                     *
                     */

                    double[] localLums = new double[8];

                    localLums[0] = GetLum(lums, x - 1, y - 1);
                    localLums[1] = GetLum(lums, x, y - 1);
                    localLums[2] = GetLum(lums, x + 1, y - 1);
                    localLums[3] = GetLum(lums, x + 1, y);
                    localLums[4] = GetLum(lums, x + 1, y + 1);
                    localLums[5] = GetLum(lums, x, y + 1);
                    localLums[6] = GetLum(lums, x - 1, y + 1);
                    localLums[7] = GetLum(lums, x - 1, y);

                    if (t_invertLuminance)
                    {
                        lum = 255 - lum;

                        localLums[0] = 255 - localLums[0];
                        localLums[1] = 255 - localLums[1];
                        localLums[2] = 255 - localLums[2];
                        localLums[3] = 255 - localLums[3];
                        localLums[4] = 255 - localLums[4];
                        localLums[5] = 255 - localLums[5];
                        localLums[6] = 255 - localLums[6];
                        localLums[7] = 255 - localLums[7];
                    }

                    double[] lumDiffs = new double[8];

                    for (int i = 0; i < lumDiffs.Length; i++)
                    {
                        lumDiffs[i] = lum - localLums[i];
                    }

                    Engine.Calc.Vector[] vs = new Calc.Vector[lumDiffs.Length];

                    vs[0] = new Engine.Calc.Vector(-1, -1);
                    vs[1] = new Engine.Calc.Vector(0, -1);
                    vs[2] = new Engine.Calc.Vector(1, -1);
                    vs[3] = new Engine.Calc.Vector(1, 0);
                    vs[4] = new Engine.Calc.Vector(1, 1);
                    vs[5] = new Engine.Calc.Vector(0, 1);
                    vs[6] = new Engine.Calc.Vector(-1, 1);
                    vs[7] = new Engine.Calc.Vector(-1, 0);

                    Engine.Calc.Vector v_this = new Engine.Calc.Vector(0, 0);

                    for (int i = 0; i < vs.Length; i++)
                    {
                        vs[i].SetMagnitude(lumDiffs[i]);
                        v_this += vs[i];
                    }

                    //v_this.Normalize(Calc.CalculationStyles.Accord);

                    t_field[x].Add(v_this);

                    offset++;
                }
            }
        }