21 #ifndef otbPolygon_hxx
22 #define otbPolygon_hxx
29 template <
class TValue>
32 Superclass::AddVertex(vertex);
33 m_AreaIsValid =
false;
42 template <
class TValue>
47 unsigned int crossingCount = 0;
49 double xa = it.Value()[0];
50 double ya = it.Value()[1];
52 while (it != this->GetVertexList()->End())
54 double xb = it.Value()[0];
55 double yb = it.Value()[1];
56 if (std::abs(xb - xa) < m_Epsilon)
58 if (ya > yb && xa > x && y >= yb && y < ya)
62 else if (ya < yb && xa > x && y >= ya && y < yb)
67 else if (std::abs(yb - ya) >= m_Epsilon)
69 double xcross = xa + (xb - xa) * (y - ya) / (yb - ya);
71 if (ya > yb && xcross > x && y >= yb && y < ya)
75 else if (ya < yb && xcross > x && y >= ya && y < yb)
84 double xb = this->GetVertexList()->Begin().Value()[0];
85 double yb = this->GetVertexList()->Begin().Value()[1];
86 if (std::abs(xb - xa) < m_Epsilon)
88 if (ya > yb && xa > x && y >= yb && y < ya)
92 else if (ya < yb && xa > x && y >= ya && y < yb)
97 else if (std::abs(yb - ya) >= m_Epsilon)
99 double xcross = xa + (xb - xa) * (y - ya) / (yb - ya);
101 if (ya > yb && xcross > x && y >= yb && y < ya)
105 else if (ya < yb && xcross > x && y >= ya && y < yb)
111 return (crossingCount % 2 == 1);
119 template <
class TValue>
128 double xa = it.Value()[0];
129 double ya = it.Value()[1];
133 while (!resp && it != this->GetVertexList()->End())
137 if (std::abs(xb - xa) >= m_Epsilon)
139 double cd = (yb - ya) / (xb - xa);
140 double oo = (ya - cd * xa);
141 double xmin = std::min(xa, xb);
142 double xmax = std::max(xa, xb);
143 if ((std::abs(y - cd * x - oo) < m_Epsilon) && (x <= xmax) && (x >= xmin))
151 double ymin = std::min(ya, yb);
152 double ymax = std::max(ya, yb);
153 if ((std::abs(x - xa) < m_Epsilon) && (y <= ymax) && (y >= ymin))
165 if (std::abs(xb - xa) >= m_Epsilon)
167 double cd = (yb - ya) / (xb - xa);
168 double oo = (ya - cd * xa);
169 double xmin = std::min(xa, xb);
170 double xmax = std::max(xa, xb);
173 if ((std::abs(y - cd * x - oo) < m_Epsilon) && (x <= xmax) && (x >= xmin))
181 double ymin = std::min(ya, yb);
182 double ymax = std::max(ya, yb);
183 if ((std::abs(x - xa) <= m_Epsilon) && (y <= ymax) && (y >= ymin))
198 template <
class TValue>
201 unsigned int resp = 0;
210 if (IsCrossing(a, b, current, it.Value()))
214 current = it.Value();
218 if (IsCrossing(a, b, current, first))
231 template <
class TValue>
234 unsigned int resp = 0;
243 if (IsTouching(a, b, current, it.Value()))
247 current = it.Value();
251 if (IsTouching(a, b, current, first))
266 template <
class TValue>
270 double xbmin = std::min(b1[0], b2[0]);
271 double xbmax = std::max(b1[0], b2[0]);
272 double ybmin = std::min(b1[1], b2[1]);
273 double ybmax = std::max(b1[1], b2[1]);
274 double xamin = std::min(a1[0], a2[0]);
275 double xamax = std::max(a1[0], a2[0]);
276 double yamin = std::min(a1[1], a2[1]);
277 double yamax = std::max(a1[1], a2[1]);
278 if (std::abs(a1[0] - a2[0]) < m_Epsilon && std::abs(b1[0] - b2[0]) < m_Epsilon)
282 else if (std::abs(a1[0] - a2[0]) < m_Epsilon)
284 double cd2 = (b2[1] - b1[1]) / (b2[0] - b1[0]);
285 double oo2 = b1[1] - cd2 * b1[0];
286 double ycross = cd2 * a1[0] + oo2;
287 resp = (xbmin < a1[0] && xbmax > a1[0] && yamin < ycross && yamax > ycross);
289 else if (std::abs(b1[0] - b2[0]) < m_Epsilon)
291 double cd1 = (a2[1] - a1[1]) / (a2[0] - a1[0]);
292 double oo1 = a1[1] - cd1 * a1[0];
293 double ycross = cd1 * b1[0] + oo1;
294 resp = (xamin < b1[0] && xamax > b1[0] && ybmin < ycross && ybmax > ycross);
298 double cd1 = (a2[1] - a1[1]) / (a2[0] - a1[0]);
299 double oo1 = a1[1] - cd1 * a1[0];
300 double cd2 = (b2[1] - b1[1]) / (b2[0] - b1[0]);
301 double oo2 = b1[1] - cd2 * b1[0];
304 double xcross = (oo2 - oo1) / (cd1 - cd2);
305 resp = (xamin < xcross && xbmin < xcross && xamax > xcross && xbmax > xcross);
319 template <
class TValue>
323 double xbmin = std::min(b1[0], b2[0]);
324 double xbmax = std::max(b1[0], b2[0]);
325 double ybmin = std::min(b1[1], b2[1]);
326 double ybmax = std::max(b1[1], b2[1]);
327 double xamin = std::min(a1[0], a2[0]);
328 double xamax = std::max(a1[0], a2[0]);
329 double yamin = std::min(a1[1], a2[1]);
330 double yamax = std::max(a1[1], a2[1]);
331 if (std::abs(a1[0] - a2[0]) < m_Epsilon && std::abs(b1[0] - b2[0]) < m_Epsilon)
333 resp = (std::abs(a1[0] - b1[0]) < m_Epsilon) && ((a1[1] <= ybmax && a1[1] >= ybmin) || (a2[1] <= ybmax && a2[1] >= ybmin) ||
334 (b1[1] <= yamax && b1[1] >= yamin) || (b2[1] <= yamax && b2[1] >= yamin));
336 else if (std::abs(a1[0] - a2[0]) < m_Epsilon)
338 double cd2 = (b2[1] - b1[1]) / (b2[0] - b1[0]);
339 double oo2 = b1[1] - cd2 * b1[0];
342 if (std::abs(a1[1] - cd2 * a1[0] - oo2) < m_Epsilon)
344 resp = (a1[0] >= xbmin && a1[0] <= xbmax);
346 else if (std::abs(a2[1] - cd2 * a2[0] - oo2) < m_Epsilon)
348 resp = (a2[0] >= xbmin && a2[0] <= xbmax);
351 else if (std::abs(b1[0] - b2[0]) < m_Epsilon)
353 double cd1 = (a2[1] - a1[1]) / (a2[0] - a1[0]);
354 double oo1 = a1[1] - cd1 * a1[0];
356 if (std::abs(b1[1] - cd1 * b1[0] - oo1) < m_Epsilon)
358 resp = (b1[0] >= xamin && b1[0] <= xamax);
360 else if (std::abs(b2[1] - cd1 * b2[0] - oo1) < m_Epsilon)
362 resp = (b2[0] >= xamin && b2[0] <= xamax);
367 double cd1 = (a2[1] - a1[1]) / (a2[0] - a1[0]);
368 double oo1 = a1[1] - cd1 * a1[0];
369 double cd2 = (b2[1] - b1[1]) / (b2[0] - b1[0]);
370 double oo2 = b1[1] - cd2 * b1[0];
371 if (std::abs(cd1 - cd2) < m_Epsilon && std::abs(oo1 - oo2) < m_Epsilon)
373 resp = ((xamin <= xbmax && xamin >= xbmin) || (xamax <= xbmax && xamax >= xbmin) || (xbmin <= xamax && xbmin >= xamin) ||
374 (xbmax <= xamax && xbmax >= xamin));
378 if (std::abs(a1[1] - cd2 * a1[0] - oo2) < m_Epsilon)
380 resp = (a1[0] >= xbmin && a1[0] <= xbmax);
382 else if (std::abs(a2[1] - cd2 * a2[0] - oo2) < m_Epsilon)
384 resp = (a2[0] >= xbmin && a2[0] <= xbmax);
386 if (std::abs(b1[1] - cd1 * b1[0] - oo1) < m_Epsilon)
388 resp = (b1[0] >= xamin && b1[0] <= xamax);
390 else if (std::abs(b2[1] - cd1 * b2[0] - oo1) < m_Epsilon)
392 resp = (b2[0] >= xamin && b2[0] <= xamax);
402 template <
class TValue>
407 if (this->GetVertexList()->Size() > 2)
415 while (it != this->GetVertexList()->End())
420 double vector1x = pt1[0] - origin[0];
421 double vector1y = pt1[1] - origin[1];
422 double vector2x = pt2[0] - origin[0];
423 double vector2y = pt2[1] - origin[1];
424 double crossProdduct = vector1x * vector2y - vector2x * vector1y;
425 area += crossProdduct;
429 m_Area = fabs(area / 2.0);
436 m_AreaIsValid =
true;
442 template <
class TValue>
456 template <
class TValue>
464 if (this->GetVertexList()->Size() > 1)
471 while (it != this->GetVertexList()->End())
476 for (
int i = 0; i < 2; ++i)
478 accum += (pt1[i] - pt2[i]) * (pt1[i] - pt2[i]);
480 length += std::sqrt(accum);
486 for (
int i = 0; i < 2; ++i)
488 accum += (origin[i] - pt2[i]) * (origin[i] - pt2[i]);
490 length += std::sqrt(accum);
500 template <
class TValue>
503 Superclass::Modified();
504 m_AreaIsValid =
false;
510 template <
class TValue>
513 Superclass::PrintSelf(os, indent);