Advertisement
Guest User

Untitled

a guest
Dec 21st, 2014
353
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 9.23 KB | None | 0 0
  1. public class RotatedRectangle
  2.     {
  3.         public Rectangle CollisionRectangle;
  4.         public float Rotation;
  5.         public Vector2 Origin;
  6.        
  7.         public RotatedRectangle(Rectangle theRectangle, float theInitialRotation)
  8.         {
  9.             CollisionRectangle = theRectangle;
  10.             Rotation = theInitialRotation;
  11.        
  12.             //Calculate the Rectangles origin. We assume the center of the Rectangle will
  13.             //be the point that we will be rotating around and we use that for the origin
  14.             Origin = new Vector2((int)theRectangle.Width / 2, (int)theRectangle.Height / 2);
  15.         }
  16.  
  17.         /// <summary>
  18.         /// Used for changing the X and Y position of the RotatedRectangle
  19.         /// </summary>
  20.         /// <param name="theXPositionAdjustment"></param>
  21.         /// <param name="theYPositionAdjustment"></param>
  22.         public void ChangePosition(int theXPositionAdjustment, int theYPositionAdjustment)
  23.         {
  24.             CollisionRectangle.X += theXPositionAdjustment;
  25.             CollisionRectangle.Y += theYPositionAdjustment;
  26.         }
  27.  
  28.         /// <summary>
  29.         /// This intersects method can be used to check a standard XNA framework Rectangle
  30.         /// object and see if it collides with a Rotated Rectangle object
  31.         /// </summary>
  32.         /// <param name="theRectangle"></param>
  33.         /// <returns></returns>
  34.         public bool Intersects(Rectangle theRectangle)
  35.         {
  36.             return Intersects(new RotatedRectangle(theRectangle, 0.0f));
  37.         }
  38.  
  39.         /// <summary>
  40.         /// Check to see if two Rotated Rectangls have collided
  41.         /// </summary>
  42.         /// <param name="theRectangle"></param>
  43.         /// <returns></returns>
  44.         public bool Intersects(RotatedRectangle theRectangle)
  45.         {
  46.             //Calculate the Axis we will use to determine if a collision has occurred
  47.             //Since the objects are rectangles, we only have to generate 4 Axis (2 for
  48.             //each rectangle) since we know the other 2 on a rectangle are parallel.
  49.             List<Vector2> aRectangleAxis = new List<Vector2>();
  50.             aRectangleAxis.Add(UpperRightCorner() - UpperLeftCorner());
  51.             aRectangleAxis.Add(UpperRightCorner() - LowerRightCorner());
  52.             aRectangleAxis.Add(theRectangle.UpperLeftCorner() - theRectangle.LowerLeftCorner());
  53.             aRectangleAxis.Add(theRectangle.UpperLeftCorner() - theRectangle.UpperRightCorner());
  54.  
  55.             //Cycle through all of the Axis we need to check. If a collision does not occur
  56.             //on ALL of the Axis, then a collision is NOT occurring. We can then exit out
  57.             //immediately and notify the calling function that no collision was detected. If
  58.             //a collision DOES occur on ALL of the Axis, then there is a collision occurring
  59.             //between the rotated rectangles. We know this to be true by the Seperating Axis Theorem
  60.             foreach (Vector2 aAxis in aRectangleAxis)
  61.             {
  62.                 if (!IsAxisCollision(theRectangle, aAxis))
  63.                 {
  64.                     return false;
  65.                 }
  66.             }
  67.  
  68.             return true;
  69.         }
  70.        
  71.         /// <summary>
  72.         /// Determines if a collision has occurred on an Axis of one of the
  73.         /// planes parallel to the Rectangle
  74.         /// </summary>
  75.         /// <param name="theRectangle"></param>
  76.         /// <param name="aAxis"></param>
  77.         /// <returns></returns>
  78.         private bool IsAxisCollision(RotatedRectangle theRectangle, Vector2 aAxis)
  79.         {
  80.             //Project the corners of the Rectangle we are checking on to the Axis and
  81.             //get a scalar value of that project we can then use for comparison
  82.             List<int> aRectangleAScalars = new List<int>();
  83.             aRectangleAScalars.Add(GenerateScalar(theRectangle.UpperLeftCorner(), aAxis));
  84.             aRectangleAScalars.Add(GenerateScalar(theRectangle.UpperRightCorner(), aAxis));
  85.             aRectangleAScalars.Add(GenerateScalar(theRectangle.LowerLeftCorner(), aAxis));
  86.             aRectangleAScalars.Add(GenerateScalar(theRectangle.LowerRightCorner(), aAxis));
  87.  
  88.             //Project the corners of the current Rectangle on to the Axis and
  89.             //get a scalar value of that project we can then use for comparison
  90.             List<int> aRectangleBScalars = new List<int>();
  91.             aRectangleBScalars.Add(GenerateScalar(UpperLeftCorner(), aAxis));
  92.             aRectangleBScalars.Add(GenerateScalar(UpperRightCorner(), aAxis));
  93.             aRectangleBScalars.Add(GenerateScalar(LowerLeftCorner(), aAxis));
  94.             aRectangleBScalars.Add(GenerateScalar(LowerRightCorner(), aAxis));
  95.  
  96.             //Get the Maximum and Minium Scalar values for each of the Rectangles
  97.             int aRectangleAMinimum = aRectangleAScalars.Min();
  98.             int aRectangleAMaximum = aRectangleAScalars.Max();
  99.             int aRectangleBMinimum = aRectangleBScalars.Min();
  100.             int aRectangleBMaximum = aRectangleBScalars.Max();
  101.  
  102.             //If we have overlaps between the Rectangles (i.e. Min of B is less than Max of A)
  103.             //then we are detecting a collision between the rectangles on this Axis
  104.             if (aRectangleBMinimum <= aRectangleAMaximum && aRectangleBMaximum >= aRectangleAMaximum)
  105.             {
  106.                 return true;
  107.             }
  108.             else if (aRectangleAMinimum <= aRectangleBMaximum && aRectangleAMaximum >= aRectangleBMaximum)
  109.             {
  110.                 return true;
  111.             }
  112.  
  113.             return false;
  114.         }
  115.  
  116.         /// <summary>
  117.         /// Generates a scalar value that can be used to compare where corners of
  118.         /// a rectangle have been projected onto a particular axis.
  119.         /// </summary>
  120.         /// <param name="theRectangleCorner"></param>
  121.         /// <param name="theAxis"></param>
  122.         /// <returns></returns>
  123.         private int GenerateScalar(Vector2 theRectangleCorner, Vector2 theAxis)
  124.         {
  125.             //Using the formula for Vector projection. Take the corner being passed in
  126.             //and project it onto the given Axis
  127.             float aNumerator = (theRectangleCorner.X * theAxis.X) + (theRectangleCorner.Y * theAxis.Y);
  128.             float aDenominator = (theAxis.X * theAxis.X) + (theAxis.Y * theAxis.Y);
  129.             float aDivisionResult = aNumerator / aDenominator;
  130.             Vector2 aCornerProjected = new Vector2(aDivisionResult * theAxis.X, aDivisionResult * theAxis.Y);
  131.            
  132.             //Now that we have our projected Vector, calculate a scalar of that projection
  133.             //that can be used to more easily do comparisons
  134.             float aScalar = (theAxis.X * aCornerProjected.X) + (theAxis.Y * aCornerProjected.Y);
  135.             return (int)aScalar;
  136.         }
  137.  
  138.         /// <summary>
  139.         /// Rotate a point from a given location and adjust using the Origin we
  140.         /// are rotating around
  141.         /// </summary>
  142.         /// <param name="thePoint"></param>
  143.         /// <param name="theOrigin"></param>
  144.         /// <param name="theRotation"></param>
  145.         /// <returns></returns>
  146.         private Vector2 RotatePoint(Vector2 thePoint, Vector2 theOrigin, float theRotation)
  147.         {
  148.             Vector2 aTranslatedPoint = new Vector2();
  149.             aTranslatedPoint.X = (float)(theOrigin.X + (thePoint.X - theOrigin.X) * Math.Cos(theRotation)
  150.                 - (thePoint.Y - theOrigin.Y) * Math.Sin(theRotation));
  151.             aTranslatedPoint.Y = (float)(theOrigin.Y + (thePoint.Y - theOrigin.Y) * Math.Cos(theRotation)
  152.                 + (thePoint.X - theOrigin.X) * Math.Sin(theRotation));
  153.             return aTranslatedPoint;
  154.         }
  155.                
  156.         public Vector2 UpperLeftCorner()
  157.         {
  158.             Vector2 aUpperLeft = new Vector2(CollisionRectangle.Left, CollisionRectangle.Top);
  159.             aUpperLeft = RotatePoint(aUpperLeft, aUpperLeft + Origin, Rotation);
  160.             return aUpperLeft;
  161.         }
  162.  
  163.         public Vector2 UpperRightCorner()
  164.         {
  165.             Vector2 aUpperRight = new Vector2(CollisionRectangle.Right, CollisionRectangle.Top);
  166.             aUpperRight = RotatePoint(aUpperRight, aUpperRight + new Vector2(-Origin.X, Origin.Y), Rotation);
  167.             return aUpperRight;
  168.         }
  169.  
  170.         public Vector2 LowerLeftCorner()
  171.         {
  172.             Vector2 aLowerLeft = new Vector2(CollisionRectangle.Left, CollisionRectangle.Bottom);
  173.             aLowerLeft = RotatePoint(aLowerLeft, aLowerLeft + new Vector2(Origin.X, -Origin.Y), Rotation);
  174.             return aLowerLeft;
  175.         }
  176.  
  177.         public Vector2 LowerRightCorner()
  178.         {
  179.             Vector2 aLowerRight = new Vector2(CollisionRectangle.Right, CollisionRectangle.Bottom);
  180.             aLowerRight = RotatePoint(aLowerRight, aLowerRight + new Vector2(-Origin.X, -Origin.Y), Rotation);
  181.             return aLowerRight;
  182.         }
  183.  
  184.         public int X
  185.         {
  186.             get { return CollisionRectangle.X; }
  187.         }
  188.  
  189.         public int Y
  190.         {
  191.             get { return CollisionRectangle.Y; }
  192.         }
  193.  
  194.         public int Width
  195.         {
  196.             get { return CollisionRectangle.Width; }
  197.         }
  198.  
  199.         public int Height
  200.         {
  201.             get { return CollisionRectangle.Height; }
  202.         }
  203.  
  204.     }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement