Пример #1
0
        //SAT for two rotated rectangles
        // 1st rectangle is weaker so is moved out by return vector2
        public static Vector2 intersectRectangles(RectangleShape a, RectangleShape b)
        {
            RectangleShape ar = new RectangleShape(new Rectangle((int)(a.getRectangle().X - a.getRotatePoint().X),
                (int)(a.getRectangle().Y - a.getRotatePoint().Y), a.getRectangle().Width, a.getRectangle().Height),
                a.getRotatePoint(), a.getRotation(), 0);

            //Rotated Vector points of Rectangle A
            Vector2 aUL = UpperLeftCorner(ar);
            Vector2 aUR = UpperRightCorner(ar);
            Vector2 aLL = LowerLeftCorner(ar);
            Vector2 aLR = LowerRightCorner(ar);

            Vector2[] aPoints = new Vector2[] { aUL, aUR, aLL, aLR };

            int aLeft = (int)Math.Min(Math.Min(aUL.X, aUR.X), Math.Min(aLL.X, aLR.X));
            int aTop = (int)Math.Min(Math.Min(aUL.Y, aUR.Y), Math.Min(aLL.Y, aLR.Y));
            int aRight = (int)Math.Max(Math.Max(aUL.X, aUR.X), Math.Max(aLL.X, aLR.X));
            int aBottom = (int)Math.Max(Math.Max(aUL.Y, aUR.Y), Math.Max(aLL.Y, aLR.Y));

            Rectangle aNoRotate = new Rectangle(aLeft, aTop, aRight - aLeft, aBottom - aTop);

            RectangleShape br = new RectangleShape(new Rectangle((int)(b.getRectangle().X - b.getRotatePoint().X),
                (int)(b.getRectangle().Y - b.getRotatePoint().Y), b.getRectangle().Width, b.getRectangle().Height),
                b.getRotatePoint(), b.getRotation(), 0);

            //Rotated Vector points of Rectangle B
            Vector2 bUL = UpperLeftCorner(br);
            Vector2 bUR = UpperRightCorner(br);
            Vector2 bLL = LowerLeftCorner(br);
            Vector2 bLR = LowerRightCorner(br);

            Vector2[] bPoints = new Vector2[] { bUL, bUR, bLL, bLR };

            int bLeft = (int)Math.Min(Math.Min(bUL.X, bUR.X), Math.Min(bLL.X, bLR.X));
            int bTop = (int)Math.Min(Math.Min(bUL.Y, bUR.Y), Math.Min(bLL.Y, bLR.Y));
            int bRight = (int)Math.Max(Math.Max(bUL.X, bUR.X), Math.Max(bLL.X, bLR.X));
            int bBottom = (int)Math.Max(Math.Max(bUL.Y, bUR.Y), Math.Max(bLL.Y, bLR.Y));

            Rectangle bNoRotate = new Rectangle(bLeft, bTop, bRight - bLeft, bBottom - bTop);

            //Checks initially for the bounding rectangles non rotated.
            if (!intersectRectanglesNoRotate(aNoRotate, bNoRotate))
            {
                return Vector2.Zero;
            }

            List<Vector2> aRectangleAxis = new List<Vector2>();
            aRectangleAxis.Add(aUR - aUL);
            aRectangleAxis.Add(aUR - aLR);
            aRectangleAxis.Add(bUL - bLL);
            aRectangleAxis.Add(bUL - bUR);

            //Cycle through all of the Axis we need to check. If a collision does not occur
            //on ALL of the Axis, then a collision is NOT occurring. We can then exit out
            //immediately and notify the calling function that no collision was detected. If
            //a collision DOES occur on ALL of the Axis, then there is a collision occurring
            //between the rotated rectangles. We know this to be true by the Seperating Axis Theorem
            Vector2 smallest = new Vector2(10000, 10000);
            foreach (Vector2 aAxis in aRectangleAxis)
            {

                Vector2 res = IsAxisCollision(aPoints, bPoints, aAxis);
                if (res == Vector2.Zero)
                {
                    return Vector2.Zero;
                }
                else
                {
                    if (Math.Pow(res.X, 2) + Math.Pow(res.Y, 2) < Math.Pow(smallest.X, 2) + Math.Pow(smallest.Y, 2))
                    {
                        smallest = res;
                    }
                }

            }

            return smallest;
        }
