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