浏览代码

point in polygon and test prog

Sven Sickert 10 年之前
父节点
当前提交
8cd9be058c
共有 3 个文件被更改,包括 193 次插入16 次删除
  1. 117 7
      cbaselib/Polygon.cpp
  2. 15 9
      cbaselib/Polygon.h
  3. 61 0
      progs/testPolygonClass.cpp

+ 117 - 7
cbaselib/Polygon.cpp

@@ -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 );
+}

+ 15 - 9
cbaselib/Polygon.h

@@ -1,8 +1,8 @@
-/*!
- * \file Polygon.h
- * \brief
- * \author Gapchich Vladislav
- * \date 23/10/11
+/**
+ * \file Polygon.cpp
+ * \brief a polygon class
+ * \author Gapchich Vladislav, Sven Sickert
+ * \date 23/10/2011 (07/10/2015)
  */
 
 #ifndef __POLYGON_H__
@@ -33,12 +33,22 @@ class Polygon
     NICE::CoordT< int > pop();
     int id() const;
 
+    // check whether point is inside polygon or not
+    bool insidePolygon ( const NICE::CoordT< int > &aPoint );
+    bool insidePolygon ( const int &px, const int &py );
+
   private:
     PointsList points_;
 
     /// id interpreted as a class label
     int id_;
 
+    // helper function for point in polygon test
+    bool handleEdge ( const int px, const int py,
+                      const int x1, const int y1,
+                      const int x2, const int y2,
+                      int & lastdir, int & c );
+
   public:
     /// unique id that distinguishs this particular bounding box object from all others
     int unique_id_;
@@ -47,7 +57,3 @@ class Polygon
 } //namespace
 
 #endif /* __POLYGON_H__ */
-
-/*
- *
- */

+ 61 - 0
progs/testPolygonClass.cpp

@@ -0,0 +1,61 @@
+/**
+ * @file testPolygonClass.cpp
+ * @brief test function of polygon class
+ * @author Sven Sickert
+ * @date 07/10/2015
+
+*/
+
+#include "vislearning/cbaselib/Polygon.h"
+
+using namespace OBJREC;
+
+int main ( int argc, char **argv )
+{
+    Polygon * poly1 = new Polygon ();
+    Polygon * poly2 = new Polygon(*poly1);
+
+    delete poly2;
+
+    NICE::CoordT<int> coord( 10, 10);
+
+    poly1->push( coord );
+    poly1->push( 20, 20 );
+    poly1->push( 10, 20 );
+    poly1->setID( 42 );
+    const PointsList* ptsList = poly1->points();
+
+    poly1->pop();
+    poly1->push ( 20, 10 );
+
+    for ( PointsList::const_iterator it = ptsList->begin();
+          it != ptsList->end(); ++it )
+        std::cout << it->x << " " << it->y << std::endl;
+
+    NICE::CoordT<int> test1( 18, 15 );
+    std::cout << "Point (" << test1.x << "," << test1.y << ") in polygon?"
+              << std::endl;
+    if ( poly1->insidePolygon( test1) )
+        std::cout << "true" << std::endl;
+    else
+        std::cout << "false" << std::endl;
+
+    NICE::CoordT<int> test2( 5, 5 );
+    std::cout << "Point (" << test2.x << "," << test2.y << ") in polygon?"
+              << std::endl;
+    if ( poly1->insidePolygon( test2) )
+        std::cout << "true" << std::endl;
+    else
+        std::cout << "false" << std::endl;
+
+    NICE::CoordT<int> test3( 10, 10 );
+    std::cout << "Point (" << test3.x << "," << test3.y << ") in polygon?"
+              << std::endl;
+    if ( poly1->insidePolygon( test3) )
+        std::cout << "true" << std::endl;
+    else
+        std::cout << "false" << std::endl;
+
+
+    delete poly1;
+}