16acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*M/////////////////////////////////////////////////////////////////////////////////////// 26acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 36acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. 46acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 56acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// By downloading, copying, installing or using the software you agree to this license. 66acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// If you do not agree to this license, do not download, install, 76acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// copy or use the software. 86acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 96acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Intel License Agreement 116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// For Open Source Computer Vision Library 126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Copyright (C) 2000, Intel Corporation, all rights reserved. 146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Third party copyrights are property of their respective owners. 156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Redistribution and use in source and binary forms, with or without modification, 176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// are permitted provided that the following conditions are met: 186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// * Redistribution's of source code must retain the above copyright notice, 206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// this list of conditions and the following disclaimer. 216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// * Redistribution's in binary form must reproduce the above copyright notice, 236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// this list of conditions and the following disclaimer in the documentation 246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// and/or other materials provided with the distribution. 256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// * The name of Intel Corporation may not be used to endorse or promote products 276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// derived from this software without specific prior written permission. 286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// This software is provided by the copyright holders and contributors "as is" and 306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// any express or implied warranties, including, but not limited to, the implied 316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// warranties of merchantability and fitness for a particular purpose are disclaimed. 326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// In no event shall the Intel Corporation or contributors be liable for any direct, 336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// indirect, incidental, special, exemplary, or consequential damages 346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// (including, but not limited to, procurement of substitute goods or services; 356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// loss of use, data, or profits; or business interruption) however caused 366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// and on any theory of liability, whether in contract, strict liability, 376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// or tort (including negligence or otherwise) arising in any way out of 386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// the use of this software, even if advised of the possibility of such damage. 396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//M*/ 416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include "_cvaux.h" 436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#if 0 456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include <malloc.h> 476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//#include "decomppoly.h" 486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define ZERO_CLOSE 0.00001f 506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define ONE_CLOSE 0.99999f 516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define CHECK_COLLINEARITY(vec1_x,vec1_y,vec2_x,vec2_y) \ 536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( vec1_x == 0 ) { \ 546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( vec1_y * vec2_y > 0 ) { \ 556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return 0; \ 566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } \ 576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } \ 586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else { \ 596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( vec1_x * vec2_x > 0 ) { \ 606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return 0; \ 616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } \ 626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// determines if edge number one lies in counterclockwise 656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// earlier than edge number two 666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renninline int icvIsFirstEdgeClosier( int x0, 676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int y0, 686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int x0_end, 696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int y0_end, 706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int x1_end, 716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int y1_end, 726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int x2_end, 736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int y2_end ) 746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int mult, mult1, mult2; 766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int vec0_x, vec0_y; 776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int vec1_x, vec1_y; 786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int vec2_x, vec2_y; 796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn vec0_x = x0_end - x0; 816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn vec0_y = y0_end - y0; 826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn vec1_x = x1_end - x0; 836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn vec1_y = y1_end - y0; 846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn vec2_x = x2_end - x0; 856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn vec2_y = y2_end - y0; 866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mult1 = vec1_x * vec0_y - vec0_x * vec1_y; 886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mult2 = vec2_x * vec0_y - vec0_x * vec2_y; 896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( mult1 == 0 ) { 916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CHECK_COLLINEARITY( vec0_x, vec0_y, vec1_x, vec1_y ); 926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( mult2 == 0 ) { 946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CHECK_COLLINEARITY( vec0_x, vec0_y, vec2_x, vec2_y ); 956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( mult1 > 0 && mult2 < 0 ) { 976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return 1; 986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( mult1 < 0 && mult2 > 0 ) { 1006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return -1; 1016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 1026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mult = vec1_x * vec2_y - vec2_x * vec1_y; 1046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( mult == 0 ) { 1056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CHECK_COLLINEARITY( vec1_x, vec1_y, vec2_x, vec2_y ); 1066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 1076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( mult1 > 0 ) 1096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 1106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( mult > 0 ) { 1116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return -1; 1126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 1136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else { 1146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return 1; 1156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 1166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } // if( mult1 > 0 ) 1176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 1186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 1196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( mult1 != 0 ) { 1206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( mult > 0 ) { 1216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return 1; 1226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 1236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else { 1246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return -1; 1256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 1266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } // if( mult1 != 0 ) 1276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else { 1286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( mult2 > 0 ) { 1296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return -1; 1306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 1316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else { 1326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return 1; 1336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 1346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } // if( mult1 != 0 ) else 1356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } // if( mult1 > 0 ) else 1376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} // icvIsFirstEdgeClosier 1396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennbool icvEarCutTriangulation( CvPoint* contour, 1416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int num, 1426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int* outEdges, 1436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int* numEdges ) 1446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 1456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int i; 1466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int notFoundFlag = 0; 1476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int begIndex = -1; 1486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int isInternal; 1496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int currentNum = num; 1506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int index1, index2, index3; 1516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int ix0, iy0, ix1, iy1, ix2, iy2; 1526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int x1, y1, x2, y2, x3, y3; 1536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int dx1, dy1, dx2, dy2; 1546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int* pointExist = ( int* )0; 1556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int det, det1, det2; 1566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float t1, t2; 1576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (*numEdges) = 0; 1596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( num <= 2 ) { 1616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return false; 1626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 1636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn pointExist = ( int* )malloc( num * sizeof( int ) ); 1656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < num; i ++ ) { 1676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn pointExist[i] = 1; 1686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 1696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < num; i ++ ) { 1716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn outEdges[ (*numEdges) * 2 ] = i; 1726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( i != num - 1 ) { 1736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn outEdges[ (*numEdges) * 2 + 1 ] = i + 1; 1746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 1756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else { 1766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn outEdges[ (*numEdges) * 2 + 1 ] = 0; 1776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 1786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (*numEdges) ++; 1796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } // for( i = 0; i < num; i ++ ) 1806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // initializing data before while cycle 1826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn index1 = 0; 1836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn index2 = 1; 1846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn index3 = 2; 1856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn x1 = contour[ index1 ].x; 1866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn y1 = contour[ index1 ].y; 1876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn x2 = contour[ index2 ].x; 1886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn y2 = contour[ index2 ].y; 1896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn x3 = contour[ index3 ].x; 1906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn y3 = contour[ index3 ].y; 1916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( currentNum > 3 ) 1936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 1946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn dx1 = x2 - x1; 1956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn dy1 = y2 - y1; 1966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn dx2 = x3 - x2; 1976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn dy2 = y3 - y2; 1986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( dx1 * dy2 - dx2 * dy1 < 0 ) // convex condition 1996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 2006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // checking for noncrossing edge 2016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ix1 = x3 - x1; 2026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn iy1 = y3 - y1; 2036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn isInternal = 1; 2046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < num; i ++ ) 2056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 2066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( i != num - 1 ) { 2076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ix2 = contour[ i + 1 ].x - contour[ i ].x; 2086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn iy2 = contour[ i + 1 ].y - contour[ i ].y; 2096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 2106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else { 2116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ix2 = contour[ 0 ].x - contour[ i ].x; 2126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn iy2 = contour[ 0 ].y - contour[ i ].y; 2136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 2146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ix0 = contour[ i ].x - x1; 2156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn iy0 = contour[ i ].y - y1; 2166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn det = ix2 * iy1 - ix1 * iy2; 2186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn det1 = ix2 * iy0 - ix0 * iy2; 2196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( det != 0.0f ) 2206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 2216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn t1 = ( ( float )( det1 ) ) / det; 2226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( t1 > ZERO_CLOSE && t1 < ONE_CLOSE ) 2236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 2246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn det2 = ix1 * iy0 - ix0 * iy1; 2256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn t2 = ( ( float )( det2 ) ) / det; 2266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( t2 > ZERO_CLOSE && t2 < ONE_CLOSE ) { 2276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn isInternal = 0; 2286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 2296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } // if( t1 > ZERO_CLOSE && t1 < ONE_CLOSE ) 2316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } // if( det != 0.0f ) 2336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } // for( i = 0; i < (*numEdges); i ++ ) 2356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( isInternal ) 2376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 2386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // this edge is internal 2396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn notFoundFlag = 0; 2406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn outEdges[ (*numEdges) * 2 ] = index1; 2416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn outEdges[ (*numEdges) * 2 + 1 ] = index3; 2426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (*numEdges) ++; 2436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn pointExist[ index2 ] = 0; 2446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn index2 = index3; 2456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn x2 = x3; 2466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn y2 = y3; 2476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn currentNum --; 2486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( currentNum >= 3 ) { 2496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn do { 2506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn index3 ++; 2516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( index3 == num ) { 2526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn index3 = 0; 2536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 2546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } while( !pointExist[ index3 ] ); 2556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn x3 = contour[ index3 ].x; 2566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn y3 = contour[ index3 ].y; 2576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } // if( currentNum >= 3 ) 2586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } // if( isInternal ) 2606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else { 2616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // this edge intersects some other initial edges 2626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !notFoundFlag ) { 2636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn notFoundFlag = 1; 2646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn begIndex = index1; 2656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 2666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn index1 = index2; 2676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn x1 = x2; 2686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn y1 = y2; 2696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn index2 = index3; 2706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn x2 = x3; 2716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn y2 = y3; 2726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn do { 2736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn index3 ++; 2746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( index3 == num ) { 2756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn index3 = 0; 2766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 2776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( index3 == begIndex ) { 2786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( pointExist ) { 2796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn free( pointExist ); 2806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 2816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return false; 2826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 2836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } while( !pointExist[ index3 ] ); 2846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn x3 = contour[ index3 ].x; 2856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn y3 = contour[ index3 ].y; 2866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } // if( isInternal ) else 2876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } // if( dx1 * dy2 - dx2 * dy1 < 0 ) 2896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 2906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 2916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !notFoundFlag ) { 2926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn notFoundFlag = 1; 2936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn begIndex = index1; 2946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 2956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn index1 = index2; 2966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn x1 = x2; 2976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn y1 = y2; 2986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn index2 = index3; 2996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn x2 = x3; 3006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn y2 = y3; 3016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn do { 3026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn index3 ++; 3036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( index3 == num ) { 3046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn index3 = 0; 3056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( index3 == begIndex ) { 3076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( pointExist ) { 3086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn free( pointExist ); 3096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return false; 3116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } while( !pointExist[ index3 ] ); 3136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn x3 = contour[ index3 ].x; 3146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn y3 = contour[ index3 ].y; 3156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } // if( dx1 * dy2 - dx2 * dy1 < 0 ) else 3166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } // while( currentNum > 3 ) 3186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( pointExist ) { 3206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn free( pointExist ); 3216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return true; 3246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} // icvEarCutTriangulation 3266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renninline bool icvFindTwoNeighbourEdges( CvPoint* contour, 3286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int* edges, 3296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int numEdges, 3306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int vtxIdx, 3316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int mainEdgeIdx, 3326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int* leftEdgeIdx, 3336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int* rightEdgeIdx ) 3346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 3356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int i; 3366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int compRes; 3376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int vec0_x, vec0_y; 3386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int x0, y0, x0_end, y0_end; 3396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int x1_left = 0, y1_left = 0, x1_right = 0, y1_right = 0, x2, y2; 3406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (*leftEdgeIdx) = -1; 3426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (*rightEdgeIdx) = -1; 3436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( edges[ mainEdgeIdx * 2 ] == vtxIdx ) { 3456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn x0 = contour[ vtxIdx ].x; 3466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn y0 = contour[ vtxIdx ].y; 3476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn x0_end = contour[ edges[ mainEdgeIdx * 2 + 1 ] ].x; 3486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn y0_end = contour[ edges[ mainEdgeIdx * 2 + 1 ] ].y; 3496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn vec0_x = x0_end - x0; 3506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn vec0_y = y0_end - y0; 3516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else { 3536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn //x0 = contour[ edges[ mainEdgeIdx * 2 ] ].x; 3546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn //y0 = contour[ edges[ mainEdgeIdx * 2 ] ].y; 3556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn //x0_end = contour[ vtxIdx ].x; 3566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn //y0_end = contour[ vtxIdx ].y; 3576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn x0 = contour[ vtxIdx ].x; 3586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn y0 = contour[ vtxIdx ].y; 3596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn x0_end = contour[ edges[ mainEdgeIdx * 2 ] ].x; 3606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn y0_end = contour[ edges[ mainEdgeIdx * 2 ] ].y; 3616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn vec0_x = x0_end - x0; 3626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn vec0_y = y0_end - y0; 3636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < numEdges; i ++ ) 3666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 3676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( ( i != mainEdgeIdx ) && 3686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ( edges[ i * 2 ] == vtxIdx || edges[ i * 2 + 1 ] == vtxIdx ) ) 3696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 3706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( (*leftEdgeIdx) == -1 ) 3716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 3726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (*leftEdgeIdx) = (*rightEdgeIdx) = i; 3736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( edges[ i * 2 ] == vtxIdx ) { 3746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn x1_left = x1_right = contour[ edges[ i * 2 + 1 ] ].x; 3756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn y1_left = y1_right = contour[ edges[ i * 2 + 1 ] ].y; 3766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else { 3786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn x1_left = x1_right = contour[ edges[ i * 2 ] ].x; 3796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn y1_left = y1_right = contour[ edges[ i * 2 ] ].y; 3806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } // if( (*leftEdgeIdx) == -1 ) 3836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 3846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 3856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( edges[ i * 2 ] == vtxIdx ) { 3866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn x2 = contour[ edges[ i * 2 + 1 ] ].x; 3876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn y2 = contour[ edges[ i * 2 + 1 ] ].y; 3886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else { 3906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn x2 = contour[ edges[ i * 2 ] ].x; 3916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn y2 = contour[ edges[ i * 2 ] ].y; 3926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn compRes = icvIsFirstEdgeClosier( x0, 3956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn y0, x0_end, y0_end, x1_left, y1_left, x2, y2 ); 3966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( compRes == 0 ) { 3976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return false; 3986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( compRes == -1 ) { 4006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (*leftEdgeIdx) = i; 4016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn x1_left = x2; 4026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn y1_left = y2; 4036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } // if( compRes == -1 ) 4046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else { 4056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn compRes = icvIsFirstEdgeClosier( x0, 4066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn y0, x0_end, y0_end, x1_right, y1_right, x2, y2 ); 4076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( compRes == 0 ) { 4086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return false; 4096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 4106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( compRes == 1 ) { 4116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (*rightEdgeIdx) = i; 4126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn x1_right = x2; 4136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn y1_right = y2; 4146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 4156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } // if( compRes == -1 ) else 4176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } // if( (*leftEdgeIdx) == -1 ) else 4196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } // if( ( i != mainEdgesIdx ) && ... 4216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } // for( i = 0; i < numEdges; i ++ ) 4236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return true; 4256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} // icvFindTwoNeighbourEdges 4276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennbool icvFindReferences( CvPoint* contour, 4296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int num, 4306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int* outEdges, 4316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int* refer, 4326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int* numEdges ) 4336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 4346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int i; 4356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int currPntIdx; 4366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int leftEdgeIdx, rightEdgeIdx; 4376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( icvEarCutTriangulation( contour, num, outEdges, numEdges ) ) 4396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 4406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < (*numEdges); i ++ ) 4416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 4426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn refer[ i * 4 ] = -1; 4436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn refer[ i * 4 + 1 ] = -1; 4446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn refer[ i * 4 + 2 ] = -1; 4456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn refer[ i * 4 + 3 ] = -1; 4466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } // for( i = 0; i < (*numEdges); i ++ ) 4476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < (*numEdges); i ++ ) 4496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 4506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn currPntIdx = outEdges[ i * 2 ]; 4516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !icvFindTwoNeighbourEdges( contour, 4526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn outEdges, (*numEdges), currPntIdx, 4536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn i, &leftEdgeIdx, &rightEdgeIdx ) ) 4546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 4556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return false; 4566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } // if( !icvFindTwoNeighbourEdges( contour, ... 4576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 4586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 4596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( outEdges[ leftEdgeIdx * 2 ] == currPntIdx ) { 4606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( refer[ i * 4 ] == -1 ) { 4616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn refer[ i * 4 ] = ( leftEdgeIdx << 2 ); 4626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 4636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 4646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else { 4656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( refer[ i * 4 ] == -1 ) { 4666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn refer[ i * 4 ] = ( leftEdgeIdx << 2 ) | 2; 4676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 4686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 4696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( outEdges[ rightEdgeIdx * 2 ] == currPntIdx ) { 4706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( refer[ i * 4 + 1 ] == -1 ) { 4716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn refer[ i * 4 + 1 ] = ( rightEdgeIdx << 2 ) | 3; 4726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 4736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 4746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else { 4756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( refer[ i * 4 + 1 ] == -1 ) { 4766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn refer[ i * 4 + 1 ] = ( rightEdgeIdx << 2 ) | 1; 4776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 4786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 4796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } // if( !icvFindTwoNeighbourEdges( contour, ... ) else 4816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn currPntIdx = outEdges[ i * 2 + 1 ]; 4836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( i == 18 ) { 4846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn i = i; 4856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 4866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !icvFindTwoNeighbourEdges( contour, 4876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn outEdges, (*numEdges), currPntIdx, 4886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn i, &leftEdgeIdx, &rightEdgeIdx ) ) 4896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 4906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return false; 4916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } // if( !icvFindTwoNeighbourEdges( contour, ... 4926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 4936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 4946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( outEdges[ leftEdgeIdx * 2 ] == currPntIdx ) { 4956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( refer[ i * 4 + 3 ] == -1 ) { 4966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn refer[ i * 4 + 3 ] = ( leftEdgeIdx << 2 ); 4976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 4986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 4996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else { 5006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( refer[ i * 4 + 3 ] == -1 ) { 5016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn refer[ i * 4 + 3 ] = ( leftEdgeIdx << 2 ) | 2; 5026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 5036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 5046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( outEdges[ rightEdgeIdx * 2 ] == currPntIdx ) { 5056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( refer[ i * 4 + 2 ] == -1 ) { 5066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn refer[ i * 4 + 2 ] = ( rightEdgeIdx << 2 ) | 3; 5076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 5086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 5096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else { 5106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( refer[ i * 4 + 2 ] == -1 ) { 5116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn refer[ i * 4 + 2 ] = ( rightEdgeIdx << 2 ) | 1; 5126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 5136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 5146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } // if( !icvFindTwoNeighbourEdges( contour, ... ) else 5166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } // for( i = 0; i < (*numEdges); i ++ ) 5186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } // if( icvEarCutTriangulation( contour, num, outEdges, numEdges ) ) 5206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else { 5216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return false; 5226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } // if( icvEarCutTriangulation( contour, num, outEdges, ... ) else 5236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return true; 5256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} // icvFindReferences 5276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid cvDecompPoly( CvContour* cont, 5296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSubdiv2D** subdiv, 5306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvMemStorage* storage ) 5316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 5326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int* memory; 5336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvPoint* contour; 5346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int* outEdges; 5356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int* refer; 5366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSubdiv2DPoint** pntsPtrs; 5376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvQuadEdge2D** edgesPtrs; 5386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int numVtx; 5396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int numEdges; 5406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int i; 5416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSeqReader reader; 5426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvPoint2D32f pnt; 5436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvQuadEdge2D* quadEdge; 5446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn numVtx = cont -> total; 5466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( numVtx < 3 ) { 5476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return; 5486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 5496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn *subdiv = ( CvSubdiv2D* )0; 5516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn memory = ( int* )malloc( sizeof( int ) * ( numVtx * 2 5536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn + numVtx * numVtx * 2 * 5 ) 5546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn + sizeof( CvQuadEdge2D* ) * ( numVtx * numVtx ) 5556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn + sizeof( CvSubdiv2DPoint* ) * ( numVtx * 2 ) ); 5566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn contour = ( CvPoint* )memory; 5576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn outEdges = ( int* )( contour + numVtx ); 5586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn refer = outEdges + numVtx * numVtx * 2; 5596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn edgesPtrs = ( CvQuadEdge2D** )( refer + numVtx * numVtx * 4 ); 5606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn pntsPtrs = ( CvSubdiv2DPoint** )( edgesPtrs + numVtx * numVtx ); 5616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvStartReadSeq( ( CvSeq* )cont, &reader, 0 ); 5636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < numVtx; i ++ ) 5646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 5656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_READ_SEQ_ELEM( (contour[ i ]), reader ); 5666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } // for( i = 0; i < numVtx; i ++ ) 5676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !icvFindReferences( contour, numVtx, outEdges, refer, &numEdges ) ) 5696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 5706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn free( memory ); 5716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return; 5726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } // if( !icvFindReferences( contour, numVtx, outEdges, refer, ... 5736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn *subdiv = cvCreateSubdiv2D( CV_SEQ_KIND_SUBDIV2D, 5756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sizeof( CvSubdiv2D ), 5766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sizeof( CvSubdiv2DPoint ), 5776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sizeof( CvQuadEdge2D ), 5786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn storage ); 5796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < numVtx; i ++ ) 5816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 5826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn pnt.x = ( float )contour[ i ].x; 5836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn pnt.y = ( float )contour[ i ].y; 5846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn pntsPtrs[ i ] = cvSubdiv2DAddPoint( *subdiv, pnt, 0 ); 5856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } // for( i = 0; i < numVtx; i ++ ) 5866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < numEdges; i ++ ) 5886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 5896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn edgesPtrs[ i ] = ( CvQuadEdge2D* ) 5906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ( cvSubdiv2DMakeEdge( *subdiv ) & 0xfffffffc ); 5916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } // for( i = 0; i < numEdges; i ++ ) 5926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < numEdges; i ++ ) 5946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 5956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn quadEdge = edgesPtrs[ i ]; 5966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn quadEdge -> next[ 0 ] = 5976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ( ( CvSubdiv2DEdge )edgesPtrs[ refer[ i * 4 ] >> 2 ] ) 5986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn | ( refer[ i * 4 ] & 3 ); 5996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn quadEdge -> next[ 1 ] = 6006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ( ( CvSubdiv2DEdge )edgesPtrs[ refer[ i * 4 + 1 ] >> 2 ] ) 6016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn | ( refer[ i * 4 + 1 ] & 3 ); 6026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn quadEdge -> next[ 2 ] = 6036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ( ( CvSubdiv2DEdge )edgesPtrs[ refer[ i * 4 + 2 ] >> 2 ] ) 6046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn | ( refer[ i * 4 + 2 ] & 3 ); 6056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn quadEdge -> next[ 3 ] = 6066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ( ( CvSubdiv2DEdge )edgesPtrs[ refer[ i * 4 + 3 ] >> 2 ] ) 6076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn | ( refer[ i * 4 + 3 ] & 3 ); 6086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn quadEdge -> pt[ 0 ] = pntsPtrs[ outEdges[ i * 2 ] ]; 6096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn quadEdge -> pt[ 1 ] = ( CvSubdiv2DPoint* )0; 6106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn quadEdge -> pt[ 2 ] = pntsPtrs[ outEdges[ i * 2 + 1 ] ]; 6116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn quadEdge -> pt[ 3 ] = ( CvSubdiv2DPoint* )0; 6126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } // for( i = 0; i < numEdges; i ++ ) 6136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (*subdiv) -> topleft.x = ( float )cont -> rect.x; 6156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (*subdiv) -> topleft.y = ( float )cont -> rect.y; 6166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (*subdiv) -> bottomright.x = 6176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ( float )( cont -> rect.x + cont -> rect.width ); 6186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (*subdiv) -> bottomright.y = 6196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ( float )( cont -> rect.y + cont -> rect.height ); 6206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn free( memory ); 6226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return; 6236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} // cvDecompPoly 6256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#endif 6276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// End of file decomppoly.cpp 6296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 630