コード例 #1
0
        private static int[] GetFieldCircle(Point point, double radiusX, double radiusY, FluidField2D field)
        {
            // Get the box that contains the return circle
            var center = GetFieldPoint_XY(point, field);
            var min = GetFieldPoint_XY(new Point(point.X - radiusX, point.Y - radiusY), field);
            var max = GetFieldPoint_XY(new Point(point.X + radiusX, point.Y + radiusY), field);

            // Get points that are inside the circle
            List<int> retVal = new List<int>();
            double maxDistance = ((radiusX * field.XSize) + (radiusY * field.YSize)) * .5d;     // just take the average.  TODO: see if inside the ellipse
            double maxDistanceSquared = maxDistance * maxDistance;

            for (int x = min.Item1; x <= max.Item1; x++)
            {
                for (int y = min.Item2; y <= max.Item2; y++)
                {
                    double dx = x - center.Item1;
                    double dy = y - center.Item2;
                    double distanceSquared = (dx * dx) + (dy * dy);

                    if (distanceSquared <= maxDistanceSquared)
                    {
                        retVal.Add(field.GetK(x, y));
                    }
                }
            }

            // Exit Function
            return retVal.ToArray();
        }
コード例 #2
0
        private static Tuple<int, double>[] GetFieldCircle(Point point, double radiusX, double radiusY, double valueCenter, double valueEdge, FluidField2D field)
        {
            // Get the box that contains the return circle
            var center = GetFieldPoint_XY(new Point(point.X, point.Y), field);
            var min = GetFieldPoint_XY(new Point(point.X - radiusX, point.Y - radiusY), field);
            var max = GetFieldPoint_XY(new Point(point.X + radiusX, point.Y + radiusY), field);

            // Get points that are inside the circle
            List<Tuple<int, double>> retVal = new List<Tuple<int, double>>();
            Vector radius = new Vector(radiusX * field.XSize, radiusY * field.YSize);
            double maxDistance = ((radiusX * field.XSize) + (radiusY * field.YSize)) * .5d;     // just take the average.  TODO: see if inside the ellipse
            double maxDistanceSquared = maxDistance * maxDistance;

            for (int x = min.Item1; x <= max.Item1; x++)
            {
                for (int y = min.Item2; y <= max.Item2; y++)
                {
                    double dx = x - center.Item1;
                    double dy = y - center.Item2;
                    double distanceSquared = (dx * dx) + (dy * dy);

                    if (distanceSquared <= maxDistanceSquared)
                    {
                        double distance = Math.Sqrt(distanceSquared);

                        retVal.Add(Tuple.Create(
                            field.GetK(x, y),       // coordinates that the field wants
                            UtilityCore.GetScaledValue(valueCenter, valueEdge, 0, maxDistance, distance)      // LERP
                            ));
                    }
                }
            }

            // Exit Function
            return retVal.ToArray();
        }
コード例 #3
0
        private static Tuple<int, int> GetFieldPoint_XY(Point point, FluidField2D field)
        {
            int x = Convert.ToInt32(Math.Round(point.X * field.XSize));
            if (x < 0)
            {
                x = 0;
            }
            else if (x >= field.XSize)
            {
                x = field.XSize - 1;
            }

            int y = Convert.ToInt32(Math.Round(point.Y * field.XSize));
            if (y < 0)
            {
                y = 0;
            }
            else if (y >= field.YSize)
            {
                y = field.YSize - 1;
            }

            return Tuple.Create(x, y);
        }
コード例 #4
0
        /// <summary>
        /// This takes a point from 0 to 1, and returns the corresponding position in the field (what the field calls k)
        /// </summary>
        private static int GetFieldPoint(Point point, FluidField2D field)
        {
            var xy = GetFieldPoint_XY(point, field);

            return field.GetK(xy.Item1, xy.Item2);
        }
