Beispiel #1
0
 /// <summary>
 /// Checks if this rectangle intersects another rectangle
 /// </summary>
 /// <param name="otherRect">The rectangle to check</param>
 /// <returns>Whether or not this rectangle intersects or touches the other</returns>
 public bool IntersectsOrTouches(FRect otherRect)
 {
     return(!(Bottom < otherRect.Top ||
              Top > otherRect.Bottom ||
              Right < otherRect.Left ||
              Left > otherRect.Right));
 }
        /// <summary>
        /// Returns all items (not nodes) that intersect with the given area.
        /// </summary>
        /// <param name="area"></param>
        /// <returns></returns>
        public List <T> GetItemsWithinArea(FRect area)
        {
            List <T> items = new List <T>();

            RootNode.GetItemsWithinArea(ref items, ref area, false);
            return(items);
        }
Beispiel #3
0
 /// <summary>
 /// Checks if this rectangle intersects another rectangle
 /// </summary>
 /// <param name="otherRect">The rectangle to check</param>
 /// <returns>Whether or not this rectangle intersects the other</returns>
 public bool Intersects(FRect otherRect)
 {
     return(!(Bottom <= otherRect.Top ||
              Top >= otherRect.Bottom ||
              Right <= otherRect.Left ||
              Left >= otherRect.Right));
 }
Beispiel #4
0
        /// <summary>
        /// Modified code from the XNA platformer starter kit 4.0
        /// </summary>
        /// <param name="rectA"></param>
        /// <param name="rectB"></param>
        /// <returns></returns>
        public Vector2 GetIntersectionDepth(FRect rectB)
        {
            // If we are not intersecting at all, return (0, 0).
            if (!Intersects(rectB))
            {
                return(Vector2.Zero);
            }

            // Calculate half sizes.
            float halfWidthA  = Width / 2.0f;
            float halfHeightA = Height / 2.0f;
            float halfWidthB  = rectB.Width / 2.0f;
            float halfHeightB = rectB.Height / 2.0f;

            // Calculate centers.
            Vector2 centerA = CenterLoc;       // new Vector2(Left + halfWidthA, Top + halfHeightA);
            Vector2 centerB = rectB.CenterLoc; //new Vector2(rectB.Left + halfWidthB, rectB.Top + halfHeightB);

            // Calculate current and minimum-non-intersecting distances between centers.
            float distanceX    = centerA.X - centerB.X;
            float distanceY    = centerA.Y - centerB.Y;
            float minDistanceX = halfWidthA + halfWidthB;
            float minDistanceY = halfHeightA + halfHeightB;

            // Calculate and return intersection depths.
            float depthX = distanceX > 0 ? minDistanceX - distanceX : -minDistanceX - distanceX;
            float depthY = distanceY > 0 ? minDistanceY - distanceY : -minDistanceY - distanceY;

            return(new Vector2(depthX, depthY));
        }
