All Classes Namespaces Files Functions Variables Typedefs Friends Macros Pages
Triangle.hh
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2014 Open Source Robotics Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16 */
17 
18 #ifndef _IGNITION_TRIANGLE_HH_
19 #define _IGNITION_TRIANGLE_HH_
20 
21 #include <set>
22 #include <ignition/math/Line2.hh>
23 #include <ignition/math/Vector2.hh>
25 
26 namespace ignition
27 {
28  namespace math
29  {
32  template<typename T>
33  class Triangle
34  {
36  public: Triangle() = default;
37 
42  public: Triangle(const math::Vector2<T> &_pt1,
43  const math::Vector2<T> &_pt2,
44  const math::Vector2<T> &_pt3)
45  {
46  this->Set(_pt1, _pt2, _pt3);
47  }
48 
53  public: void Set(unsigned int _index, const math::Vector2<T> &_pt)
54  {
55  if (_index >2)
56  throw IndexException();
57  else
58  this->pts[_index] = _pt;
59  }
60 
65  public: void Set(const math::Vector2<T> &_pt1,
66  const math::Vector2<T> &_pt2,
67  const math::Vector2<T> &_pt3)
68  {
69  this->pts[0] = _pt1;
70  this->pts[1] = _pt2;
71  this->pts[2] = _pt3;
72  }
73 
78  public: bool Valid() const
79  {
80  T a = this->Side(0).Length();
81  T b = this->Side(1).Length();
82  T c = this->Side(2).Length();
83  return (a+b) > c && (b+c) > a && (c+a) > b;
84  }
85 
93  public: Line2<T> Side(unsigned int _index) const
94  {
95  if (_index > 2)
96  throw IndexException();
97  else if (_index == 0)
98  return Line2<T>(this->pts[0], this->pts[1]);
99  else if (_index == 1)
100  return Line2<T>(this->pts[1], this->pts[2]);
101  else
102  return Line2<T>(this->pts[2], this->pts[0]);
103  }
104 
110  public: bool Contains(const Line2<T> &_line) const
111  {
112  return this->Contains(_line[0]) && this->Contains(_line[1]);
113  }
114 
118  public: bool Contains(const math::Vector2<T> &_pt) const
119  {
120  // Compute vectors
121  math::Vector2<T> v0 = this->pts[2] -this->pts[0];
122  math::Vector2<T> v1 = this->pts[1] -this->pts[0];
123  math::Vector2<T> v2 = _pt - this->pts[0];
124 
125  // Compute dot products
126  double dot00 = v0.Dot(v0);
127  double dot01 = v0.Dot(v1);
128  double dot02 = v0.Dot(v2);
129  double dot11 = v1.Dot(v1);
130  double dot12 = v1.Dot(v2);
131 
132  // Compute barycentric coordinates
133  double invDenom = 1.0 / (dot00 * dot11 - dot01 * dot01);
134  double u = (dot11 * dot02 - dot01 * dot12) * invDenom;
135  double v = (dot00 * dot12 - dot01 * dot02) * invDenom;
136 
137  // Check if point is in triangle
138  return (u >= 0) && (v >= 0) && (u + v <= 1);
139  }
140 
148  public: bool Intersects(const Line2<T> &_line,
149  math::Vector2<T> &_ipt1,
150  math::Vector2<T> &_ipt2) const
151  {
152  if (this->Contains(_line))
153  {
154  _ipt1 = _line[0];
155  _ipt2 = _line[1];
156  return true;
157  }
158 
159  Line2<T> line1(this->pts[0], this->pts[1]);
160  Line2<T> line2(this->pts[1], this->pts[2]);
161  Line2<T> line3(this->pts[2], this->pts[0]);
162 
163  math::Vector2<T> pt;
164  std::set<math::Vector2<T> > points;
165 
166  if (line1.Intersect(_line, pt))
167  points.insert(pt);
168 
169  if (line2.Intersect(_line, pt))
170  points.insert(pt);
171 
172  if (line3.Intersect(_line, pt))
173  points.insert(pt);
174 
175  if (points.empty())
176  {
177  return false;
178  }
179  else if (points.size() == 1)
180  {
181  typename std::set<math::Vector2<T> >::iterator iter = points.begin();
182 
183  _ipt1 = *iter;
184  if (this->Contains(_line[0]))
185  _ipt2 = _line[0];
186  else
187  {
188  _ipt2 = _line[1];
189  }
190  }
191  else
192  {
193  typename std::set<math::Vector2<T> >::iterator iter = points.begin();
194  _ipt1 = *(iter++);
195  _ipt2 = *iter;
196  }
197 
198  return true;
199  }
200 
203  public: T Perimeter() const
204  {
205  return this->Side(0).Length() + this->Side(1).Length() +
206  this->Side(2).Length();
207  }
208 
211  public: double Area() const
212  {
213  double s = this->Perimeter() / 2.0;
214  T a = this->Side(0).Length();
215  T b = this->Side(1).Length();
216  T c = this->Side(2).Length();
217 
218  // Heron's formula
219  // http://en.wikipedia.org/wiki/Heron%27s_formula
220  return sqrt(s * (s-a) * (s-b) * (s-c));
221  }
222 
226  public: math::Vector2<T> operator[](size_t _index) const
227  {
228  if (_index > 2)
229  throw IndexException();
230  return this->pts[_index];
231  }
232 
234  private: math::Vector2<T> pts[3];
235  };
236 
239 
242 
245  }
246 }
247 #endif
bool Contains(const Line2< T > &_line) const
Check if this triangle completely contains the given line segment.
Definition: Triangle.hh:110
Line2< T > Side(unsigned int _index) const
Get a line segment for one side of the triangle.
Definition: Triangle.hh:93
Two dimensional (x, y) vector.
Definition: Vector2.hh:29
A two dimensional line segment.
Definition: Line2.hh:32
math::Vector2< T > operator[](size_t _index) const
Get one of points that define the triangle.
Definition: Triangle.hh:226
void Set(unsigned int _index, const math::Vector2< T > &_pt)
Set one vertex of the triangle.
Definition: Triangle.hh:53
bool Valid() const
Get whether this triangle is valid, based on triangle inequality: the sum of the lengths of any two s...
Definition: Triangle.hh:78
Triangle< int > Trianglei
Integer specialization of the Triangle class.
Definition: Triangle.hh:238
Triangle< double > Triangled
Double specialization of the Triangle class.
Definition: Triangle.hh:241
bool Contains(const math::Vector2< T > &_pt) const
Get whether this triangle contains the given point.
Definition: Triangle.hh:118
double Area() const
Get the area of this triangle.
Definition: Triangle.hh:211
T Dot(const Vector2< T > &_v) const
Get the dot product of this vector and _v.
Definition: Vector2.hh:89
void Set(const math::Vector2< T > &_pt1, const math::Vector2< T > &_pt2, const math::Vector2< T > &_pt3)
Set all vertices of the triangle.
Definition: Triangle.hh:65
Triangle()=default
Default constructor.
Exception that is thrown when an out-of-bounds index is encountered.
Definition: IndexException.hh:30
Triangle class and related functions.
Definition: Triangle.hh:33
T Perimeter() const
Get the length of the triangle's perimeter.
Definition: Triangle.hh:203
bool Intersect(const Line2< T > &_line, double _epsilon=1e-6) const
Check if this line intersects the given line segment.
Definition: Line2.hh:177
Triangle< float > Trianglef
Float specialization of the Triangle class.
Definition: Triangle.hh:244
bool Intersects(const Line2< T > &_line, math::Vector2< T > &_ipt1, math::Vector2< T > &_ipt2) const
Get whether the given line intersects this triangle.
Definition: Triangle.hh:148
Triangle(const math::Vector2< T > &_pt1, const math::Vector2< T > &_pt2, const math::Vector2< T > &_pt3)
Constructor.
Definition: Triangle.hh:42