|
@@ -1,8 +1,8 @@
|
|
|
-/*!
|
|
|
+/**
|
|
|
* \file Polygon.cpp
|
|
|
- * \brief
|
|
|
- * \author Gapchich Vladislav
|
|
|
- * \date 23/10/11
|
|
|
+ * \brief a polygon class
|
|
|
+ * \author Gapchich Vladislav, Sven Sickert
|
|
|
+ * \date 23/10/2011 (07/10/2015)
|
|
|
*/
|
|
|
|
|
|
#include "vislearning/cbaselib/Polygon.h"
|
|
@@ -100,6 +100,116 @@ Polygon::id() const
|
|
|
return id_;
|
|
|
}
|
|
|
|
|
|
-/*
|
|
|
- *
|
|
|
- */
|
|
|
+// check whether point is inside polygon or not
|
|
|
+bool
|
|
|
+Polygon::handleEdge ( const int px, const int py,
|
|
|
+ const int x1, const int y1,
|
|
|
+ const int x2, const int y2,
|
|
|
+ int & lastdir, int & c )
|
|
|
+{
|
|
|
+ if (py == y1)
|
|
|
+ {
|
|
|
+ if (px == x1) return true;
|
|
|
+
|
|
|
+ if (y1 > y2)
|
|
|
+ {
|
|
|
+ if (lastdir == -1) // decreasing (cont.)
|
|
|
+ if (x1 < px) c++;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (y1 < y2)
|
|
|
+ {
|
|
|
+ if (lastdir == 1) // increasing (cont.)
|
|
|
+ if (x1 < px) c++;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (y1 == y2)
|
|
|
+ {
|
|
|
+ if ((x1 <= px) && (x2 >= px)) return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( (y1 > py && y2 < py) || (y1 < py && y2 > py) )
|
|
|
+ {
|
|
|
+ int xz = (int)( (py - y1) * (x2 - x1) / (y2 - y1) + x1 );
|
|
|
+
|
|
|
+ /* is point laying on the polygon curve? */
|
|
|
+ if (xz == px) return true;
|
|
|
+
|
|
|
+ /* does the scanning line cut the polygon curve left of the point? */
|
|
|
+ if (xz < px) c++;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (y2 > y1) lastdir = 1;
|
|
|
+
|
|
|
+ if (y2 < y1) lastdir = -1;
|
|
|
+
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+bool
|
|
|
+Polygon::insidePolygon ( const int &px, const int &py )
|
|
|
+{
|
|
|
+ int i, j, c = 0;
|
|
|
+ int lastdir = 0;
|
|
|
+
|
|
|
+ if ( points_.size() < 2 )
|
|
|
+ {
|
|
|
+ cerr << "Polygon::insidePolygon: Not a valid Polygon curve" << endl;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ for ( PointsList::const_iterator i = points_.begin();
|
|
|
+ i != points_.end(); ++i )
|
|
|
+ {
|
|
|
+ PointsList::const_iterator j = i;
|
|
|
+ j++;
|
|
|
+
|
|
|
+ if ( j == points_.end() ) j = points_.begin();
|
|
|
+
|
|
|
+ CoordT<int> pi = *i;
|
|
|
+ CoordT<int> pj = *j;
|
|
|
+
|
|
|
+ if (pj.y > pi.y) lastdir = 1;
|
|
|
+
|
|
|
+ if (pj.y < pi.y) lastdir = -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (lastdir == 0)
|
|
|
+ {
|
|
|
+ cerr << "Polygon::insidePolygon: Polygon is degenerated" << endl;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ for ( PointsList::const_iterator i = points_.begin();
|
|
|
+ i != points_.end(); ++i )
|
|
|
+ {
|
|
|
+ PointsList::const_iterator j = i;
|
|
|
+ j++;
|
|
|
+
|
|
|
+ if ( j == points_.end() ) j = points_.begin();
|
|
|
+
|
|
|
+ CoordT<int> pi = *i;
|
|
|
+ CoordT<int> pj = *j;
|
|
|
+
|
|
|
+ if ( handleEdge( px, py, pi.x, pi.y, pj.x, pj.y, lastdir, c ) )
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (c & 1) return true;
|
|
|
+
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
+bool
|
|
|
+Polygon::insidePolygon ( const CoordT< int > &aPoint )
|
|
|
+{
|
|
|
+ if (aPoint.x < 0 || aPoint.y < 0) {
|
|
|
+ cerr << "Polygon::insidePolygon(): point does not have valid coordinates"
|
|
|
+ << endl;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ return insidePolygon ( aPoint.x, aPoint.y );
|
|
|
+}
|