Loading...
Searching...
No Matches
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#ifndef IGNITION_MATH_TRIANGLE_HH_
18#define IGNITION_MATH_TRIANGLE_HH_
19
20#include <set>
24#include <ignition/math/config.hh>
25
26namespace ignition
27{
28 namespace math
29 {
30 inline namespace IGNITION_MATH_VERSION_NAMESPACE
31 {
34 template<typename T>
36 {
38 public: Triangle() = default;
39
44 public: Triangle(const math::Vector2<T> &_pt1,
45 const math::Vector2<T> &_pt2,
46 const math::Vector2<T> &_pt3)
47 {
48 this->Set(_pt1, _pt2, _pt3);
49 }
50
56 public: void Set(const unsigned int _index, const math::Vector2<T> &_pt)
57 {
58 this->pts[clamp(_index, 0u, 2u)] = _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(const unsigned int _index) const
94 {
95 if (_index == 0)
96 return Line2<T>(this->pts[0], this->pts[1]);
97 else if (_index == 1)
98 return Line2<T>(this->pts[1], this->pts[2]);
99 else
100 return Line2<T>(this->pts[2], this->pts[0]);
101 }
102
108 public: bool Contains(const Line2<T> &_line) const
109 {
110 return this->Contains(_line[0]) && this->Contains(_line[1]);
111 }
112
116 public: bool Contains(const math::Vector2<T> &_pt) const
117 {
118 // Compute vectors
119 math::Vector2<T> v0 = this->pts[2] -this->pts[0];
120 math::Vector2<T> v1 = this->pts[1] -this->pts[0];
121 math::Vector2<T> v2 = _pt - this->pts[0];
122
123 // Compute dot products
124 double dot00 = v0.Dot(v0);
125 double dot01 = v0.Dot(v1);
126 double dot02 = v0.Dot(v2);
127 double dot11 = v1.Dot(v1);
128 double dot12 = v1.Dot(v2);
129
130 // Compute barycentric coordinates
131 double invDenom = 1.0 / (dot00 * dot11 - dot01 * dot01);
132 double u = (dot11 * dot02 - dot01 * dot12) * invDenom;
133 double v = (dot00 * dot12 - dot01 * dot02) * invDenom;
134
135 // Check if point is in triangle
136 return (u >= 0) && (v >= 0) && (u + v <= 1);
137 }
138
146 public: bool Intersects(const Line2<T> &_line,
147 math::Vector2<T> &_ipt1,
148 math::Vector2<T> &_ipt2) const
149 {
150 if (this->Contains(_line))
151 {
152 _ipt1 = _line[0];
153 _ipt2 = _line[1];
154 return true;
155 }
156
157 Line2<T> line1(this->pts[0], this->pts[1]);
158 Line2<T> line2(this->pts[1], this->pts[2]);
159 Line2<T> line3(this->pts[2], this->pts[0]);
160
162 std::set<math::Vector2<T> > points;
163
164 if (line1.Intersect(_line, pt))
165 points.insert(pt);
166
167 if (line2.Intersect(_line, pt))
168 points.insert(pt);
169
170 if (line3.Intersect(_line, pt))
171 points.insert(pt);
172
173 if (points.empty())
174 {
175 return false;
176 }
177 else if (points.size() == 1)
178 {
179 auto iter = points.begin();
180
181 _ipt1 = *iter;
182 if (this->Contains(_line[0]))
183 _ipt2 = _line[0];
184 else
185 {
186 _ipt2 = _line[1];
187 }
188 }
189 else
190 {
191 auto iter = points.begin();
192 _ipt1 = *(iter++);
193 _ipt2 = *iter;
194 }
195
196 return true;
197 }
198
201 public: T Perimeter() const
202 {
203 return this->Side(0).Length() + this->Side(1).Length() +
204 this->Side(2).Length();
205 }
206
209 public: double Area() const
210 {
211 double s = this->Perimeter() / 2.0;
212 T a = this->Side(0).Length();
213 T b = this->Side(1).Length();
214 T c = this->Side(2).Length();
215
216 // Heron's formula
217 // http://en.wikipedia.org/wiki/Heron%27s_formula
218 return sqrt(s * (s-a) * (s-b) * (s-c));
219 }
220
226 public: math::Vector2<T> operator[](const size_t _index) const
227 {
228 return this->pts[clamp(_index, IGN_ZERO_SIZE_T, IGN_TWO_SIZE_T)];
229 }
230
232 private: math::Vector2<T> pts[3];
233 };
234
237
240
243 }
244 }
245}
246#endif
A two dimensional line segment.
Definition Line2.hh:35
bool Intersect(const Line2< T > &_line, double _epsilon=1e-6) const
Check if this line intersects the given line segment.
Definition Line2.hh:179
Triangle class and related functions.
Definition Triangle.hh:36
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
bool Contains(const math::Vector2< T > &_pt) const
Get whether this triangle contains the given point.
Definition Triangle.hh:116
Triangle(const math::Vector2< T > &_pt1, const math::Vector2< T > &_pt2, const math::Vector2< T > &_pt3)
Constructor.
Definition Triangle.hh:44
T Perimeter() const
Get the length of the triangle's perimeter.
Definition Triangle.hh:201
Line2< T > Side(const unsigned int _index) const
Get a line segment for one side of the triangle.
Definition Triangle.hh:93
bool Contains(const Line2< T > &_line) const
Check if this triangle completely contains the given line segment.
Definition Triangle.hh:108
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:146
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
double Area() const
Get the area of this triangle.
Definition Triangle.hh:209
math::Vector2< T > operator[](const size_t _index) const
Get one of points that define the triangle.
Definition Triangle.hh:226
void Set(const unsigned int _index, const math::Vector2< T > &_pt)
Set one vertex of the triangle.
Definition Triangle.hh:56
Two dimensional (x, y) vector.
Definition Vector2.hh:33
T Dot(const Vector2< T > &_v) const
Get the dot product of this vector and _v.
Definition Vector2.hh:115
T clamp(T _v, T _min, T _max)
Simple clamping function.
Definition Helpers.hh:395
static const size_t IGN_TWO_SIZE_T
size_t type with a value of 2
Definition Helpers.hh:222
static const size_t IGN_ZERO_SIZE_T
size_t type with a value of 0
Definition Helpers.hh:216
Triangle< double > Triangled
Double specialization of the Triangle class.
Definition Triangle.hh:239
Triangle< float > Trianglef
Float specialization of the Triangle class.
Definition Triangle.hh:242
Triangle< int > Trianglei
Integer specialization of the Triangle class.
Definition Triangle.hh:236
Definition Angle.hh:40