Beispiel #5
0
        /// <summary>
        /// DOES NOT WORK. WIP. probably because the additems() doesnt work correctly.
        /// </summary>
        /// <param name="items"></param>
        /// <param name="area"></param>
        /// <param name="skipChecks"></param>
        public void GetItemsWithinArea(ref List <T> items, ref FRect area, bool skipChecks)
        {
            if (skipChecks || AABB.Intersects(area))
            {
                // When the area if entirely within the Cell then skip collision checks on the child nodes
                if (area.FullyEncloses(AABB))
                {
                    skipChecks = true;
                }

                foreach (T item in items)
                {
                    if (skipChecks || item.AABB.Intersects(area))
                    {
                        items.Add(item);
                    }
                }

                if (!IsLeaf)
                {
                    TopLeft.GetItemsWithinArea(ref items, ref area, skipChecks);
                    TopRight.GetItemsWithinArea(ref items, ref area, skipChecks);
                    BottomLeft.GetItemsWithinArea(ref items, ref area, skipChecks);
                    BottomRight.GetItemsWithinArea(ref items, ref area, skipChecks);
                }
            }
        }
        public static Vector2 GetIntersectionDepth(this Rectangle rectA, FRect rectB)
        {
            // Calculate half sizes.
            float halfWidthA  = rectA.Width / 2.0f;
            float halfHeightA = rectA.Height / 2.0f;
            float halfWidthB  = rectB.Width / 2.0f;
            float halfHeightB = rectB.Height / 2.0f;

            // Calculate centers.
            Vector2 centerA = new Vector2(rectA.Left + halfWidthA, rectA.Top + halfHeightA);
            Vector2 centerB = new Vector2(rectB.Left + halfWidthB, rectB.Top + halfHeightB);

            // Calculate current and minimum-non-intersecting distances between centers.
            float distanceX    = centerA.X - centerB.X;
            float distanceY    = centerA.Y - centerB.Y;
            float minDistanceX = halfWidthA + halfWidthB;
            float minDistanceY = halfHeightA + halfHeightB;

            // If we are not intersecting at all, return (0, 0).
            if (Math.Abs(distanceX) >= minDistanceX || Math.Abs(distanceY) >= minDistanceY)
            {
                return(Vector2.Zero);
            }

            // Calculate and return intersection depths.
            float depthX = distanceX > 0 ? minDistanceX - distanceX : -minDistanceX - distanceX;
            float depthY = distanceY > 0 ? minDistanceY - distanceY : -minDistanceY - distanceY;

            return(new Vector2(depthX, depthY));
        }
Beispiel #7
0
 /// <summary>
 /// Root node constructor
 /// </summary>
 /// <param name="AABB"></param>
 /// <param name="maxItems"></param>
 public QuadTreeNode(FRect AABB, int maxItems)
 {
     ParentNode = null; // Rootnode
     this.AABB  = AABB;
     MaxItems   = maxItems;
     m_depth    = 0;
 }
Beispiel #8
0
 /// <summary>
 /// Regular constructor
 /// </summary>
 /// <param name="parentNode"></param>
 /// <param name="AABB"></param>
 /// <param name="maxItems"></param>
 public QuadTreeNode(QuadTreeNode <T> parentNode, FRect AABB, int maxItems)
 {
     ParentNode = parentNode;
     this.AABB  = AABB;
     MaxItems   = maxItems;
     m_depth    = parentNode.Depth + 1;
 }
