Fix pointPolygonTest for large coordinate values (#10222)
authorJuha Reunanen <juha.reunanen@gmail.com>
Tue, 5 Dec 2017 12:49:44 +0000 (14:49 +0200)
committerVadim Pisarevsky <vadim.pisarevsky@gmail.com>
Tue, 5 Dec 2017 12:49:44 +0000 (15:49 +0300)
* Add test that fails

* Fix integer pointPolygonTest for large coordinate values

* Review fixes:
- change type from long long to int64
- move test code to test_contours.cpp, and make it C++98 compliant

* Hopefully fix compiler error by using push_back instead of emplace_back

modules/imgproc/src/geometry.cpp
modules/imgproc/test/test_contours.cpp

index cf9cb07..66df611 100644 (file)
@@ -119,7 +119,6 @@ double cv::pointPolygonTest( InputArray _contour, Point2f pt, bool measureDist )
 
         for( i = 0; i < total; i++ )
         {
-            int dist;
             v0 = v;
             v = cnt[i];
 
@@ -133,7 +132,8 @@ double cv::pointPolygonTest( InputArray _contour, Point2f pt, bool measureDist )
                 continue;
             }
 
-            dist = (ip.y - v0.y)*(v.x - v0.x) - (ip.x - v0.x)*(v.y - v0.y);
+            int64 dist = static_cast<int64>(ip.y - v0.y)*(v.x - v0.x)
+                       - static_cast<int64>(ip.x - v0.x)*(v.y - v0.y);
             if( dist == 0 )
                 return 0;
             if( v.y < v0.y )
index d5c4e44..d7d5128 100644 (file)
@@ -485,4 +485,18 @@ TEST(Imgproc_FindContours, border)
     ASSERT_TRUE(norm(img - img_draw_contours, NORM_INF) == 0.0);
 }
 
+TEST(Imgproc_PointPolygonTest, regression_10222)
+{
+    vector<Point> contour;
+    contour.push_back(Point(0, 0));
+    contour.push_back(Point(0, 100000));
+    contour.push_back(Point(100000, 100000));
+    contour.push_back(Point(100000, 50000));
+    contour.push_back(Point(100000, 0));
+
+    const Point2f point(40000, 40000);
+    const double result = cv::pointPolygonTest(contour, point, false);
+    EXPECT_GT(result, 0) << "Desired result: point is inside polygon - actual result: point is not inside polygon";
+}
+
 /* End of file. */