Esempio n. 1
0
        void SimulateStep()
        {
            FluidMath.VelStep(N, M, u, v, uS, vS, viscosity, 1.0f);
            FluidMath.DensStep(N, M, d, dS, u, v, diffusion, 1.0f);

            // Clear source arrays.
            for (int i = 0; i < size; i++)
            {
                dS[i] = 0; uS[i] = 0; vS[i] = 0;
            }
        }
Esempio n. 2
0
        void AddCenteredRect(float coverage, float densityFull)
        {
            int xH      = GetXH(coverage);
            int yH      = GetYH(coverage);
            int offsetX = GetOffsetX(xH);
            int offsetY = GetOffsetY(yH);

            float fill = ((N * M) / (xH * yH)) * densityFull;

            for (int i = offsetX; i <= offsetX + xH - 1; i++)
            {
                for (int j = offsetY; j <= offsetY + yH - 1; j++)
                {
                    dS[FluidMath.IX(N, i, j)] = fill;
                }
            }
        }
        void Draw(SKSurface surface, int width, int height)
        {
            Stopwatch sw = new Stopwatch();

            if (canRender)
            {
                var canvas = surface.Canvas;
                canvas.Clear(SKColors.White);

                sw.Restart();

                using (var paint = new SKPaint())
                {
                    paint.Style = SKPaintStyle.Fill;

                    SKRect rect = new SKRect();
                    Color  densityColor;
                    float  xCord = 0;
                    float  yCord = 0;
                    float  xInc, yInc;
                    float  colorScale = 1.0f;
                    float  density;

                    xInc = width / (float)N;
                    yInc = height / (float)M;

                    // Loop through, match simulation format of first cell (0,0) at bottom left.
                    for (int i = 1; i <= N; i++)
                    {
                        yCord = height;
                        for (int j = 1; j <= M; j++)
                        {
                            // Set bounds of rectangle.
                            rect.Left   = xCord;
                            rect.Top    = yCord - yInc;
                            rect.Right  = xCord + xInc;
                            rect.Bottom = yCord;

                            // Read from corresponding cell to set color based on density. Note bottom left in simulation is index 1,1.
                            density    = d[FluidMath.IX(N, i, j)];
                            colorScale = colorScaleFactor * Math.Max(1.0f, Math.Min(1.0f, (1 / density)));
                            if (density > 0.05)
                            {
                                densityColor = new Color(baseColor.R * colorScale, baseColor.G * colorScale, baseColor.B * colorScale, baseColor.A * Math.Pow(density, 1 - Math.Min(1.0, density)));
                                paint.Color  = densityColor.ToSKColor();
                                canvas.DrawRect(rect, paint);
                            }

                            // Decrement y for next rectangle.
                            yCord -= yInc;
                        }
                        // Increment x for next rectangle.
                        xCord += xInc;
                    }
                    canvas.Flush();
                }

                var drawTime = sw.ElapsedMilliseconds;
                if (drawTime > 10)
                {
                    #if DEBUG
                    Debug.WriteLine("Slow render time: {0} milliseconds.", drawTime);
                    #endif
                }
            }
        }
