예제 #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
        /// <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));
        }
예제 #4
0
        public void Update()
        {
            const int NUMSAMPLES = 20;

            double width  = this.ActualWidth;
            double height = this.ActualHeight;

            if (double.IsNaN(width) || double.IsInfinity(width))
            {
                // This control isn't visible yet
                return;
            }

            DrawingContext drawing = _visual.RenderOpen();

            double[] xVel, yVel;

            xVel = _field.XVel;
            yVel = _field.YVel;

            int xSize = _field.XSize;
            int ySize = _field.YSize;

            double cellWidth      = width / xSize;
            double cellHeight     = height / ySize;
            double cellHalfWidth  = cellWidth / 2d;
            double cellHalfHeight = cellHeight / 2d;

            double scale = (width + height) / 2d;

            double dotRadius = (cellWidth + cellHeight) / 5d;

            // Always include 0 and size - 1.  The rest should be evenly distributed
            double incX = Convert.ToDouble(xSize - 1) / (NUMSAMPLES - 1);        // subtracting 1 to guarantee the edges get one
            double incY = Convert.ToDouble(ySize - 1) / (NUMSAMPLES - 1);

            for (double xd = 0; xd < xSize; xd += incX)
            {
                for (double yd = 0; yd < ySize; yd += incY)
                {
                    int x = Convert.ToInt32(Math.Round(xd));
                    if (x > xSize - 1)
                    {
                        x = xSize - 1;
                    }
                    int y = Convert.ToInt32(Math.Round(yd));
                    if (y > ySize - 1)
                    {
                        y = ySize - 1;
                    }

                    // Figure out the center of this cell
                    Point center = new Point((cellWidth * x) + cellHalfWidth, (cellHeight * y) + cellHalfHeight);

                    // Add the velocity at this cell
                    int   index = FluidField2D.GetK(xSize, x, y);
                    Point end   = new Point(center.X + (xVel[index] * scale), center.Y + (yVel[index] * scale));

                    drawing.DrawLine(_pen, center, end);

                    //drawing.DrawEllipse(Brushes.Gold, _pen, center, dotRadius, dotRadius);        // too expensive
                }
            }

            drawing.Close();

            this.InvalidateVisual();
        }