Пример #2
0
        private static Vector2 intersectCircleRectangle(Circle circle, RectangleShape rectangle)
        {
            RectangleShape rectangle2 = new RectangleShape(new Rectangle((int)(rectangle.getRectangle().X - rectangle.getRotatePoint().X),
                (int)(rectangle.getRectangle().Y - rectangle.getRotatePoint().Y),
                rectangle.getRectangle().Width, rectangle.getRectangle().Height),
                rectangle.getRotatePoint(), rectangle.getRotation(), 0);

            //Rotated Vector points of Rectangle
            Vector2 rUL = UpperLeftCorner(rectangle2);
            Vector2 rUR = UpperRightCorner(rectangle2);
            Vector2 rLL = LowerLeftCorner(rectangle2);
            Vector2 rLR = LowerRightCorner(rectangle2);

            Vector2[] bPoints = new Vector2[] { rUL, rUR, rLL, rLR };

            int bLeft = (int)Math.Min(Math.Min(rUL.X, rUR.X), Math.Min(rLL.X, rLR.X));
            int bTop = (int)Math.Min(Math.Min(rUL.Y, rUR.Y), Math.Min(rLL.Y, rLR.Y));
            int bRight = (int)Math.Max(Math.Max(rUL.X, rUR.X), Math.Max(rLL.X, rLR.X));
            int bBottom = (int)Math.Max(Math.Max(rUL.Y, rUR.Y), Math.Max(rLL.Y, rLR.Y));

            Vector2 Normalisedvec;
            //Now we normalise the rectangle and circle by rotating the two objects by the rectangles rotation
            Vector2 rNUL = GeometryHelper.rotatePoint(rUL, new Vector2(rectangle2.getRectangle().X, rectangle2.getRectangle().Y), -rectangle2.getRotation());
            Vector2 rNUR = GeometryHelper.rotatePoint(rUR, new Vector2(rectangle2.getRectangle().X, rectangle2.getRectangle().Y), -rectangle2.getRotation());
            Vector2 rNLL = GeometryHelper.rotatePoint(rLL, new Vector2(rectangle2.getRectangle().X, rectangle2.getRectangle().Y), -rectangle2.getRotation());
            Vector2 rNLR = GeometryHelper.rotatePoint(rLR, new Vector2(rectangle2.getRectangle().X, rectangle2.getRectangle().Y), -rectangle2.getRotation());

            Rectangle recNormal = new Rectangle((int)rNUL.X, (int)rNUL.Y, (int)(rNUR.X - rNUL.X), (int)(rNLL.Y - rNUL.Y));

            Vector2 circleLoc = GeometryHelper.rotatePoint(circle.getLocation(),
                new Vector2(rectangle2.getRectangle().X, rectangle2.getRectangle().Y), -rectangle2.getRotation());

            //Now we check for voronoi regions on the rectangle
            bool voronoid = false;
            Vector2 vertexVoronoi;

            //See if cirlce point fits in any voronoi region
            if (circleLoc.X < recNormal.Left && circleLoc.Y < recNormal.Top)
            {
                vertexVoronoi = rNUL;
                voronoid = true;
            }

            if (circleLoc.X > recNormal.Right && circleLoc.Y < recNormal.Top)
            {
                vertexVoronoi = rNUR;
                voronoid = true;
            }

            if (circleLoc.X < recNormal.Left && circleLoc.Y > recNormal.Bottom)
            {
                vertexVoronoi = rNLL;
                voronoid = true;
            }

            if (circleLoc.X > recNormal.Right && circleLoc.Y > recNormal.Bottom)
            {
                vertexVoronoi = rNLR;
                voronoid = true;
            }

            if (!voronoid)
            {
                circle.setRotation(0.0f);

                Rectangle circleRec = new Rectangle((int)(circleLoc.X - circle.getRadius()), (int)(circleLoc.Y - circle.getRadius()), (int)circle.getRadius() * 2, (int)circle.getRadius() * 2);

                Normalisedvec = intersectRectangles(new RectangleShape(circleRec, Vector2.Zero, 0, 0), new RectangleShape(recNormal, Vector2.Zero, 0, 0));
            }
            else
            {
                circle.setRotation((float)Math.PI / 4);

                Rectangle circleRec = new Rectangle((int)(circleLoc.X), (int)(circleLoc.Y), (int)circle.getRadius() * 2, (int)circle.getRadius() * 2);

                Normalisedvec = intersectRectangles(new RectangleShape(circleRec, new Vector2(circle.getRadius(), circle.getRadius()), (float)Math.PI / 4, 0), new RectangleShape(recNormal, Vector2.Zero, 0, 0));
            }
            return GeometryHelper.rotatePoint(Normalisedvec, Vector2.Zero, rectangle.getRotation());
        }
Пример #3
0
 public static Vector2 UpperRightCorner(RectangleShape a)
 {
     Vector2 aUpperRight = new Vector2(a.getRectangle().Right, a.getRectangle().Top);
     aUpperRight = RotatePoint(aUpperRight, aUpperRight + new Vector2(-(a.getRectangle().Width - a.getRotatePoint().X),
         a.getRotatePoint().Y), a.getRotation());
     return aUpperRight;
 }
Пример #4
0
 public static Vector2 UpperLeftCorner(RectangleShape a)
 {
     Vector2 aUpperLeft = new Vector2(a.getRectangle().Left, a.getRectangle().Top);
     aUpperLeft = RotatePoint(aUpperLeft, aUpperLeft + a.getRotatePoint(), a.getRotation());
     return aUpperLeft;
 }
Пример #5
0
 public static Vector2 LowerRightCorner(RectangleShape a)
 {
     Vector2 aLowerRight = new Vector2(a.getRectangle().Right, a.getRectangle().Bottom);
     aLowerRight = RotatePoint(aLowerRight, aLowerRight + new Vector2(-(a.getRectangle().Width - a.getRotatePoint().X),
         -(a.getRectangle().Height - a.getRotatePoint().Y)), a.getRotation());
     return aLowerRight;
 }
Пример #6
0
 public static Vector2 LowerLeftCorner(RectangleShape a)
 {
     Vector2 aLowerLeft = new Vector2(a.getRectangle().Left, a.getRectangle().Bottom);
     aLowerLeft = RotatePoint(aLowerLeft, aLowerLeft + new Vector2(a.getRotatePoint().X,
         -(a.getRectangle().Height - a.getRotatePoint().Y)), a.getRotation());
     return aLowerLeft;
 }