Esempio n. 4
0
        void Spin()
        {
            float cellVelocity = 0, addU = 0, addV = 0;
            int   xH = GetXH(SPIN_FORCE_COVERAGE); int yH = GetYH(SPIN_FORCE_COVERAGE);
            int   average = (xH + yH) / 2;

            xH = average; yH = average;

            int offsetX = GetOffsetX(xH);
            int offsetY = GetOffsetY(yH);

            float gravity = this.gravity * 1.2f; // Extra force for spin.

            // Normalize and reverse X & Y direction.
            MotionVector normalizedMotion = new MotionVector();

            normalizedMotion.X = (double)N / (N + M) * (N + M / 30); normalizedMotion.Y = (double)M / (N + M) * (N + M / 30);
            switch (spin)
            {
            case 0:
                normalizedMotion.X *= 1; normalizedMotion.Y *= 1;
                break;

            case 1:
                normalizedMotion.X *= 1; normalizedMotion.Y *= -1;
                break;

            case 2:
                normalizedMotion.X *= -1; normalizedMotion.Y *= -1;
                break;

            case 3:
                normalizedMotion.X *= -1; normalizedMotion.Y *= 1;
                break;
            }

            if (lastSpin.ElapsedMilliseconds >= 120 || !lastSpin.IsRunning)
            {
                lastSpin.Restart();
                spin += 1;
                if (spin > 3)
                {
                    spin = 0;
                }
            }

            if (lastSpinMove.ElapsedMilliseconds >= 1920 || !lastSpinMove.IsRunning)
            {
                lastSpinMove.Restart();

                // Find random spot where there is some fluid (>10% density).
                do
                {
                    spinOffsetAddX = spinRandom.Next(-(N - xH - 2) / 2, (N - xH - 2) / 2);
                    spinOffsetAddY = spinRandom.Next(-(M - yH - 2) / 2, (M - yH - 2) / 2);
                } while (d[FluidMath.IX(N, offsetX + spinOffsetAddX, offsetY + spinOffsetAddY)] < 0.10f);
            }

            offsetX += spinOffsetAddX;
            offsetY += spinOffsetAddY;

            for (int i = offsetX; i <= offsetX + xH - 1; i++)
            {
                for (int j = offsetY; j <= offsetY + yH - 1; j++)
                {
                    if (d[FluidMath.IX(N, i, j)] > 0)
                    {
                        addU = gravity * (float)normalizedMotion.X * d[FluidMath.IX(N, i, j)];
                        addV = gravity * (float)normalizedMotion.Y * d[FluidMath.IX(N, i, j)];
                    }
                    else
                    {
                        addU = gravity * (float)normalizedMotion.X;
                        addV = gravity * (float)normalizedMotion.Y;
                    }
                    uS[FluidMath.IX(N, i, j)] = addU;
                    vS[FluidMath.IX(N, i, j)] = addV;

                    // Set u.
                    cellVelocity = u[FluidMath.IX(N, i, j)] + addU;
                    if (cellVelocity < -terminalVelocity)
                    {
                        uS[FluidMath.IX(N, i, j)] = addU - (cellVelocity - -terminalVelocity);
                    }
                    else if (cellVelocity > terminalVelocity)
                    {
                        uS[FluidMath.IX(N, i, j)] = addU - (cellVelocity - terminalVelocity);
                    }
                    else
                    {
                        uS[FluidMath.IX(N, i, j)] = addU;
                    }

                    // Set v.
                    cellVelocity = v[FluidMath.IX(N, i, j)] + addV;
                    if (cellVelocity < -terminalVelocity)
                    {
                        vS[FluidMath.IX(N, i, j)] = addV - (cellVelocity - -terminalVelocity);;
                    }
                    else if (cellVelocity > terminalVelocity)
                    {
                        vS[FluidMath.IX(N, i, j)] = addV - (cellVelocity - terminalVelocity);
                    }
                    else
                    {
                        vS[FluidMath.IX(N, i, j)] = addV;
                    }
                }
            }
        }
Esempio n. 5
0
        void AddForces()
        {
            float cellVelocity = 0, addU = 0, addV = 0;
            int   xH = GetXH(FORCE_COVERAGE); int yH = GetYH(FORCE_COVERAGE);
            int   average = (xH + yH) / 2;

            xH = average; yH = average;
            int offsetX = GetOffsetX(xH);
            int offsetY = GetOffsetY(yH);

            // Normalize and reverse X & Y direction.
            MotionVector normalizedMotion = new MotionVector();
            double       normal           = 1.0d; //; Math.Sqrt(Math.Pow(deviceMotion.X, 2) + Math.Pow(deviceMotion.Y, 2) + Math.Pow(deviceMotion.Z, 2));

            normalizedMotion.X = deviceMotion.X / -normal; normalizedMotion.Y = deviceMotion.Y / -normal;

            for (int i = offsetX; i <= offsetX + xH - 1; i++)
            {
                for (int j = offsetY; j <= offsetY + yH - 1; j++)
                {
                    if (d[FluidMath.IX(N, i, j)] > 0)
                    {
                        addU = gravity * (float)normalizedMotion.X * d[FluidMath.IX(N, i, j)];
                        addV = gravity * (float)normalizedMotion.Y * d[FluidMath.IX(N, i, j)];
                    }
                    else
                    {
                        addU = gravity * (float)normalizedMotion.X;
                        addV = gravity * (float)normalizedMotion.Y;
                    }
                    uS[FluidMath.IX(N, i, j)] = addU;
                    vS[FluidMath.IX(N, i, j)] = addV;

                    // Set u.
                    cellVelocity = u[FluidMath.IX(N, i, j)] + addU;
                    if (cellVelocity < -terminalVelocity)
                    {
                        uS[FluidMath.IX(N, i, j)] = addU - (cellVelocity - -terminalVelocity);
                    }
                    else if (cellVelocity > terminalVelocity)
                    {
                        uS[FluidMath.IX(N, i, j)] = addU - (cellVelocity - terminalVelocity);
                    }
                    else
                    {
                        uS[FluidMath.IX(N, i, j)] = addU;
                    }

                    // Set v.
                    cellVelocity = v[FluidMath.IX(N, i, j)] + addV;
                    if (cellVelocity < -terminalVelocity)
                    {
                        vS[FluidMath.IX(N, i, j)] = addV - (cellVelocity - -terminalVelocity);;
                    }
                    else if (cellVelocity > terminalVelocity)
                    {
                        vS[FluidMath.IX(N, i, j)] = addV - (cellVelocity - terminalVelocity);
                    }
                    else
                    {
                        vS[FluidMath.IX(N, i, j)] = addV;
                    }
                }
            }
        }