Ellipse2D.cs 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. #if UNITY_EDITOR
  2. using UnityEngine;
  3. using System.Collections.Generic;
  4. namespace O3DWB
  5. {
  6. public struct Ellipse2D
  7. {
  8. #region Private Variables
  9. private Vector2 _center;
  10. private Vector2 _radii;
  11. #endregion
  12. #region Public Properties
  13. public Vector2 Center { get { return _center; } set { _center = value; } }
  14. public Vector2 Radii { get { return _radii; } set { _radii = value; } }
  15. public float RadiusX { get { return _radii.x; } set { _radii.x = value; } }
  16. public float RadiusY { get { return _radii.y; } set { _radii.y = value; } }
  17. #endregion
  18. #region Constructors
  19. public Ellipse2D(Vector2 center, Vector2 radii)
  20. {
  21. _center = center;
  22. _radii = radii;
  23. }
  24. public Ellipse2D(Vector2 center, float radiusX, float radiusY)
  25. {
  26. _center = center;
  27. _radii = new Vector2(radiusX, radiusY);
  28. }
  29. public Ellipse2D(Rect enclosingRectangle)
  30. {
  31. _center = enclosingRectangle.center;
  32. _radii = new Vector2(enclosingRectangle.width * 0.5f, enclosingRectangle.height * 0.5f);
  33. }
  34. public Ellipse2D(Circle2D circle)
  35. {
  36. _center = circle.Center;
  37. _radii = new Vector2(circle.Radius, circle.Radius);
  38. }
  39. #endregion
  40. #region Public Methods
  41. public bool OverlapsRectangle(Rect rectangle)
  42. {
  43. if (ContainsAnyPoint(rectangle.GetCenterAndCornerPoints())) return true;
  44. if (rectangle.ContainsAnyPoint(GetExtentsPoints())) return true;
  45. if (IntersectsAnyRay(rectangle.GetEdgeRays())) return true;
  46. return false;
  47. }
  48. public bool ContainsRectangle(Rect rectangle)
  49. {
  50. return ContainsAllPoints(rectangle.GetCornerPoints());
  51. }
  52. public bool ContainsAllPoints(List<Vector2> points)
  53. {
  54. Vector2 invRadii = new Vector2(1.0f / Radii.x, 1.0f / Radii.y);
  55. Circle2D circle = new Circle2D(Vector2.Scale(Center, invRadii), 1.0f);
  56. foreach (Vector2 point in points)
  57. {
  58. Vector2 adjustedPoint = Vector2.Scale(point, invRadii);
  59. if (!circle.ContainsPoint(adjustedPoint)) return false;
  60. }
  61. return true;
  62. }
  63. public bool ContainsAnyPoint(List<Vector2> points)
  64. {
  65. Vector2 invRadii = new Vector2(1.0f / Radii.x, 1.0f / Radii.y);
  66. Circle2D circle = new Circle2D(Vector2.Scale(Center, invRadii), 1.0f);
  67. foreach (Vector2 point in points)
  68. {
  69. Vector2 adjustedPoint = Vector2.Scale(point, invRadii);
  70. if (circle.ContainsPoint(adjustedPoint)) return true;
  71. }
  72. return false;
  73. }
  74. public bool ContainsPoint(Vector2 point)
  75. {
  76. Vector2 invRadii = new Vector2(1.0f / Radii.x, 1.0f / Radii.y);
  77. Circle2D circle = new Circle2D(Vector2.Scale(Center, invRadii), 1.0f);
  78. Vector2 adjustedPoint = Vector2.Scale(point, invRadii);
  79. return circle.ContainsPoint(adjustedPoint);
  80. }
  81. public bool IntersectsAnyRay(List<Ray2D> rays)
  82. {
  83. foreach(Ray2D ray in rays)
  84. {
  85. if (IntersectsRay(ray)) return true;
  86. }
  87. return false;
  88. }
  89. public bool IntersectsRay(Ray2D ray, out float t)
  90. {
  91. Vector2 invRadii = new Vector2(1.0f / Radii.x, 1.0f / Radii.y);
  92. Ray2D adjustedRay = new Ray2D(Vector2.Scale(ray.Origin, invRadii), Vector2.Scale(ray.Direction, invRadii));
  93. Circle2D circle = new Circle2D(Vector2.Scale(Center, invRadii), 1.0f);
  94. return circle.Raycast(adjustedRay, out t);
  95. }
  96. public bool IntersectsRay(Ray2D ray)
  97. {
  98. float t;
  99. return IntersectsRay(ray, out t);
  100. }
  101. public List<Vector2> GetExtentsPoints()
  102. {
  103. // Return the extent points in the following format: top, right, bottom, left.
  104. return new List<Vector2>
  105. {
  106. _center + new Vector2(0.0f, _radii.y),
  107. _center + new Vector2(_radii.x, 0.0f),
  108. _center + new Vector2(0.0f, -_radii.y),
  109. _center + new Vector2(-_radii.x, 0.0f)
  110. };
  111. }
  112. public Vector3 GetWorldCenterPointInFrontOfCamera(Camera camera, float distanceFromCamNearPlane)
  113. {
  114. return _center.GetWorldPointInFrontOfCamera(camera, distanceFromCamNearPlane);
  115. }
  116. public List<Vector3> GetWorldExtentPointsInFrontOfCamera(Camera camera, float distanceFromCamNearPlane)
  117. {
  118. List<Vector2> extentPoints = GetExtentsPoints();
  119. return Vector2Extensions.GetWorldPointsInFrontOfCamera(extentPoints, camera, distanceFromCamNearPlane);
  120. }
  121. public List<Vector3> GetWorldBorderLinesInFrontOfCamera(Camera camera, float distanceFromCamNearPlane, int numberOfEllipseSlices)
  122. {
  123. List<Vector3> worldExtentPoints = GetWorldExtentPointsInFrontOfCamera(camera, distanceFromCamNearPlane);
  124. Vector3 worldCenterPoint = GetWorldCenterPointInFrontOfCamera(camera, distanceFromCamNearPlane);
  125. Vector3 ellipseUp = worldExtentPoints[0] - worldCenterPoint;
  126. Vector3 ellipseRight = worldExtentPoints[1] - worldCenterPoint;
  127. float radiusX = ellipseRight.magnitude;
  128. float radiusY = ellipseUp.magnitude;
  129. ellipseUp.Normalize();
  130. ellipseRight.Normalize();
  131. return Vector3Extensions.Get3DEllipseCircumferencePoints(radiusX, radiusY, ellipseRight, ellipseUp, worldCenterPoint, numberOfEllipseSlices);
  132. }
  133. public bool FullyContainsOrientedBoxCenterAndCornerPointsInScreenSpace(OrientedBox orientedBox, Camera camera)
  134. {
  135. List<Vector2> boxCenterAndCornerScreenPoints = orientedBox.GetScreenCenterAndCornerPoints(camera);
  136. return ContainsAllPoints(boxCenterAndCornerScreenPoints);
  137. }
  138. #endregion
  139. }
  140. }
  141. #endif