ImathSphere.h 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. //
  2. // SPDX-License-Identifier: BSD-3-Clause
  3. // Copyright Contributors to the OpenEXR Project.
  4. //
  5. //
  6. // A 3D sphere class template
  7. //
  8. #ifndef INCLUDED_IMATHSPHERE_H
  9. #define INCLUDED_IMATHSPHERE_H
  10. #include "ImathExport.h"
  11. #include "ImathNamespace.h"
  12. #include "ImathBox.h"
  13. #include "ImathLine.h"
  14. #include "ImathVec.h"
  15. IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
  16. ///
  17. /// A 3D sphere
  18. ///
  19. template <class T> class IMATH_EXPORT_TEMPLATE_TYPE Sphere3
  20. {
  21. public:
  22. /// @{
  23. /// @name Direct access to member fields
  24. /// Center
  25. Vec3<T> center;
  26. /// Radius
  27. T radius;
  28. /// @}
  29. /// @{
  30. /// @name Constructors
  31. /// Default is center at (0,0,0) and radius of 0.
  32. IMATH_HOSTDEVICE constexpr Sphere3() : center (0, 0, 0), radius (0) {}
  33. /// Initialize to a given center and radius
  34. IMATH_HOSTDEVICE constexpr Sphere3 (const Vec3<T>& c, T r) : center (c), radius (r) {}
  35. /// @}
  36. /// @{
  37. /// @name Manipulation
  38. /// Set the center and radius of the sphere so that it tightly
  39. /// encloses Box b.
  40. IMATH_HOSTDEVICE void circumscribe (const Box<Vec3<T>>& box);
  41. /// @}
  42. /// @{
  43. /// @name Utility Methods
  44. /// If the sphere and line `l` intersect, then compute the
  45. /// smallest `t` with `t>=0` so that `l(t)` is a point on the sphere.
  46. ///
  47. /// @param[in] l The line
  48. /// @param[out] intersection The point of intersection
  49. /// @return True if the sphere and line intersect, false if they
  50. /// do not.
  51. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool
  52. intersect (const Line3<T>& l, Vec3<T>& intersection) const;
  53. /// If the sphere and line `l` intersect, then compute the
  54. /// smallest `t` with `t>=0` so that `l(t)` is a point on the sphere.
  55. ///
  56. /// @param[in] l The line
  57. /// @param[out] t The parameter of the line at the intersection point
  58. /// @return True if the sphere and line intersect, false if they
  59. /// do not.
  60. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool intersectT (const Line3<T>& l, T& t) const;
  61. /// @}
  62. };
  63. /// Sphere of type float
  64. typedef Sphere3<float> Sphere3f;
  65. /// Sphere of type double
  66. typedef Sphere3<double> Sphere3d;
  67. //---------------
  68. // Implementation
  69. //---------------
  70. template <class T>
  71. IMATH_HOSTDEVICE inline void
  72. Sphere3<T>::circumscribe (const Box<Vec3<T>>& box)
  73. {
  74. center = T (0.5) * (box.min + box.max);
  75. radius = (box.max - center).length();
  76. }
  77. template <class T>
  78. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool
  79. Sphere3<T>::intersectT (const Line3<T>& line, T& t) const
  80. {
  81. bool doesIntersect = true;
  82. Vec3<T> v = line.pos - center;
  83. T B = T (2.0) * (line.dir ^ v);
  84. T C = (v ^ v) - (radius * radius);
  85. // compute discriminant
  86. // if negative, there is no intersection
  87. T discr = B * B - T (4.0) * C;
  88. if (discr < 0.0)
  89. {
  90. // line and Sphere3 do not intersect
  91. doesIntersect = false;
  92. }
  93. else
  94. {
  95. // t0: (-B - sqrt(B^2 - 4AC)) / 2A (A = 1)
  96. T sqroot = std::sqrt (discr);
  97. t = (-B - sqroot) * T (0.5);
  98. if (t < 0.0)
  99. {
  100. // no intersection, try t1: (-B + sqrt(B^2 - 4AC)) / 2A (A = 1)
  101. t = (-B + sqroot) * T (0.5);
  102. }
  103. if (t < 0.0)
  104. doesIntersect = false;
  105. }
  106. return doesIntersect;
  107. }
  108. template <class T>
  109. IMATH_CONSTEXPR14 bool
  110. Sphere3<T>::intersect (const Line3<T>& line, Vec3<T>& intersection) const
  111. {
  112. T t (0);
  113. if (intersectT (line, t))
  114. {
  115. intersection = line (t);
  116. return true;
  117. }
  118. else
  119. {
  120. return false;
  121. }
  122. }
  123. IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
  124. #endif // INCLUDED_IMATHSPHERE_H