triangle_2d.inl
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 #ifndef LASS_GUARDIAN_OF_INCLUSION_PRIM_TRIANGLE_2D_INL
00046 #define LASS_GUARDIAN_OF_INCLUSION_PRIM_TRIANGLE_2D_INL
00047
00048 #include "prim_common.h"
00049 #include "triangle_2d.h"
00050 #include "line_2d.h"
00051
00052 namespace lass
00053 {
00054 namespace prim
00055 {
00056
00057
00058
00059
00060 template <typename T>
00061 Triangle2D<T>::Triangle2D()
00062 {
00063 }
00064
00065
00066
00067
00068
00069 template <typename T>
00070 Triangle2D<T>::Triangle2D(const TPoint& iA, const TPoint& iB, const TPoint& iC)
00071 {
00072 vertices_[0] = iA;
00073 vertices_[1] = iB;
00074 vertices_[2] = iC;
00075 }
00076
00077
00078
00079
00080
00081 template <typename T>
00082 const typename Triangle2D<T>::TPoint& Triangle2D<T>::operator[](int iIndexOfVertex) const
00083 {
00084 LASS_ASSERT(isInRange(iIndexOfVertex));
00085 return vertices_[iIndexOfVertex];
00086 }
00087
00088
00089
00090
00091
00092 template <typename T>
00093 typename Triangle2D<T>::TPoint& Triangle2D<T>::operator[](int iIndexOfVertex)
00094 {
00095 LASS_ASSERT(isInRange(iIndexOfVertex));
00096 return vertices_[iIndexOfVertex];
00097 }
00098
00099
00100
00101
00102
00103 template <typename T>
00104 const typename Triangle2D<T>::TPoint& Triangle2D<T>::at(int iIndexOfVertex) const
00105 {
00106 const int i = num::mod(iIndexOfVertex, static_cast<unsigned>(size_));
00107 LASS_ASSERT(isInRange(i));
00108 return vertices_[i];
00109 }
00110
00111
00112
00113
00114
00115 template <typename T>
00116 typename Triangle2D<T>::TPoint& Triangle2D<T>::at(int iIndexOfVertex)
00117 {
00118 const int i = num::mod(iIndexOfVertex, static_cast<unsigned>(size_));
00119 LASS_ASSERT(isInRange(i));
00120 return vertices_[i];
00121 }
00122
00123
00124
00125
00126
00127 template <typename T>
00128 const typename Triangle2D<T>::TLineSegment Triangle2D<T>::edge(int iIndexOfTailVertex) const
00129 {
00130 return TLineSegment(at(iIndexOfTailVertex), at(iIndexOfTailVertex + 1));
00131 }
00132
00133
00134
00135
00136
00137 template <typename T>
00138 const typename Triangle2D<T>::TVector Triangle2D<T>::vector(int iIndexOfTailVertex) const
00139 {
00140 return at(iIndexOfTailVertex + 1) - at(iIndexOfTailVertex);
00141 }
00142
00143
00144
00145
00146
00147
00148
00149 template <typename T>
00150 const bool Triangle2D<T>::isEmpty() const
00151 {
00152 return vertices_[0] == vertices_[1] && vertices_[0] == vertices_[2];
00153 }
00154
00155
00156
00157
00158
00159 template <typename T>
00160 const int Triangle2D<T>::size() const
00161 {
00162 return size_;
00163 }
00164
00165
00166
00167
00168
00169 template <typename T>
00170 const typename Triangle2D<T>::TValue Triangle2D<T>::signedArea() const
00171 {
00172 LASS_ASSERT(size_ == 3);
00173 return perpDot(vertices_[1] - vertices_[0], vertices_[2] - vertices_[0]) / T(2);
00174 }
00175
00176
00177
00178
00179
00180 template <typename T>
00181 const typename Triangle2D<T>::TValue Triangle2D<T>::area() const
00182 {
00183 return num::abs(signedArea());
00184 }
00185
00186
00187
00188
00189
00190 template <typename T>
00191 const typename Triangle2D<T>::TValue Triangle2D<T>::perimeter() const
00192 {
00193 return distance(vertices_[0], vertices_[1]) +
00194 distance(vertices_[1], vertices_[2]) +
00195 distance(vertices_[2], vertices_[0]);
00196 }
00197
00198
00199
00200
00201
00202 template <typename T>
00203 const typename Triangle2D<T>::TPointH
00204 Triangle2D<T>::vertexCentroid() const
00205 {
00206 TPointH result = vertices_[0] + vertices_[1] + vertices_[2];
00207 return result;
00208 }
00209
00210
00211
00212
00213
00214 template <typename T> inline
00215 const typename Triangle2D<T>::TPointH
00216 Triangle2D<T>::surfaceCentroid() const
00217 {
00218 return vertexCentroid();
00219 }
00220
00221
00222
00223
00224
00225
00226
00227 template <typename T>
00228 const bool Triangle2D<T>::isSimple() const
00229 {
00230 return true;
00231 }
00232
00233
00234
00235
00236
00237
00238
00239 template <typename T>
00240 const bool Triangle2D<T>::isConvex() const
00241 {
00242 return true;
00243 }
00244
00245
00246
00247
00248
00249 template <typename T>
00250 const Orientation Triangle2D<T>::orientation() const
00251 {
00252 const TValue area = signedArea();
00253 if (area > TNumTraits::zero)
00254 {
00255 return oCounterClockWise;
00256 }
00257 else if (area < TNumTraits::zero)
00258 {
00259 return oClockWise;
00260 }
00261 else
00262 {
00263 return oInvalid;
00264 }
00265 }
00266
00267
00268
00269
00270
00271
00272
00273 template <typename T>
00274 const bool Triangle2D<T>::isReflex(int iIndexOfVertex) const
00275 {
00276 return false;
00277 }
00278
00279
00280
00281
00282
00283 template <typename T>
00284 const bool Triangle2D<T>::contains(const TPoint& iP) const
00285 {
00286 return
00287 perpDot(vertices_[1] - vertices_[0], iP - vertices_[0]) >= TNumTraits::zero &&
00288 perpDot(vertices_[2] - vertices_[1], iP - vertices_[1]) >= TNumTraits::zero &&
00289 perpDot(vertices_[0] - vertices_[2], iP - vertices_[2]) >= TNumTraits::zero;
00290 }
00291
00292
00293
00294 template <typename T>
00295 const Side Triangle2D<T>::classify(const TPoint& iP) const
00296 {
00297 return contains(iP) ? sInside : sOutside;
00298 }
00299
00300
00301
00302
00303
00304 template <typename T>
00305 void Triangle2D<T>::flip()
00306 {
00307 std::swap(vertices_[0], vertices_[2]);
00308 }
00309
00310
00311
00312
00313
00314
00315
00316 template <typename T>
00317 const bool Triangle2D<T>::isInRange(int iIndexOfVertex) const
00318 {
00319 return iIndexOfVertex >= 0 && iIndexOfVertex < size_;
00320 }
00321
00322
00323
00324
00325
00326
00327
00328 template <typename T>
00329 const T squaredDistance(const Triangle2D<T>& triangle, const Point2D<T>& point)
00330 {
00331 typedef typename Triangle2D<T>::TPoint TPoint;
00332 typedef typename Triangle2D<T>::TVector TVector;
00333 typedef typename Triangle2D<T>::TValue TValue;
00334 typedef typename Triangle2D<T>::TNumTraits TNumTraits;
00335
00336 TValue sqrBest = TNumTraits::infinity;
00337 for (int k1 = 0, k0 = 2; k1 < 3; k0 = k1++)
00338 {
00339 const TPoint& tail = triangle[k0];
00340 const TPoint& head = triangle[k1];
00341 const TVector vector = point - tail;
00342 const TVector edge = head - tail;
00343 const TValue t = dot(vector, edge);
00344 const TValue tMax = dot(edge, edge);
00345 if (t > 0 && t < tMax)
00346 {
00347 const TVector rejected = vector - edge * (t / tMax);
00348 sqrBest = std::min(sqrBest, rejected.squaredNorm());
00349 }
00350 sqrBest = std::min(sqrBest, vector.squaredNorm());
00351 }
00352
00353 return sqrBest;
00354 }
00355
00356
00357
00358
00359
00360 template <typename T>
00361 const T distance(const Triangle2D<T>& triangle, const Point2D<T>& point)
00362 {
00363 return num::sqrt(squaredDistance(triangle, point));
00364 }
00365
00366
00367
00368
00369
00370 template <typename T>
00371 io::XmlOStream& operator<<(io::XmlOStream& ioOStream, const Triangle2D<T>& iTriangle)
00372 {
00373 LASS_ENFORCE_STREAM(ioOStream) << "<Triangle2D>\n";
00374 for (unsigned i = 0; i < 3; ++i)
00375 {
00376 ioOStream << "<vertex id='" << i << "'>" << iTriangle[i] << "</vertex>\n";
00377 }
00378 ioOStream << "</Triangle2D>\n";
00379 return ioOStream;
00380 }
00381
00382
00383
00384
00385
00386 template <typename T>
00387 std::ostream& operator<<(std::ostream& ioOStream, const Triangle2D<T>& iTriangle)
00388 {
00389 LASS_ENFORCE_STREAM(ioOStream)
00390 << "{" << iTriangle[0] << ", " << iTriangle[1] << ", " << iTriangle[2] << "}";
00391 return ioOStream;
00392 }
00393
00394
00395
00396 template<typename T>
00397 lass::io::MatlabOStream& operator<<(lass::io::MatlabOStream& oOStream,
00398 const Triangle2D<T>& iTriangle)
00399 {
00400 LASS_ENFORCE_STREAM(oOStream) << "lasthandle = patch(";
00401 oOStream << "[" << iTriangle[0].x << "," << iTriangle[1].x << "," << iTriangle[2].x << "],";
00402 oOStream << "[" << iTriangle[0].y << "," << iTriangle[1].y << "," << iTriangle[2].y << "],";
00403 oOStream << oOStream.color() << ");\n";
00404 return oOStream;
00405 }
00406
00407
00408
00409
00410
00411
00412
00413
00414 template <typename T>
00415 T partialVoronoiArea(const Triangle2D<T> iT, int iIndexOfVertex)
00416 {
00417
00418 typedef typename Triangle2D<T>::TPoint TPoint;
00419 typedef typename Triangle2D<T>::TPointH TPointH;
00420 typedef typename Triangle2D<T>::TVector TVector;
00421 typedef Line2D<T> TLine;
00422 TPoint a = iT.at(iIndexOfVertex);
00423 TPoint b = iT.at(iIndexOfVertex+1);
00424 TPoint c = iT.at(iIndexOfVertex-1);
00425
00426 TPointH abh = a+b;
00427 TPointH ach = a+c;
00428 TPoint ab = abh.affine();
00429 TPoint ac = ach.affine();
00430 TLine pbisAb(ab, (b-a).perp());
00431 TLine pbisAc(ac, (c-a).perp());
00432
00433 TPoint m;
00434 LASS_ENFORCE(rOne == intersect(pbisAb, pbisAc,m));
00435
00436 Triangle2D<T> aAbm(a,ab,m);
00437 Triangle2D<T> amAc(a,m,ac);
00438
00439 return aAbm.area()+amAc.area();
00440 }
00441
00442 }
00443
00444 }
00445
00446 #endif
00447
00448