Sphere.pkg 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. $#include "Sphere.h"
  2. /// %Sphere in three-dimensional space.
  3. class Sphere
  4. {
  5. public:
  6. /// Construct undefined.
  7. Sphere() :
  8. center_(Vector3::ZERO),
  9. radius_(0.0f),
  10. defined_(false)
  11. {
  12. }
  13. /// Copy-construct from another sphere.
  14. Sphere(const Sphere& sphere) :
  15. center_(sphere.center_),
  16. radius_(sphere.radius_),
  17. defined_(sphere.defined_)
  18. {
  19. }
  20. /// Construct from center and radius.
  21. Sphere(const Vector3& center, float radius) :
  22. center_(center),
  23. radius_(radius),
  24. defined_(true)
  25. {
  26. }
  27. /// Construct from an array of vertices.
  28. Sphere(const Vector3* vertices, unsigned count) :
  29. defined_(false)
  30. {
  31. Define(vertices, count);
  32. }
  33. /// Construct from a bounding box.
  34. Sphere(const BoundingBox& box) :
  35. defined_(false)
  36. {
  37. Define(box);
  38. }
  39. /// Construct from a frustum.
  40. Sphere(const Frustum& frustum) :
  41. defined_(false)
  42. {
  43. Define(frustum);
  44. }
  45. /// Construct from a polyhedron.
  46. Sphere(const Polyhedron& poly) :
  47. defined_(false)
  48. {
  49. Define(poly);
  50. }
  51. /// Test for equality with another sphere.
  52. bool operator == (const Sphere& rhs) const { return center_ == rhs.center_ && radius_ == rhs.radius_; }
  53. /// Define from another sphere.
  54. void Define(const Sphere& sphere)
  55. {
  56. Define(sphere.center_, sphere.radius_);
  57. }
  58. /// Define from center and radius.
  59. void Define(const Vector3& center, float radius)
  60. {
  61. center_ = center;
  62. radius_ = radius;
  63. defined_ = true;
  64. }
  65. /// Define from an array of vertices.
  66. void Define(const Vector3* vertices, unsigned count);
  67. /// Define from a bounding box.
  68. void Define(const BoundingBox& box);
  69. /// Define from a frustum.
  70. void Define(const Frustum& frustum);
  71. /// Define from a polyhedron.
  72. void Define(const Polyhedron& poly);
  73. /// Merge a point.
  74. void Merge(const Vector3& point)
  75. {
  76. if (!defined_)
  77. {
  78. center_ = point;
  79. radius_ = 0.0f;
  80. defined_ = true;
  81. return;
  82. }
  83. Vector3 offset = point - center_;
  84. float dist = offset.Length();
  85. if (dist > radius_)
  86. {
  87. float half = (dist - radius_) * 0.5f;
  88. radius_ += half;
  89. center_ += (half / dist) * offset;
  90. }
  91. }
  92. /// Merge an array of vertices.
  93. void Merge(const Vector3* vertices, unsigned count);
  94. /// Merge a bounding box.
  95. void Merge(const BoundingBox& box);
  96. /// Merge a frustum.
  97. void Merge(const Frustum& frustum);
  98. /// Merge a polyhedron.
  99. void Merge(const Polyhedron& poly);
  100. /// Merge a sphere.
  101. void Merge(const Sphere& sphere);
  102. /// Clear to undefined state.
  103. void Clear()
  104. {
  105. center_ = Vector3::ZERO;
  106. radius_ = 0.0f;
  107. defined_ = false;
  108. }
  109. /// Test if a point is inside.
  110. Intersection IsInside(const Vector3& point) const
  111. {
  112. float distSquared = (point - center_).LengthSquared();
  113. if (distSquared < radius_ * radius_)
  114. return INSIDE;
  115. else
  116. return OUTSIDE;
  117. }
  118. /// Test if another sphere is inside, outside or intersects.
  119. Intersection IsInside(const Sphere& sphere) const
  120. {
  121. float dist = (sphere.center_ - center_).Length();
  122. if (dist >= sphere.radius_ + radius_)
  123. return OUTSIDE;
  124. else if (dist + sphere.radius_ < radius_)
  125. return INSIDE;
  126. else
  127. return INTERSECTS;
  128. }
  129. /// Test if another sphere is (partially) inside or outside.
  130. Intersection IsInsideFast(const Sphere& sphere) const
  131. {
  132. float distSquared = (sphere.center_ - center_).LengthSquared();
  133. float combined = sphere.radius_ + radius_;
  134. if (distSquared >= combined * combined)
  135. return OUTSIDE;
  136. else
  137. return INSIDE;
  138. }
  139. /// Test if a bounding box is inside, outside or intersects.
  140. Intersection IsInside(const BoundingBox& box) const;
  141. /// Test if a bounding box is (partially) inside or outside.
  142. Intersection IsInsideFast(const BoundingBox& box) const;
  143. /// Return distance of a point to the surface, or 0 if inside.
  144. float Distance(const Vector3& point) const { return Max((point - center_).Length() - radius_, 0.0f); }
  145. /// Sphere center.
  146. Vector3 center_ @ center;
  147. /// Sphere radius.
  148. float radius_ @ radius;
  149. };