ImathLine.h 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. //
  2. // SPDX-License-Identifier: BSD-3-Clause
  3. // Copyright Contributors to the OpenEXR Project.
  4. //
  5. //
  6. // A 3D line class template
  7. //
  8. #ifndef INCLUDED_IMATHLINE_H
  9. #define INCLUDED_IMATHLINE_H
  10. #include "ImathMatrix.h"
  11. #include "ImathNamespace.h"
  12. #include "ImathVec.h"
  13. IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
  14. ///
  15. /// The `Line3` class represents a 3D line, defined by a point and a
  16. /// direction vector.
  17. ///
  18. template <class T> class Line3
  19. {
  20. public:
  21. /// @{
  22. /// @name Direct access to member fields
  23. /// A point on the line
  24. Vec3<T> pos;
  25. /// The direction of the line
  26. Vec3<T> dir;
  27. /// @}
  28. /// @{
  29. /// @name Constructors
  30. /// Uninitialized by default
  31. IMATH_HOSTDEVICE constexpr Line3() IMATH_NOEXCEPT {}
  32. /// Initialize with two points. The direction is the difference
  33. /// between the points.
  34. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Line3 (const Vec3<T>& point1, const Vec3<T>& point2) IMATH_NOEXCEPT;
  35. /// @}
  36. /// @{
  37. /// @name Manipulation
  38. /// Set the line defined by two points. The direction is the difference
  39. /// between the points.
  40. IMATH_HOSTDEVICE void set (const Vec3<T>& point1, const Vec3<T>& point2) IMATH_NOEXCEPT;
  41. /// @}
  42. /// @{
  43. /// @name Utility Methods
  44. /// Return the point on the line at the given parameter value,
  45. /// e.g. L(t)
  46. IMATH_HOSTDEVICE constexpr Vec3<T> operator() (T parameter) const IMATH_NOEXCEPT;
  47. /// Return the distance to the given point
  48. IMATH_HOSTDEVICE constexpr T distanceTo (const Vec3<T>& point) const IMATH_NOEXCEPT;
  49. /// Return the distance to the given line
  50. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 T distanceTo (const Line3<T>& line) const IMATH_NOEXCEPT;
  51. /// Return the point on the line closest to the given point
  52. IMATH_HOSTDEVICE constexpr Vec3<T> closestPointTo (const Vec3<T>& point) const IMATH_NOEXCEPT;
  53. /// Return the point on the line closest to the given line
  54. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Vec3<T> closestPointTo (const Line3<T>& line) const IMATH_NOEXCEPT;
  55. /// @}
  56. };
  57. /// Line of type float
  58. typedef Line3<float> Line3f;
  59. /// Line of type double
  60. typedef Line3<double> Line3d;
  61. template <class T>
  62. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline Line3<T>::Line3 (const Vec3<T>& p0, const Vec3<T>& p1) IMATH_NOEXCEPT
  63. {
  64. set (p0, p1);
  65. }
  66. template <class T>
  67. IMATH_HOSTDEVICE inline void
  68. Line3<T>::set (const Vec3<T>& p0, const Vec3<T>& p1) IMATH_NOEXCEPT
  69. {
  70. pos = p0;
  71. dir = p1 - p0;
  72. dir.normalize();
  73. }
  74. template <class T>
  75. IMATH_HOSTDEVICE constexpr inline Vec3<T>
  76. Line3<T>::operator() (T parameter) const IMATH_NOEXCEPT
  77. {
  78. return pos + dir * parameter;
  79. }
  80. template <class T>
  81. IMATH_HOSTDEVICE constexpr inline T
  82. Line3<T>::distanceTo (const Vec3<T>& point) const IMATH_NOEXCEPT
  83. {
  84. return (closestPointTo (point) - point).length();
  85. }
  86. template <class T>
  87. IMATH_HOSTDEVICE constexpr inline Vec3<T>
  88. Line3<T>::closestPointTo (const Vec3<T>& point) const IMATH_NOEXCEPT
  89. {
  90. return ((point - pos) ^ dir) * dir + pos;
  91. }
  92. template <class T>
  93. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline T
  94. Line3<T>::distanceTo (const Line3<T>& line) const IMATH_NOEXCEPT
  95. {
  96. T d = (dir % line.dir) ^ (line.pos - pos);
  97. return (d >= 0) ? d : -d;
  98. }
  99. template <class T>
  100. IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline Vec3<T>
  101. Line3<T>::closestPointTo (const Line3<T>& line) const IMATH_NOEXCEPT
  102. {
  103. // Assumes the lines are normalized
  104. Vec3<T> posLpos = pos - line.pos;
  105. T c = dir ^ posLpos;
  106. T a = line.dir ^ dir;
  107. T f = line.dir ^ posLpos;
  108. T num = c - a * f;
  109. T denom = a * a - 1;
  110. T absDenom = ((denom >= 0) ? denom : -denom);
  111. if (absDenom < 1)
  112. {
  113. T absNum = ((num >= 0) ? num : -num);
  114. if (absNum >= absDenom * std::numeric_limits<T>::max())
  115. return pos;
  116. }
  117. return pos + dir * (num / denom);
  118. }
  119. /// Stream output, as "(pos dir)"
  120. template <class T>
  121. std::ostream&
  122. operator<< (std::ostream& o, const Line3<T>& line)
  123. {
  124. return o << "(" << line.pos << ", " << line.dir << ")";
  125. }
  126. /// Transform a line by a matrix
  127. template <class S, class T>
  128. IMATH_HOSTDEVICE constexpr inline Line3<S>
  129. operator* (const Line3<S>& line, const Matrix44<T>& M) IMATH_NOEXCEPT
  130. {
  131. return Line3<S> (line.pos * M, (line.pos + line.dir) * M);
  132. }
  133. IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
  134. #endif // INCLUDED_IMATHLINE_H