TrinityCore
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
G3D::LineSegment2D Class Reference

#include <LineSegment.h>

Public Member Functions

 LineSegment2D ()
 
Point2 intersection (const LineSegment2D &other) const
 
Point2 point (int i) const
 
Point2 closestPoint (const Point2 &Q) const
 
float distance (const Point2 &p) const
 
float length () const
 

Static Public Member Functions

static LineSegment2D fromTwoPoints (const Point2 &p0, const Vector2 &p1)
 

Private Attributes

Point2 m_origin
 
Vector2 m_direction
 
float m_length
 

Constructor & Destructor Documentation

G3D::LineSegment2D::LineSegment2D ( )
inline
99 {}

Member Function Documentation

Vector2 G3D::LineSegment2D::closestPoint ( const Point2 Q) const
125  {
126  // Two constants that appear in the result
127  const Vector2 k1(m_origin - Q);
128  const Vector2& k2 = m_direction;
129 
130  if (fuzzyEq(m_length, 0)) {
131  // This line segment has no length
132  return m_origin;
133  }
134 
135  // Time [0, 1] at which we hit the closest point travelling from p0 to p1.
136  // Derivation can be obtained by minimizing the expression
137  // ||P0 + (P1 - P0)t - Q||.
138  const float t = -k1.dot(k2) / (m_length * m_length);
139 
140  if (t < 0) {
141  // Clipped to low end point
142  return m_origin;
143  } else if (t > 1) {
144  // Clipped to high end point
145  return m_origin + m_direction;
146  } else {
147  // Subsitute into the line equation to find
148  // the point on the segment.
149  return m_origin + k2 * t;
150  }
151 }
Vector2 m_direction
Definition: LineSegment.h:92
Point2 m_origin
Definition: LineSegment.h:89
float m_length
Definition: LineSegment.h:95
bool fuzzyEq(double a, double b)
Definition: g3dmath.h:857
uint8 const Q[]
Definition: AuthenticationPackets.cpp:237
float dot(const Vector2 &s) const
Definition: Vector2.h:446

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

float G3D::LineSegment2D::distance ( const Point2 p) const
154  {
155  Vector2 closest = closestPoint(p);
156  return (closest - p).length();
157 }
Point2 closestPoint(const Point2 &Q) const
Definition: LineSegment.cpp:125

+ Here is the call graph for this function:

LineSegment2D G3D::LineSegment2D::fromTwoPoints ( const Point2 p0,
const Vector2 p1 
)
static
106  {
107  LineSegment2D s;
108  s.m_origin = p0;
109  s.m_direction = p1 - p0;
110  s.m_length = s.m_direction.length();
111  return s;
112 }
LineSegment2D()
Definition: LineSegment.h:99

+ Here is the call graph for this function:

Vector2 G3D::LineSegment2D::intersection ( const LineSegment2D other) const

Returns the intersection of these segements (including testing endpoints), or Point2::inf() if they do not intersect.

165  {
166 
167  if ((m_origin == other.m_origin) ||
168  (m_origin == other.m_origin + other.m_direction)) {
169  return m_origin;
170  }
171 
172  if (m_origin + m_direction == other.m_origin) {
173  return other.m_origin;
174  }
175 
176  // Note: Now that we've checked the endpoints, all other parallel lines can now be assumed
177  // to not intersect (within numerical precision)
178 
179  Vector2 dir1 = m_direction;
180  Vector2 dir2 = other.m_direction;
181  Vector2 origin1 = m_origin;
182  Vector2 origin2 = other.m_origin;
183 
184  if (dir1.x == 0) {
185  // Avoid an upcoming divide by zero
186  dir1 = dir1.yx();
187  dir2 = dir2.yx();
188  origin1 = origin1.yx();
189  origin2 = origin2.yx();
190  }
191 
192  // t1 = ((other.m_origin.x - m_origin.x) + other.m_direction.x * t2) / m_direction.x
193  //
194  // ((other.m_origin.x - m_origin.x) + other.m_direction.x * t2) * m_direction.y / m_direction.x =
195  // (other.m_origin.y - m_origin.y) + other.m_direction.y * t2
196  //
197  // m = m_direction.y / m_direction.x
198  // d = other.m_origin - m_origin
199  //
200  // (d.x + other.m_direction.x * t2) * m = d.y + other.m_direction.y * t2
201  //
202  // d.x * m + other.m_direction.x * m * t2 = d.y + other.m_direction.y * t2
203  //
204  // d.x * m - d.y = (other.m_direction.y - other.m_direction.x * m) * t2
205  //
206  // (d.x * m - d.y) / (other.m_direction.y - other.m_direction.x * m) = t2
207  //
208 
209  Vector2 d = origin2 - origin1;
210  float m = dir1.y / dir1.x;
211 
212  float t2 = (d.x * m - d.y) / (dir2.y - dir2.x * m);
213  if (! isFinite(t2)) {
214  // Parallel lines: no intersection
215  return Vector2::inf();
216  }
217 
218  if ((t2 < 0.0f) || (t2 > 1.0f)) {
219  // Intersection occurs past the end of the line segments
220  return Vector2::inf();
221  }
222 
223  float t1 = (d.x + dir2.x * t2) / dir1.x;
224  if ((t1 < 0.0f) || (t1 > 1.0f)) {
225  // Intersection occurs past the end of the line segments
226  return Vector2::inf();
227  }
228 
229  // Return the intersection point (computed from non-transposed
230  // variables even if we flipped above)
231  return m_origin + m_direction * t1;
232 
233 }
Vector2 yx() const
Definition: Vector2.cpp:182
Vector2 m_direction
Definition: LineSegment.h:92
Point2 m_origin
Definition: LineSegment.h:89
float y
Definition: Vector2.h:50
bool isFinite(double x)
Definition: g3dmath.h:525
static const Vector2 & inf()
Definition: Vector2.cpp:82

+ Here is the call graph for this function:

float G3D::LineSegment2D::length ( ) const
160  {
161  return m_length;
162 }
float m_length
Definition: LineSegment.h:95
Vector2 G3D::LineSegment2D::point ( int  i) const
115  {
116  debugAssert(i == 0 || i == 1);
117  if (i == 0) {
118  return m_origin;
119  } else {
120  return m_direction + m_origin;
121  }
122 }
Vector2 m_direction
Definition: LineSegment.h:92
Point2 m_origin
Definition: LineSegment.h:89
#define debugAssert(exp)
Definition: debugAssert.h:160

Member Data Documentation

Vector2 G3D::LineSegment2D::m_direction
private

Not normalized

float G3D::LineSegment2D::m_length
private

Length of m_direction

Point2 G3D::LineSegment2D::m_origin
private

The documentation for this class was generated from the following files: