Ocular Engine
LineSegment2D.hpp
1 
17 #pragma once
18 #ifndef __H__OCULAR_MATH_LINE_SEGMENT_2D__H__
19 #define __H__OCULAR_MATH_LINE_SEGMENT_2D__H__
20 
21 #include "Math/MathCommon.hpp"
22 #include "Math/Equality.hpp"
23 #include "Math/Vector2.hpp"
24 
25 //------------------------------------------------------------------------------------------
26 
31 namespace Ocular
32 {
37  namespace Math
38  {
39  enum LineSegmentSide
40  {
41  RightOfSegment = -1,
42  OnSegment = 0,
43  LeftOfSegment = 1
44  };
45 
51  template<typename T>
53  {
54  public:
55 
62  LineSegment2D(Vector2<T> const& a, Vector2<T> const& b)
63  {
64  m_A = a;
65  m_B = b;
66 
67  updateLength();
68  }
69 
71  {
72  m_Length = static_cast<T>(0);
73  m_LengthSquared = static_cast<T>(0);
74  }
75 
76  ~LineSegment2D()
77  {
78 
79  }
80 
81  Vector2<T> const& getA() const
82  {
83  return m_A;
84  }
85 
86  Vector2<T> const& getB() const
87  {
88  return m_B;
89  }
90 
91  void setA(Vector2<T> const& a)
92  {
93  m_A = a;
94  updateLength();
95  }
96 
97  void setB(Vector2<T> const& b)
98  {
99  m_B = b;
100  updateLength();
101  }
102 
106  T const& getLength() const
107  {
108  return m_Length;
109  }
110 
114  T const& getLengthSquared() const
115  {
116  return m_LengthSquared;
117  }
118 
131  LineSegmentSide whichSide(Vector2<T> const& point) const
132  {
133  LineSegmentSide result;
134  const T value = ((m_B.x - m_A.x) * (point.y - m_A.y)) - ((m_B.y - m_A.y) * (point.x - m_A.x));
135 
136  if(IsZero<T>(value))
137  {
138  result = OnSegment;
139  }
140  else
141  {
142  result = (value < static_cast<T>(0)) ? RightOfSegment : LeftOfSegment;
143  }
144 
145  return result;
146  }
147 
156  T distanceTo(Vector2<T> const& point) const
157  {
158  T result;
159 
160  if(IsZero<T>(m_LengthSquared))
161  {
162  const Vector2<T> pointToA = point - m_A;
163  result = pointToA.getLength();
164  }
165  else
166  {
167  const Vector2<T> pointToA = point - m_A;
168  const Vector2<T> pointToB = point - m_B;
169  const Vector2<T> bToA = m_B - m_A;
170 
171  const T t = pointToA.dot(bToA) / m_LengthSquared;
172 
173  if(t < static_cast<T>(0))
174  {
175  result = pointToA.getLength();
176  }
177  else if(t > static_cast<T>(1))
178  {
179  result = pointToB.getLength();
180  }
181  else
182  {
183  const Vector2<T> projection = m_A + ((m_B - m_A) * t);
184  const Vector2<T> vector = point - projection;
185 
186  result = vector.getLength();
187  }
188  }
189 
190  return result;
191  }
192 
193  protected:
194 
195  void updateLength()
196  {
197  const Vector2<T> vector = m_B - m_A;
198 
199  m_Length = vector.getLength();
200  m_LengthSquared = m_Length * m_Length;
201  }
202 
203  private:
204 
205  Vector2<T> m_A;
206  Vector2<T> m_B;
207 
208  T m_Length;
209  T m_LengthSquared;
210  };
211 
212  //--------------------------------------------
213  // Common formats
214 
215  typedef LineSegment2D<float> LineSegment2Df;
216  typedef LineSegment2D<double> LineSegment2Dd;
217  }
221 }
226 //------------------------------------------------------------------------------------------
227 
228 #endif
T getLength() const
Definition: Vector2.hpp:199
T const & getLengthSquared() const
Definition: LineSegment2D.hpp:114
Definition: LineSegment2D.hpp:52
Note: Once this library is made dynamic, this will no longer be needed.
Definition: Common.hpp:70
LineSegmentSide whichSide(Vector2< T > const &point) const
Definition: LineSegment2D.hpp:131
T const & getLength() const
Definition: LineSegment2D.hpp:106
LineSegment2D(Vector2< T > const &a, Vector2< T > const &b)
Definition: LineSegment2D.hpp:62
Definition: Vector2.hpp:44
T dot(Vector2< T > const &rhs) const
Definition: Vector2.hpp:254
T distanceTo(Vector2< T > const &point) const
Definition: LineSegment2D.hpp:156