Beispiel #9
0
        /// <summary>
        /// Determines if a circle intersects a rectangle.
        /// </summary>
        /// <returns>True if the circle and rectangle overlap. False otherwise.
        /// Returns false when the circle is completely inside the rectangle (not tested)</returns>
        public bool Overlaps(FRect rectangle)
        {
            Vector2 v = new Vector2(MathHelper.Clamp(Center.X, rectangle.Left, rectangle.Right),
                                    MathHelper.Clamp(Center.Y, rectangle.Top, rectangle.Bottom));

            Vector2 direction       = Center - v;
            float   distanceSquared = direction.LengthSquared();

            return((distanceSquared > 0) && (distanceSquared < Radius * Radius));
        }
        /// <summary>
        /// Make sure that Rect1 & Rect2 intersect
        /// Source ZiggyWare (now defunct)
        /// </summary>
        /// <param name="Rect1"></param>
        /// <param name="Rect2"></param>
        /// <returns></returns>
        /// <example>
        ///  if (Player.PlayerCollisionRect.Intersects(VolcanoBorderRect))
        ///    {
        ///        //Since our rectangles are colliding, we need to seperate them.  This provides our seperation amount once they have collided.
        ///        Vector2 displacement = GameplayScreen.CalcualteMinimumTranslationDistance(Player.PlayerCollisionRect, VolcanoBorderRect);
        ///        Player.PlayerPos += displacement;  //Move player with seperation amount
        ///    }
        /// </example>
        public static Vector2 CalculateMinimumTranslationDistance(FRect Rect1, FRect Rect2)
        {
            Vector2 result     = Vector2.Zero;
            float   difference = 0.0f;
            float   minimumTranslationDistance = 0.0f; //The absolute minimum distance we'll need to separate our colliding object.
            int     axis = 0;                          // Axis stores the value of X or Y.  X = 0, Y = 1.
            int     side = 0;                          // Side stores the value of left (-1) or right (+1).

            // Left
            difference = Rect1.Right - Rect2.Left;
            minimumTranslationDistance = difference;
            axis = 0;
            side = -1;

            // Right
            difference = Rect2.Right - Rect1.Left;
            if (difference < minimumTranslationDistance)
            {
                minimumTranslationDistance = difference;
                axis = 0;
                side = 1;
            }

            // Down
            difference = Rect1.Bottom - Rect2.Top;
            if (difference < minimumTranslationDistance)
            {
                minimumTranslationDistance = difference;
                axis = 1;
                side = -1;
            }

            // Up
            difference = Rect2.Bottom - Rect1.Top;
            if (difference < minimumTranslationDistance)
            {
                minimumTranslationDistance = difference;
                axis = 1;
                side = 1;
            }

            if (axis == 1) //Y Axis
            {
                result.Y = (float)side * minimumTranslationDistance;
            }
            else
            {   //X Axis
                result.X = (float)side * minimumTranslationDistance;
            }
            //result = new Vector2((float)side * minimumTranslationDistance, (float)side * minimumTranslationDistance);
            return(result);
        }
        // perhaps see: http://stackoverflow.com/questions/8307834/fastest-algorithm-to-edge-detect-between-two-simple-rectangles for an extensive touching example.

        /// <summary>
        /// ONLY tests for touching rectangles. So if rect A contains rectB they do NOT touch!
        /// </summary>
        /// <param name="rectA"></param>
        /// <param name="rectB"></param>
        /// <param name="allowedDifference"></param>
        /// <returns></returns>
        public static bool AreOnlyTouching(this FRect rectA, FRect rectB, float allowedDifference)
        {
            // They are at the same point
            if (rectA.X == rectB.X && rectA.Y == rectB.Y)
            {
                return(true);
            }

            // A's right side touches B's left side
            if (
                (Math.Abs(rectA.Right - rectB.Left) <= allowedDifference) && // X-axis
                ((rectA.Top - allowedDifference) <= rectB.Bottom &&          // Y-axis
                 rectA.Bottom >= (rectB.Top - allowedDifference))            // Y-axis
                )
            {
                return(true);
            }

            // A's left side touches B's right side
            if (
                (Math.Abs(rectA.Left - rectB.Right) <= allowedDifference) && // X-axis
                ((rectA.Top - allowedDifference) <= rectB.Bottom &&          // Y-axis
                 rectA.Bottom >= (rectB.Top - allowedDifference))            // Y-axis
                )
            {
                return(true);
            }


            // A's bottom touches B's top
            if (
                (Math.Abs(rectA.Bottom - rectB.Top) <= allowedDifference) && // Y-axis
                ((rectA.Left + allowedDifference) <= rectB.Right &&          // X-axis
                 rectA.Right >= (rectB.Left - allowedDifference))            // X-axis
                )
            {
                return(true);
            }

            // A's top touches B's bottom
            // A's left side touches B's right side
            if (
                (Math.Abs(rectA.Top - rectB.Bottom) <= allowedDifference) && // Y-axis
                ((rectA.Left + allowedDifference) <= rectB.Right &&          // X-axis
                 rectA.Right >= (rectB.Left - allowedDifference))            // X-axis
                )
            {
                return(true);
            }

            return(false);
        }