コード例 #5
0
        private static void DrawField(WriteableBitmap bitmap, FluidField2D field, bool showBlockedCells)
        {
            Int32Rect rect = new Int32Rect(0, 0, field.XSize, field.YSize);
            int size = rect.Width * rect.Height * 4;
            byte[] pixels = new byte[size];

            double[] reds = field.GetLayer(0);
            double[] greens = field.GetLayer(1);
            double[] blues = field.GetLayer(2);

            var blockedCells = field.Blocked;

            //NOTE: The field's arrays happen to be the same layout as the rect, so there's no need to call field.GetK

            // Setup the pixel array
            for (int i = 0; i < rect.Height * rect.Width; i++)
            {
                if (blockedCells[i] && showBlockedCells)
                {
                    pixels[i * 4 + 0] = 255;   // Blue
                    pixels[i * 4 + 1] = 255;     // Green
                    pixels[i * 4 + 2] = 255;     // Red
                    pixels[i * 4 + 3] = 255;   // Alpha
                }
                else
                {
                    pixels[i * 4 + 0] = ConvertToByteCapped(blues[i] * 256);   // Blue
                    pixels[i * 4 + 1] = ConvertToByteCapped(greens[i] * 256);     // Green
                    pixels[i * 4 + 2] = ConvertToByteCapped(reds[i] * 256);     // Red
                    pixels[i * 4 + 3] = 255;   // Alpha
                }
            }

            bitmap.WritePixels(rect, pixels, rect.Width * 4, 0);
        }
コード例 #6
0
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            try
            {

                // Field
                _field = new FluidField2D(200, 200, 3);
                _field.UseCheapDiffusion = !chkUseStandardDiffusion.IsChecked.Value;

                _field.Vorticity = 0;       //this is currently broken

                // Sliders
                PropertyInfo[] propsOptions = typeof(FluidField2D).GetProperties();
                _propLinks.Add(new SliderShowValues.PropSync(trkDiffusion, propsOptions.Where(o => o.Name == "Diffusion").First(), _field, 0, .1));
                _propLinks.Add(new SliderShowValues.PropSync(trkViscocity, propsOptions.Where(o => o.Name == "Viscosity").First(), _field, 0, .1));
                _propLinks.Add(new SliderShowValues.PropSync(trkWallReflection, propsOptions.Where(o => o.Name == "WallReflectivity").First(), _field, 0, 1));
                _propLinks.Add(new SliderShowValues.PropSync(trkVorticity, propsOptions.Where(o => o.Name == "Vorticity").First(), _field, 0, 1));
                _propLinks.Add(new SliderShowValues.PropSync(trkTimestep, propsOptions.Where(o => o.Name == "TimeStep").First(), _field, 0, 100));
                _propLinks.Add(new SliderShowValues.PropSync(trkIterations, propsOptions.Where(o => o.Name == "Iterations").First(), _field, 0, 20));

                _colorBrushSize = new SliderSettings() { Min = 0, Max = .5, Value = .125 };
                _wallBrushSize = new SliderSettings() { Min = 0, Max = .1, Value = .033 };

                trkBrushSize.Minimum = _colorBrushSize.Min;
                trkBrushSize.Maximum = _colorBrushSize.Max;
                trkBrushSize.Value = _colorBrushSize.Value;

                trkVelocityMultiplier.Minimum = .1;
                trkVelocityMultiplier.Maximum = 100;        //NOTE: the right side scales from 1 to 100, but the left side scales from 1/10 to 1 (because large multipliers are more interesting)
                trkVelocityMultiplier.Value = 8;

                ResetField();

                // Create a new image
                Image img = new Image();
                RenderOptions.SetBitmapScalingMode(img, BitmapScalingMode.NearestNeighbor);
                RenderOptions.SetEdgeMode(img, EdgeMode.Aliased);

                // Add this image to the canvas
                grdFluid.Children.Add(img);

                // Create the bitmap, and set
                _bitmap = new WriteableBitmap(_field.XSize, _field.YSize, UtilityWPF.DPI, UtilityWPF.DPI, PixelFormats.Bgra32, null);

                img.Source = _bitmap;
                img.Stretch = Stretch.Fill;

                // Timer
                _timer = new DispatcherTimer();
                _timer.Interval = TimeSpan.FromMilliseconds(1);
                _timer.Tick += Timer_Tick;
                _timer.IsEnabled = true;

                // Need to manually set the scrollviewer's height (a binding can't be conditional - see Window_SizeChanged)
                expanderScrollViewer.MaxHeight = expanderRow.ActualHeight;

                _isInitialized = true;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }
コード例 #7
0
        public VelocityVisualizerVisualHost(FluidField2D field)
        {
            _field = field;

            this.AddVisualChild(_visual);
        }