diff --git a/modules/imgproc/src/min_enclosing_triangle.cpp b/modules/imgproc/src/min_enclosing_triangle.cpp index 33c4a28a31..fdc0073a5d 100644 --- a/modules/imgproc/src/min_enclosing_triangle.cpp +++ b/modules/imgproc/src/min_enclosing_triangle.cpp @@ -100,35 +100,41 @@ /////////////////////////////////// Global variables ///////////////////////////////////// -static unsigned int validationFlag; +namespace minEnclosingTriangle { -static cv::Point2f vertexA; -static cv::Point2f vertexB; -static cv::Point2f vertexC; +static unsigned int G_validationFlag; -static cv::Point2f sideAStartVertex; -static cv::Point2f sideAEndVertex; +static cv::Point2f G_vertexA; +static cv::Point2f G_vertexB; +static cv::Point2f G_vertexC; -static cv::Point2f sideBStartVertex; -static cv::Point2f sideBEndVertex; +static cv::Point2f G_sideAStartVertex; +static cv::Point2f G_sideAEndVertex; -static cv::Point2f sideCStartVertex; -static cv::Point2f sideCEndVertex; +static cv::Point2f G_sideBStartVertex; +static cv::Point2f G_sideBEndVertex; -static double triangleArea; +static cv::Point2f G_sideCStartVertex; +static cv::Point2f G_sideCEndVertex; -static unsigned int a; -static unsigned int b; -static unsigned int c; +static double G_triangleArea; -static unsigned int nrOfPoints; +static unsigned int G_a; +static unsigned int G_b; +static unsigned int G_c; -static std::vector polygon; +static unsigned int G_nrOfPoints; + +static std::vector G_polygon; + +}; ////////////////////////////// Helper functions declarations ///////////////////////////// +namespace minEnclosingTriangle { + static void advance(unsigned int &index); static void advanceBToRightChain(); @@ -257,6 +263,8 @@ static void updateSidesBA(); static void updateSidesCA(); +}; + ///////////////////////////////////// Main functions ///////////////////////////////////// @@ -269,7 +277,7 @@ static void updateSidesCA(); */ void cv::minEnclosingTriangle(cv::InputArray points, CV_OUT cv::OutputArray triangle, CV_OUT double &area) { - findMinEnclosingTriangle(points, triangle, area); + minEnclosingTriangle::findMinEnclosingTriangle(points, triangle, area); } //! Find the minimum enclosing triangle and its area for the given set of points @@ -281,13 +289,15 @@ void cv::minEnclosingTriangle(cv::InputArray points, CV_OUT cv::OutputArray triangle) { double area; - findMinEnclosingTriangle(points, triangle, area); + minEnclosingTriangle::findMinEnclosingTriangle(points, triangle, area); } /////////////////////////////// Helper functions definition ////////////////////////////// +namespace minEnclosingTriangle { + //! Find the minimum enclosing triangle and its area /*! * @param points Set of points @@ -316,7 +326,7 @@ static void createConvexHull(cv::InputArray points) { pointsMat.convertTo(pointsVector, CV_32F); - convexHull(pointsVector, polygon, true, true); + convexHull(pointsVector, G_polygon, true, true); } //! Find the minimum enclosing triangle and its area @@ -327,10 +337,10 @@ static void createConvexHull(cv::InputArray points) { * @param triangle Minimum area triangle enclosing the given polygon * @param area Area of the minimum area enclosing triangle */ -static void findMinEnclosingTriangle( std::vector &triangle, double &area) { +static void findMinEnclosingTriangle(std::vector &triangle, double &area) { initialise(triangle, area); - if (polygon.size() > 3) { + if (G_polygon.size() > 3) { findMinimumAreaEnclosingTriangle(triangle, area); } else { returnMinimumAreaEnclosingTriangle(triangle, area); @@ -353,16 +363,16 @@ static void copyResultingTriangle(const std::vector &resultingTrian * @param area Area of the minimum area enclosing triangle */ static void initialise(std::vector &triangle, double &area) { - nrOfPoints = static_cast(polygon.size()); + G_nrOfPoints = static_cast(G_polygon.size()); area = std::numeric_limits::max(); // Clear all points previously stored in the vector triangle.clear(); // Initialise the values of the indices for the algorithm - a = 1; - b = 2; - c = 0; + G_a = 1; + G_b = 2; + G_c = 0; } //! Find the minimum area enclosing triangle for the given polygon @@ -371,7 +381,7 @@ static void initialise(std::vector &triangle, double &area) { * @param area Area of the minimum area enclosing triangle */ static void findMinimumAreaEnclosingTriangle(std::vector &triangle, double &area) { - for (c = 0; c < nrOfPoints; c++) { + for (G_c = 0; G_c < G_nrOfPoints; G_c++) { advanceBToRightChain(); moveAIfLowAndBIfHigh(); searchForBTangency(); @@ -397,7 +407,7 @@ static void findMinimumAreaEnclosingTriangle(std::vector &triangle, */ static void returnMinimumAreaEnclosingTriangle(std::vector &triangle, double &area) { for (int i = 0; i < 3; i++) { - triangle.push_back(polygon[i % nrOfPoints]); + triangle.push_back(G_polygon[i % G_nrOfPoints]); } area = areaOfTriangle(triangle[0], triangle[1], triangle[2]); @@ -408,8 +418,8 @@ static void returnMinimumAreaEnclosingTriangle(std::vector &triangl * See paper [2] for more details */ static void advanceBToRightChain() { - while (greaterOrEqual(height(successor(b)), height(b))) { - advance(b); + while (greaterOrEqual(height(successor(G_b)), height(G_b))) { + advance(G_b); } } @@ -420,11 +430,11 @@ static void advanceBToRightChain() { static void moveAIfLowAndBIfHigh() { cv::Point2f gammaOfA; - while(height(b) > height(a)) { - if ((gamma(a, gammaOfA)) && (intersectsBelow(gammaOfA, b))) { - advance(b); + while(height(G_b) > height(G_a)) { + if ((gamma(G_a, gammaOfA)) && (intersectsBelow(gammaOfA, G_b))) { + advance(G_b); } else { - advance(a); + advance(G_a); } } } @@ -436,9 +446,9 @@ static void moveAIfLowAndBIfHigh() { static void searchForBTangency() { cv::Point2f gammaOfB; - while (((gamma(b, gammaOfB)) && (intersectsBelow(gammaOfB, b))) && - (greaterOrEqual(height(b), height(predecessor(a))))) { - advance(b); + while (((gamma(G_b, gammaOfB)) && (intersectsBelow(gammaOfB, G_b))) && + (greaterOrEqual(height(G_b), height(predecessor(G_a))))) { + advance(G_b); } } @@ -449,7 +459,8 @@ static void searchForBTangency() { static bool isNotBTangency() { cv::Point2f gammaOfB; - if (((gamma(b, gammaOfB)) && (intersectsAbove(gammaOfB, b))) || (height(b) < height(predecessor(a)))) { + if (((gamma(G_b, gammaOfB)) && (intersectsAbove(gammaOfB, G_b))) || + (height(G_b) < height(predecessor(G_a)))) { return true; } @@ -462,11 +473,11 @@ static bool isNotBTangency() { * Side A will have as start and end vertices the polygon points "a" and "a-1" */ static void updateSidesCA() { - sideCStartVertex = polygon[predecessor(c)]; - sideCEndVertex = polygon[c]; + G_sideCStartVertex = G_polygon[predecessor(G_c)]; + G_sideCEndVertex = G_polygon[G_c]; - sideAStartVertex = polygon[predecessor(a)]; - sideAEndVertex = polygon[a]; + G_sideAStartVertex = G_polygon[predecessor(G_a)]; + G_sideAEndVertex = G_polygon[G_a]; } //! Update sides B and possibly A if tangency for side B was not obtained @@ -475,20 +486,20 @@ static void updateSidesCA() { */ static void updateSidesBA() { // Side B is flush with edge [b, b-1] - sideBStartVertex = polygon[predecessor(b)]; - sideBEndVertex = polygon[b]; + G_sideBStartVertex = G_polygon[predecessor(G_b)]; + G_sideBEndVertex = G_polygon[G_b]; // Find middle point of side B cv::Point2f sideBMiddlePoint; if ((middlePointOfSideB(sideBMiddlePoint)) && - (height(sideBMiddlePoint) < height(predecessor(a)))) { - sideAStartVertex = polygon[predecessor(a)]; - sideAEndVertex = findVertexCOnSideB(); + (height(sideBMiddlePoint) < height(predecessor(G_a)))) { + G_sideAStartVertex = G_polygon[predecessor(G_a)]; + G_sideAEndVertex = findVertexCOnSideB(); - validationFlag = VALIDATION_SIDE_A_TANGENT; + G_validationFlag = VALIDATION_SIDE_A_TANGENT; } else { - validationFlag = VALIDATION_SIDES_FLUSH; + G_validationFlag = VALIDATION_SIDES_FLUSH; } } @@ -497,13 +508,13 @@ static void updateSidesBA() { * See paper [2] for more details */ static void updateSideB() { - if (!gamma(b, sideBStartVertex)) { + if (!gamma(G_b, G_sideBStartVertex)) { CV_Error(cv::Error::StsInternal, ERR_SIDE_B_GAMMA); } - sideBEndVertex = polygon[b]; + G_sideBEndVertex = G_polygon[G_b]; - validationFlag = VALIDATION_SIDE_B_TANGENT; + G_validationFlag = VALIDATION_SIDE_B_TANGENT; } //! Update the triangle vertices after all sides were set and check if a local minimal triangle was found or not @@ -511,9 +522,12 @@ static void updateSideB() { * See paper [2] for more details */ static bool isLocalMinimalTriangle() { - if ((!lineIntersection(sideAStartVertex, sideAEndVertex, sideBStartVertex, sideBEndVertex, vertexC)) || - (!lineIntersection(sideAStartVertex, sideAEndVertex, sideCStartVertex, sideCEndVertex, vertexB)) || - (!lineIntersection(sideBStartVertex, sideBEndVertex, sideCStartVertex, sideCEndVertex, vertexA))) { + if ((!lineIntersection(G_sideAStartVertex, G_sideAEndVertex, + G_sideBStartVertex, G_sideBEndVertex, G_vertexC)) || + (!lineIntersection(G_sideAStartVertex, G_sideAEndVertex, + G_sideCStartVertex, G_sideCEndVertex, G_vertexB)) || + (!lineIntersection(G_sideBStartVertex, G_sideBEndVertex, + G_sideCStartVertex, G_sideCEndVertex, G_vertexA))) { return false; } @@ -527,19 +541,19 @@ static bool isLocalMinimalTriangle() { * See paper [2] for more details */ static bool isValidMinimalTriangle() { - cv::Point2f midpointSideA = middlePoint(vertexB, vertexC); - cv::Point2f midpointSideB = middlePoint(vertexA, vertexC); - cv::Point2f midpointSideC = middlePoint(vertexA, vertexB); + cv::Point2f midpointSideA = middlePoint(G_vertexB, G_vertexC); + cv::Point2f midpointSideB = middlePoint(G_vertexA, G_vertexC); + cv::Point2f midpointSideC = middlePoint(G_vertexA, G_vertexB); - bool sideAValid = (validationFlag == VALIDATION_SIDE_A_TANGENT) - ? (areEqualPoints(midpointSideA, polygon[predecessor(a)])) - : (isPointOnLineSegment(midpointSideA, sideAStartVertex, sideAEndVertex)); + bool sideAValid = (G_validationFlag == VALIDATION_SIDE_A_TANGENT) + ? (areEqualPoints(midpointSideA, G_polygon[predecessor(G_a)])) + : (isPointOnLineSegment(midpointSideA, G_sideAStartVertex, G_sideAEndVertex)); - bool sideBValid = (validationFlag == VALIDATION_SIDE_B_TANGENT) - ? (areEqualPoints(midpointSideB, polygon[b])) - : (isPointOnLineSegment(midpointSideB, sideBStartVertex, sideBEndVertex)); + bool sideBValid = (G_validationFlag == VALIDATION_SIDE_B_TANGENT) + ? (areEqualPoints(midpointSideB, G_polygon[G_b])) + : (isPointOnLineSegment(midpointSideB, G_sideBStartVertex, G_sideBEndVertex)); - bool sideCValid = isPointOnLineSegment(midpointSideC, sideCStartVertex, sideCEndVertex); + bool sideCValid = isPointOnLineSegment(midpointSideC, G_sideCStartVertex, G_sideCEndVertex); return (sideAValid && sideBValid && sideCValid); } @@ -550,16 +564,16 @@ static bool isValidMinimalTriangle() { * @param area Area of the minimum area triangle enclosing the given polygon */ static void updateMinimumAreaEnclosingTriangle(std::vector &triangle, double &area) { - triangleArea = areaOfTriangle(vertexA, vertexB, vertexC); + G_triangleArea = areaOfTriangle(G_vertexA, G_vertexB, G_vertexC); - if (triangleArea < area) { + if (G_triangleArea < area) { triangle.clear(); - triangle.push_back(vertexA); - triangle.push_back(vertexB); - triangle.push_back(vertexC); + triangle.push_back(G_vertexA); + triangle.push_back(G_vertexB); + triangle.push_back(G_vertexC); - area = triangleArea; + area = G_triangleArea; } } @@ -567,8 +581,8 @@ static void updateMinimumAreaEnclosingTriangle(std::vector &triangl static bool middlePointOfSideB(cv::Point2f& middlePointOfSideB) { cv::Point2f vertexA, vertexC; - if ((!lineIntersection(sideBStartVertex, sideBEndVertex, sideCStartVertex, sideCEndVertex, vertexA)) || - (!lineIntersection(sideBStartVertex, sideBEndVertex, sideAStartVertex, sideAEndVertex, vertexC))) { + if ((!lineIntersection(G_sideBStartVertex, G_sideBEndVertex, G_sideCStartVertex, G_sideCEndVertex, vertexA)) || + (!lineIntersection(G_sideBStartVertex, G_sideBEndVertex, G_sideAStartVertex, G_sideAEndVertex, vertexC))) { return false; } @@ -586,7 +600,7 @@ static bool middlePointOfSideB(cv::Point2f& middlePointOfSideB) { * @param polygonPointIndex Index of the polygon point which is considered when determining the line */ static bool intersectsBelow(const cv::Point2f &gammaPoint, unsigned int polygonPointIndex) { - double angleOfGammaAndPoint = angleOfLineWrtOxAxis(polygon[polygonPointIndex], gammaPoint); + double angleOfGammaAndPoint = angleOfLineWrtOxAxis(G_polygon[polygonPointIndex], gammaPoint); return (intersects(angleOfGammaAndPoint, polygonPointIndex) == INTERSECTS_BELOW); } @@ -600,7 +614,7 @@ static bool intersectsBelow(const cv::Point2f &gammaPoint, unsigned int polygonP * @param polygonPointIndex Index of the polygon point which is considered when determining the line */ static bool intersectsAbove(const cv::Point2f &gammaPoint, unsigned int polygonPointIndex) { - double angleOfGammaAndPoint = angleOfLineWrtOxAxis(gammaPoint, polygon[polygonPointIndex]); + double angleOfGammaAndPoint = angleOfLineWrtOxAxis(gammaPoint, G_polygon[polygonPointIndex]); return (intersects(angleOfGammaAndPoint, polygonPointIndex) == INTERSECTS_ABOVE); } @@ -611,12 +625,12 @@ static bool intersectsAbove(const cv::Point2f &gammaPoint, unsigned int polygonP * @param polygonPointIndex Index of the polygon point which is considered when determining the line */ static unsigned int intersects(double angleGammaAndPoint, unsigned int polygonPointIndex) { - double anglePointPredecessor = angleOfLineWrtOxAxis(polygon[predecessor(polygonPointIndex)], - polygon[polygonPointIndex]); - double anglePointSuccessor = angleOfLineWrtOxAxis(polygon[successor(polygonPointIndex)], - polygon[polygonPointIndex]); - double angleFlushEdge = angleOfLineWrtOxAxis(polygon[predecessor(c)], - polygon[c]); + double anglePointPredecessor = angleOfLineWrtOxAxis(G_polygon[predecessor(polygonPointIndex)], + G_polygon[polygonPointIndex]); + double anglePointSuccessor = angleOfLineWrtOxAxis(G_polygon[successor(polygonPointIndex)], + G_polygon[polygonPointIndex]); + double angleFlushEdge = angleOfLineWrtOxAxis(G_polygon[predecessor(G_c)], + G_polygon[G_c]); if (isFlushAngleBtwPredAndSucc(angleFlushEdge, anglePointPredecessor, anglePointSuccessor)) { if ((isGammaAngleBtw(angleGammaAndPoint, anglePointPredecessor, angleFlushEdge)) || @@ -678,14 +692,15 @@ static bool gamma(unsigned int polygonPointIndex, cv::Point2f &gammaPoint) { cv::Point2f intersectionPoint1, intersectionPoint2; // Get intersection points if they exist - if (!findGammaIntersectionPoints(polygonPointIndex, polygon[a], polygon[predecessor(a)], polygon[c], - polygon[predecessor(c)], intersectionPoint1, intersectionPoint2)) { + if (!findGammaIntersectionPoints(polygonPointIndex, G_polygon[G_a], G_polygon[predecessor(G_a)], + G_polygon[G_c], G_polygon[predecessor(G_c)], + intersectionPoint1, intersectionPoint2)) { return false; } // Select the point which is on the same side of line C as the polygon - if (areOnTheSameSideOfLine(intersectionPoint1, polygon[successor(c)], - polygon[c], polygon[predecessor(c)])) { + if (areOnTheSameSideOfLine(intersectionPoint1, G_polygon[successor(G_c)], + G_polygon[G_c], G_polygon[predecessor(G_c)])) { gammaPoint = intersectionPoint1; } else { gammaPoint = intersectionPoint2; @@ -810,14 +825,15 @@ static cv::Point2f findVertexCOnSideB() { cv::Point2f intersectionPoint1, intersectionPoint2; // Get intersection points if they exist - if (!findGammaIntersectionPoints(predecessor(a), sideBStartVertex, sideBEndVertex, sideCStartVertex, - sideCEndVertex, intersectionPoint1, intersectionPoint2)) { + if (!findGammaIntersectionPoints(predecessor(G_a), G_sideBStartVertex, G_sideBEndVertex, + G_sideCStartVertex, G_sideCEndVertex, + intersectionPoint1, intersectionPoint2)) { CV_Error(cv::Error::StsInternal, ERR_VERTEX_C_ON_SIDE_B); } // Select the point which is on the same side of line C as the polygon - if (areOnTheSameSideOfLine(intersectionPoint1, polygon[successor(c)], - polygon[c], polygon[predecessor(c)])) { + if (areOnTheSameSideOfLine(intersectionPoint1, G_polygon[successor(G_c)], + G_polygon[G_c], G_polygon[predecessor(G_c)])) { return intersectionPoint1; } else { return intersectionPoint2; @@ -831,8 +847,8 @@ static cv::Point2f findVertexCOnSideB() { * @param polygonPoint Polygon point */ static double height(const cv::Point2f &polygonPoint) { - cv::Point2f pointC = polygon[c]; - cv::Point2f pointCPredecessor = polygon[predecessor(c)]; + cv::Point2f pointC = G_polygon[G_c]; + cv::Point2f pointCPredecessor = G_polygon[predecessor(G_c)]; return distanceFromPointToLine(polygonPoint, pointC, pointCPredecessor); } @@ -844,10 +860,10 @@ static double height(const cv::Point2f &polygonPoint) { * @param polygonPointIndex Index of the polygon point */ static double height(unsigned int polygonPointIndex) { - cv::Point2f pointC = polygon[c]; - cv::Point2f pointCPredecessor = polygon[predecessor(c)]; + cv::Point2f pointC = G_polygon[G_c]; + cv::Point2f pointCPredecessor = G_polygon[predecessor(G_c)]; - cv::Point2f polygonPoint = polygon[polygonPointIndex]; + cv::Point2f polygonPoint = G_polygon[polygonPointIndex]; return distanceFromPointToLine(polygonPoint, pointC, pointCPredecessor); } @@ -868,7 +884,7 @@ static void advance(unsigned int &index) { * @param index Index of the point */ static unsigned int successor(unsigned int index) { - return ((index + 1) % nrOfPoints); + return ((index + 1) % G_nrOfPoints); } //! Return the predecessor of the provided point index @@ -879,7 +895,7 @@ static unsigned int successor(unsigned int index) { * @param index Index of the point */ static unsigned int predecessor(unsigned int index) { - return (index == 0) ? (nrOfPoints - 1) + return (index == 0) ? (G_nrOfPoints - 1) : (index - 1); } @@ -1294,6 +1310,8 @@ static bool lessOrEqual(double number1, double number2) { return ((number1 < number2) || (almostEqual(number1, number2))); } +}; + ////////////////////////////////////////////// C API ///////////////////////////////////////////