line3d.h 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. // Copyright (C) 2002-2012 Nikolaus Gebhardt
  2. // This file is part of the "Irrlicht Engine".
  3. // For conditions of distribution and use, see copyright notice in irrlicht.h
  4. #ifndef __IRR_LINE_3D_H_INCLUDED__
  5. #define __IRR_LINE_3D_H_INCLUDED__
  6. #include "irrTypes.h"
  7. #include "vector3d.h"
  8. namespace irr
  9. {
  10. namespace core
  11. {
  12. //! 3D line between two points with intersection methods.
  13. template <class T>
  14. class line3d
  15. {
  16. public:
  17. //! Default constructor
  18. /** line from (0,0,0) to (1,1,1) */
  19. line3d() : start(0,0,0), end(1,1,1) {}
  20. //! Constructor with two points
  21. line3d(T xa, T ya, T za, T xb, T yb, T zb) : start(xa, ya, za), end(xb, yb, zb) {}
  22. //! Constructor with two points as vectors
  23. line3d(const vector3d<T>& start, const vector3d<T>& end) : start(start), end(end) {}
  24. // operators
  25. line3d<T> operator+(const vector3d<T>& point) const { return line3d<T>(start + point, end + point); }
  26. line3d<T>& operator+=(const vector3d<T>& point) { start += point; end += point; return *this; }
  27. line3d<T> operator-(const vector3d<T>& point) const { return line3d<T>(start - point, end - point); }
  28. line3d<T>& operator-=(const vector3d<T>& point) { start -= point; end -= point; return *this; }
  29. bool operator==(const line3d<T>& other) const
  30. { return (start==other.start && end==other.end) || (end==other.start && start==other.end);}
  31. bool operator!=(const line3d<T>& other) const
  32. { return !(start==other.start && end==other.end) || (end==other.start && start==other.end);}
  33. // functions
  34. //! Set this line to a new line going through the two points.
  35. void setLine(const T& xa, const T& ya, const T& za, const T& xb, const T& yb, const T& zb)
  36. {start.set(xa, ya, za); end.set(xb, yb, zb);}
  37. //! Set this line to a new line going through the two points.
  38. void setLine(const vector3d<T>& nstart, const vector3d<T>& nend)
  39. {start.set(nstart); end.set(nend);}
  40. //! Set this line to new line given as parameter.
  41. void setLine(const line3d<T>& line)
  42. {start.set(line.start); end.set(line.end);}
  43. //! Get length of line
  44. /** \return Length of line. */
  45. T getLength() const { return start.getDistanceFrom(end); }
  46. //! Get squared length of line
  47. /** \return Squared length of line. */
  48. T getLengthSQ() const { return start.getDistanceFromSQ(end); }
  49. //! Get middle of line
  50. /** \return Center of line. */
  51. vector3d<T> getMiddle() const
  52. {
  53. return (start + end)/(T)2;
  54. }
  55. //! Get vector of line
  56. /** \return vector of line. */
  57. vector3d<T> getVector() const
  58. {
  59. return end - start;
  60. }
  61. //! Check if the given point is between start and end of the line.
  62. /** Assumes that the point is already somewhere on the line.
  63. \param point The point to test.
  64. \return True if point is on the line between start and end, else false.
  65. */
  66. bool isPointBetweenStartAndEnd(const vector3d<T>& point) const
  67. {
  68. return point.isBetweenPoints(start, end);
  69. }
  70. //! Get the closest point on this line to a point
  71. /** \param point The point to compare to.
  72. \return The nearest point which is part of the line. */
  73. vector3d<T> getClosestPoint(const vector3d<T>& point) const
  74. {
  75. vector3d<T> c = point - start;
  76. vector3d<T> v = end - start;
  77. T d = (T)v.getLength();
  78. v /= d;
  79. T t = v.dotProduct(c);
  80. if (t < (T)0.0)
  81. return start;
  82. if (t > d)
  83. return end;
  84. v *= t;
  85. return start + v;
  86. }
  87. //! Check if the line intersects with a sphere
  88. /** \param sorigin: Origin of the sphere.
  89. \param sradius: Radius of the sphere.
  90. \param outdistance: The distance to the first intersection point.
  91. \return True if there is an intersection.
  92. If there is one, the distance to the first intersection point
  93. is stored in outdistance. */
  94. bool getIntersectionWithSphere(const vector3d<T>& sorigin, T sradius, f64& outdistance) const
  95. {
  96. const vector3d<T> q = sorigin - start;
  97. T c = q.getLength();
  98. T v = q.dotProduct(getVector().normalize());
  99. T d = sradius * sradius - (c*c - v*v);
  100. if (d < 0.0)
  101. return false;
  102. outdistance = v - core::squareroot ( d );
  103. return true;
  104. }
  105. // member variables
  106. //! Start point of line
  107. vector3d<T> start;
  108. //! End point of line
  109. vector3d<T> end;
  110. };
  111. //! Typedef for an f32 line.
  112. typedef line3d<f32> line3df;
  113. //! Typedef for an integer line.
  114. typedef line3d<s32> line3di;
  115. } // end namespace core
  116. } // end namespace irr
  117. #endif