Beispiel #12
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="otherRect"></param>
        /// <returns>The overlapping area or FRect.Empty when no collision</returns>
        public FRect Overlap(FRect otherRect)
        {
            if (!Intersects(otherRect))
            {
                return(FRect.Empty);
            }

            FRect result = FRect.Empty;

            result.Left   = Math.Max(Left, otherRect.Left);
            result.Top    = Math.Max(Top, otherRect.Top);
            result.Width  = Math.Min(Right, otherRect.Right) - result.Left;
            result.Height = Math.Min(Bottom, otherRect.Bottom) - result.Top;
            return(result);
        }
        /// <summary>
        /// Check for collision between a circle and a FRectangle
        /// </summary>
        /// <param name="centerPoint"></param>
        /// <param name="radius"></param>
        /// <param name="rectangle"></param>
        /// <returns></returns>
        public static bool Intersects(Vector2 circleCenterLoc, float radius, FRect rectangle)
        {
            if (Collision.PointIsInRect(circleCenterLoc, rectangle))
            {
                return(true);
            }


            Vector2 v = new Vector2(MathHelper.Clamp(circleCenterLoc.X, rectangle.Left, rectangle.Right),
                                    MathHelper.Clamp(circleCenterLoc.Y, rectangle.Top, rectangle.Bottom));

            Vector2 direction       = circleCenterLoc - v;
            float   distanceSquared = direction.LengthSquared();

            return((distanceSquared > 0) && (distanceSquared < radius * radius));
        }
Beispiel #14
0
        public HexGrid(Vector2 topLeft, int width, int height, int tileWidth, int tileHeight, string defaultTileTexture)
        {
            TopLeft     = topLeft;
            Width       = width;
            Height      = height;
            ArrayWidth  = width / tileWidth - 1; // -1 because otherwise the last tile in the odd rows would overlap with 50%.
            ArrayHeight = (int)(height / (tileHeight * 0.75f));
            TileArray   = new HexTile[ArrayWidth, ArrayHeight];

            m_GridArea = new FRect(topLeft, width, height);

            DefaultTileTex = Common.str2Tex(defaultTileTexture);
            TileWidth      = tileWidth;
            TileHeight     = tileHeight;

            Create();
            SetNeigbours();
        }
        /// <summary>
        /// Author: Napoleon.
        /// Tested and works.
        /// Only apply this to non-rotated rectangles.
        /// Touching rectangles don't count in this function
        /// </summary>
        /// <param name="movingRect">Usually the player or moving object.</param>
        /// <param name="staticRect">Usually the wall or something. The collided sides are the sides from this rectangle</param>
        /// <returns></returns>
        /// <example>
        ///  if ((collidedSides & Collision.RectSide.Top) == Collision.RectSide.Top)
        ///    // Top side was hit, do something here
        /// </example>
        public static RectSide CollidedSidesNoTouch(this FRect movingRect, FRect staticRect)
        {
            RectSide result = RectSide.None;

            if (!movingRect.Intersects(staticRect))
            {
                return(result); // No intersection at all
            }
            if (movingRect == staticRect)
            {
                return(RectSide.Equal);
            }

            // Left
            if (movingRect.Right > staticRect.Left && movingRect.Left < staticRect.Left)
            {
                result = (result | RectSide.Left);
            }

            // Top
            if (movingRect.Bottom > staticRect.Top && movingRect.Top < staticRect.Top)
            {
                result = (result | RectSide.Top);
            }

            // Right
            if (movingRect.Left < staticRect.Right && movingRect.Right > staticRect.Right)
            {
                result = (result | RectSide.Right);
            }

            // Bottom
            if (movingRect.Top < staticRect.Bottom && movingRect.Bottom > staticRect.Bottom)
            {
                result = (result | RectSide.Bottom);
            }

            if (result == RectSide.None)
            {
                return(RectSide.Inside); // moving rectangle is inside the static rectangle
            }
            return(result);
        }
Beispiel #16
0
 /// <summary>
 /// Checks if this rectangle fully encloses a smaller rectangle within it. If one or more eges are touching then it does not count as a full overlap.
 /// </summary>
 /// <param name="rect"></param>
 /// <returns></returns>
 public bool FullyEncloses(FRect rect)
 {
     return(rect.Top > Top && rect.Right < Right && rect.Bottom < Bottom && rect.Left > Left);
 }
 public static bool PointIsInRect(Vector2 point, FRect rectangle)
 {
     return(point.X >= rectangle.Left && point.X <= rectangle.Right && point.Y >= rectangle.Top && point.Y <= rectangle.Bottom);
 }
Beispiel #18
0
 public bool Collide(FRect rectangle)
 {
     return(Overlaps(rectangle) || rectangle.Contains(Center));
 }