/RecycleRobo/RecycleRobo/MiniGame/RotatedRectangle.cs

https://bitbucket.org/huuloc/imaginecup_recyclerobo
C# | 101 lines | 68 code | 17 blank | 16 comment | 9 complexity | 994b66f5422901c0d359b7be0774d0df MD5 | raw file
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using Microsoft.Xna.Framework;
  6. namespace RecycleRobo
  7. {
  8. public class RotatedRectangle
  9. {
  10. public static bool IntersectPixels(
  11. Matrix transformA, int widthA, int heightA, Color[] dataA,
  12. Matrix transformB, int widthB, int heightB, Color[] dataB)
  13. {
  14. // Calculate a matrix which transforms from A's local space into
  15. // world space and then into B's local space
  16. Matrix transformAToB = transformA * Matrix.Invert(transformB);
  17. // When a point moves in A's local space, it moves in B's local space with a
  18. // fixed direction and distance proportional to the movement in A.
  19. // This algorithm steps through A one pixel at a time along A's X and Y axes
  20. // Calculate the analogous steps in B
  21. Vector2 stepX = Vector2.TransformNormal(Vector2.UnitX, transformAToB);
  22. Vector2 stepY = Vector2.TransformNormal(Vector2.UnitY, transformAToB);
  23. // Calculate the top left corner of A in B's local space
  24. // This variable will be reused to keep track of the start of each row
  25. Vector2 yPosInB = Vector2.Transform(Vector2.Zero, transformAToB);
  26. // For each row of pixels in A
  27. for (int yA = 0; yA < heightA; yA++)
  28. {
  29. // Start at the beginning of the row
  30. Vector2 posInB = yPosInB;
  31. // For each pixel in this row
  32. for (int xA = 0; xA < widthA; xA++)
  33. {
  34. // Round to the nearest pixel
  35. int xB = (int)Math.Round(posInB.X);
  36. int yB = (int)Math.Round(posInB.Y);
  37. // If the pixel lies within the bounds of B
  38. if (0 <= xB && xB < widthB &&
  39. 0 <= yB && yB < heightB)
  40. {
  41. // Get the colors of the overlapping pixels
  42. Color colorA = dataA[xA + yA * widthA];
  43. Color colorB = dataB[xB + yB * widthB];
  44. // If both pixels are not completely transparent,
  45. if (colorB.A != 0 && colorA.A != 0)
  46. {
  47. // then an intersection has been found
  48. return true;
  49. }
  50. }
  51. posInB += stepX;
  52. }
  53. yPosInB += stepY;
  54. }
  55. return false;
  56. }
  57. public static Matrix GetMatrixTransfrom(Vector2 vector,Vector2 origin, float rotation, float scale)
  58. {
  59. Matrix transform =
  60. Matrix.CreateTranslation(new Vector3(-origin, 0.0f)) *
  61. Matrix.CreateRotationZ(rotation) *
  62. Matrix.CreateScale(scale) *
  63. Matrix.CreateTranslation(new Vector3(vector, 0.0f));
  64. return transform;
  65. }
  66. public static Rectangle CalculateBoundingRectangle(Rectangle rectangle,Matrix transform)
  67. {
  68. Vector2 leftTop = new Vector2(rectangle.Left, rectangle.Top);
  69. Vector2 rightTop = new Vector2(rectangle.Right, rectangle.Top);
  70. Vector2 leftBottom = new Vector2(rectangle.Left, rectangle.Bottom);
  71. Vector2 rightBottom = new Vector2(rectangle.Right, rectangle.Bottom);
  72. Vector2.Transform(ref leftTop, ref transform, out leftTop);
  73. Vector2.Transform(ref rightTop, ref transform, out rightTop);
  74. Vector2.Transform(ref leftBottom, ref transform, out leftBottom);
  75. Vector2.Transform(ref rightBottom, ref transform, out rightBottom);
  76. Vector2 min = Vector2.Min(Vector2.Min(leftTop, rightTop),
  77. Vector2.Min(leftBottom, rightBottom));
  78. Vector2 max = Vector2.Max(Vector2.Max(leftTop, rightTop),
  79. Vector2.Max(leftBottom, rightBottom));
  80. return new Rectangle((int)min.X, (int)min.Y,
  81. (int)(max.X - min.X), (int)(max.Y - min.Y));
  82. }
  83. }
  84. }