ImathPlane.h 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. //
  2. // SPDX-License-Identifier: BSD-3-Clause
  3. // Copyright Contributors to the OpenEXR Project.
  4. //
  5. //
  6. // A 3D plane class template
  7. //
  8. #ifndef INCLUDED_IMATHPLANE_H
  9. #define INCLUDED_IMATHPLANE_H
  10. #include "ImathExport.h"
  11. #include "ImathNamespace.h"
  12. #include "ImathLine.h"
  13. #include "ImathVec.h"
  14. IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
  15. ///
  16. /// The `Plane3` class represents a half space in 3D, so the normal
  17. /// may point either towards or away from origin. The plane `P` can
  18. /// be represented by Plane3 as either `p` or `-p` corresponding to
  19. /// the two half-spaces on either side of the plane. Any function
  20. /// which computes a distance will return either negative or positive
  21. /// values for the distance indicating which half-space the point is
  22. /// in. Note that reflection, and intersection functions will operate
  23. /// as expected.
  24. template <class T> class IMATH_EXPORT_TEMPLATE_TYPE Plane3
  25. {
  26. public:
  27. /// @{
  28. /// @name Direct access to member fields
  29. /// The normal to the plane
  30. Vec3<T> normal;
  31. /// The distance from the origin to the plane
  32. T distance;
  33. /// @}
  34. /// @{
  35. /// @name Constructors
  36. /// Uninitialized by default
  37. IMATH_HOSTDEVICE Plane3() IMATH_NOEXCEPT {}
  38. /// Initialize with a normal and distance
  39. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Plane3 (const Vec3<T>& normal, T distance) IMATH_NOEXCEPT;
  40. /// Initialize with a point and a normal
  41. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Plane3 (const Vec3<T>& point, const Vec3<T>& normal) IMATH_NOEXCEPT;
  42. /// Initialize with three points
  43. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Plane3 (const Vec3<T>& point1,
  44. const Vec3<T>& point2,
  45. const Vec3<T>& point3) IMATH_NOEXCEPT;
  46. /// @}
  47. /// @{
  48. /// @name Manipulation
  49. /// Set via a given normal and distance
  50. IMATH_HOSTDEVICE void set (const Vec3<T>& normal, T distance) IMATH_NOEXCEPT;
  51. /// Set via a given point and normal
  52. IMATH_HOSTDEVICE void set (const Vec3<T>& point, const Vec3<T>& normal) IMATH_NOEXCEPT;
  53. /// Set via three points
  54. IMATH_HOSTDEVICE void set (const Vec3<T>& point1, const Vec3<T>& point2, const Vec3<T>& point3) IMATH_NOEXCEPT;
  55. /// @}
  56. /// @{
  57. /// @name Utility Methods
  58. /// Determine if a line intersects the plane.
  59. /// @param line The line
  60. /// @param[out] intersection The point of intersection
  61. /// @return True if the line intersects the plane.
  62. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool
  63. intersect (const Line3<T>& line, Vec3<T>& intersection) const IMATH_NOEXCEPT;
  64. /// Determine if a line intersects the plane.
  65. /// @param line The line
  66. /// @param[out] parameter The parametric value of the point of intersection
  67. /// @return True if the line intersects the plane.
  68. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool intersectT (const Line3<T>& line, T& parameter) const IMATH_NOEXCEPT;
  69. /// Return the distance from a point to the plane.
  70. IMATH_HOSTDEVICE constexpr T distanceTo (const Vec3<T>& point) const IMATH_NOEXCEPT;
  71. /// Reflect the given point around the plane.
  72. IMATH_HOSTDEVICE constexpr Vec3<T> reflectPoint (const Vec3<T>& point) const IMATH_NOEXCEPT;
  73. /// Reflect the direction vector around the plane
  74. IMATH_HOSTDEVICE constexpr Vec3<T> reflectVector (const Vec3<T>& vec) const IMATH_NOEXCEPT;
  75. /// @}
  76. };
  77. /// Plane of type float
  78. typedef Plane3<float> Plane3f;
  79. /// Plane of type double
  80. typedef Plane3<double> Plane3d;
  81. //---------------
  82. // Implementation
  83. //---------------
  84. template <class T>
  85. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline Plane3<T>::Plane3 (const Vec3<T>& p0, const Vec3<T>& p1, const Vec3<T>& p2) IMATH_NOEXCEPT
  86. {
  87. set (p0, p1, p2);
  88. }
  89. template <class T>
  90. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline Plane3<T>::Plane3 (const Vec3<T>& n, T d) IMATH_NOEXCEPT
  91. {
  92. set (n, d);
  93. }
  94. template <class T>
  95. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline Plane3<T>::Plane3 (const Vec3<T>& p, const Vec3<T>& n) IMATH_NOEXCEPT
  96. {
  97. set (p, n);
  98. }
  99. template <class T>
  100. IMATH_HOSTDEVICE inline void
  101. Plane3<T>::set (const Vec3<T>& point1, const Vec3<T>& point2, const Vec3<T>& point3) IMATH_NOEXCEPT
  102. {
  103. normal = (point2 - point1) % (point3 - point1);
  104. normal.normalize();
  105. distance = normal ^ point1;
  106. }
  107. template <class T>
  108. IMATH_HOSTDEVICE inline void
  109. Plane3<T>::set (const Vec3<T>& point, const Vec3<T>& n) IMATH_NOEXCEPT
  110. {
  111. normal = n;
  112. normal.normalize();
  113. distance = normal ^ point;
  114. }
  115. template <class T>
  116. IMATH_HOSTDEVICE inline void
  117. Plane3<T>::set (const Vec3<T>& n, T d) IMATH_NOEXCEPT
  118. {
  119. normal = n;
  120. normal.normalize();
  121. distance = d;
  122. }
  123. template <class T>
  124. IMATH_HOSTDEVICE constexpr inline T
  125. Plane3<T>::distanceTo (const Vec3<T>& point) const IMATH_NOEXCEPT
  126. {
  127. return (point ^ normal) - distance;
  128. }
  129. template <class T>
  130. IMATH_HOSTDEVICE constexpr inline Vec3<T>
  131. Plane3<T>::reflectPoint (const Vec3<T>& point) const IMATH_NOEXCEPT
  132. {
  133. return normal * distanceTo (point) * -2.0 + point;
  134. }
  135. template <class T>
  136. IMATH_HOSTDEVICE constexpr inline Vec3<T>
  137. Plane3<T>::reflectVector (const Vec3<T>& v) const IMATH_NOEXCEPT
  138. {
  139. return normal * (normal ^ v) * 2.0 - v;
  140. }
  141. template <class T>
  142. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline bool
  143. Plane3<T>::intersect (const Line3<T>& line, Vec3<T>& point) const IMATH_NOEXCEPT
  144. {
  145. T d = normal ^ line.dir;
  146. if (d == 0.0)
  147. return false;
  148. T t = -((normal ^ line.pos) - distance) / d;
  149. point = line (t);
  150. return true;
  151. }
  152. template <class T>
  153. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline bool
  154. Plane3<T>::intersectT (const Line3<T>& line, T& t) const IMATH_NOEXCEPT
  155. {
  156. T d = normal ^ line.dir;
  157. if (d == 0.0)
  158. return false;
  159. t = -((normal ^ line.pos) - distance) / d;
  160. return true;
  161. }
  162. /// Stream output, as "(normal distance)"
  163. template <class T>
  164. std::ostream&
  165. operator<< (std::ostream& o, const Plane3<T>& plane)
  166. {
  167. return o << "(" << plane.normal << ", " << plane.distance << ")";
  168. }
  169. /// Transform a plane by a matrix
  170. template <class T>
  171. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Plane3<T>
  172. operator* (const Plane3<T>& plane, const Matrix44<T>& M) IMATH_NOEXCEPT
  173. {
  174. // T
  175. // -1
  176. // Could also compute M but that would suck.
  177. //
  178. Vec3<T> dir1 = Vec3<T> (1, 0, 0) % plane.normal;
  179. T dir1Len = dir1 ^ dir1;
  180. Vec3<T> tmp = Vec3<T> (0, 1, 0) % plane.normal;
  181. T tmpLen = tmp ^ tmp;
  182. if (tmpLen > dir1Len)
  183. {
  184. dir1 = tmp;
  185. dir1Len = tmpLen;
  186. }
  187. tmp = Vec3<T> (0, 0, 1) % plane.normal;
  188. tmpLen = tmp ^ tmp;
  189. if (tmpLen > dir1Len)
  190. {
  191. dir1 = tmp;
  192. }
  193. Vec3<T> dir2 = dir1 % plane.normal;
  194. Vec3<T> point = plane.distance * plane.normal;
  195. return Plane3<T> (point * M, (point + dir2) * M, (point + dir1) * M);
  196. }
  197. /// Reflect the pla
  198. template <class T>
  199. IMATH_HOSTDEVICE constexpr inline Plane3<T>
  200. operator- (const Plane3<T>& plane) IMATH_NOEXCEPT
  201. {
  202. return Plane3<T> (-plane.normal, -plane.distance);
  203. }
  204. IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
  205. #endif // INCLUDED_IMATHPLANE_H