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#include "_cv.h" 426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef struct 446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int bottom; 466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int left; 476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float height; 486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float width; 496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float base_a; 506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float base_b; 516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvMinAreaState; 536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define CV_CALIPERS_MAXHEIGHT 0 556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define CV_CALIPERS_MINAREARECT 1 566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define CV_CALIPERS_MAXDIST 2 576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*F/////////////////////////////////////////////////////////////////////////////////////// 596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Name: icvRotatingCalipers 606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Purpose: 616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Rotating calipers algorithm with some applications 626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Context: 646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Parameters: 656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// points - convex hull vertices ( any orientation ) 666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// n - number of vertices 676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// mode - concrete application of algorithm 686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// can be CV_CALIPERS_MAXDIST or 696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// CV_CALIPERS_MINAREARECT 706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// left, bottom, right, top - indexes of extremal points 716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// out - output info. 726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// In case CV_CALIPERS_MAXDIST it points to float value - 736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// maximal height of polygon. 746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// In case CV_CALIPERS_MINAREARECT 756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// ((CvPoint2D32f*)out)[0] - corner 766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// ((CvPoint2D32f*)out)[1] - vector1 776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// ((CvPoint2D32f*)out)[0] - corner2 786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// ^ 806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// | 816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// vector2 | 826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// | 836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// |____________\ 846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// corner / 856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// vector1 866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Returns: 886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Notes: 896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//F*/ 906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* we will use usual cartesian coordinates */ 926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void 936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvRotatingCalipers( CvPoint2D32f* points, int n, int mode, float* out ) 946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float minarea = FLT_MAX; 966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float max_dist = 0; 976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn char buffer[32]; 986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int i, k; 996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvPoint2D32f* vect = (CvPoint2D32f*)cvAlloc( n * sizeof(vect[0]) ); 1006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float* inv_vect_length = (float*)cvAlloc( n * sizeof(inv_vect_length[0]) ); 1016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int left = 0, bottom = 0, right = 0, top = 0; 1026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int seq[4] = { -1, -1, -1, -1 }; 1036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* rotating calipers sides will always have coordinates 1056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (a,b) (-b,a) (-a,-b) (b, -a) 1066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn */ 1076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* this is a first base bector (a,b) initialized by (1,0) */ 1086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float orientation = 0; 1096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float base_a; 1106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float base_b = 0; 1116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float left_x, right_x, top_y, bottom_y; 1136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvPoint2D32f pt0 = points[0]; 1146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn left_x = right_x = pt0.x; 1166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn top_y = bottom_y = pt0.y; 1176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < n; i++ ) 1196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 1206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double dx, dy; 1216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( pt0.x < left_x ) 1236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn left_x = pt0.x, left = i; 1246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( pt0.x > right_x ) 1266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn right_x = pt0.x, right = i; 1276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( pt0.y > top_y ) 1296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn top_y = pt0.y, top = i; 1306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( pt0.y < bottom_y ) 1326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn bottom_y = pt0.y, bottom = i; 1336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvPoint2D32f pt = points[(i+1) & (i+1 < n ? -1 : 0)]; 1356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn dx = pt.x - pt0.x; 1376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn dy = pt.y - pt0.y; 1386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn vect[i].x = (float)dx; 1406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn vect[i].y = (float)dy; 1416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn inv_vect_length[i] = (float)(1./sqrt(dx*dx + dy*dy)); 1426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn pt0 = pt; 1446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 1456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn //cvbInvSqrt( inv_vect_length, inv_vect_length, n ); 1476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* find convex hull orientation */ 1496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 1506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double ax = vect[n-1].x; 1516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double ay = vect[n-1].y; 1526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < n; i++ ) 1546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 1556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double bx = vect[i].x; 1566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double by = vect[i].y; 1576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double convexity = ax * by - ay * bx; 1596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( convexity != 0 ) 1616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 1626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn orientation = (convexity > 0) ? 1.f : (-1.f); 1636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 1646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 1656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ax = bx; 1666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ay = by; 1676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 1686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn assert( orientation != 0 ); 1696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 1706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn base_a = orientation; 1716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*****************************************************************************************/ 1736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* init calipers position */ 1746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn seq[0] = bottom; 1756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn seq[1] = right; 1766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn seq[2] = top; 1776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn seq[3] = left; 1786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*****************************************************************************************/ 1796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Main loop - evaluate angles and rotate calipers */ 1806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* all of edges will be checked while rotating calipers by 90 degrees */ 1826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( k = 0; k < n; k++ ) 1836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 1846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* sinus of minimal angle */ 1856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /*float sinus;*/ 1866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* compute cosine of angle between calipers side and polygon edge */ 1886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* dp - dot product */ 1896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float dp0 = base_a * vect[seq[0]].x + base_b * vect[seq[0]].y; 1906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float dp1 = -base_b * vect[seq[1]].x + base_a * vect[seq[1]].y; 1916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float dp2 = -base_a * vect[seq[2]].x - base_b * vect[seq[2]].y; 1926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float dp3 = base_b * vect[seq[3]].x - base_a * vect[seq[3]].y; 1936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float cosalpha = dp0 * inv_vect_length[seq[0]]; 1956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float maxcos = cosalpha; 1966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* number of calipers edges, that has minimal angle with edge */ 1986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int main_element = 0; 1996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* choose minimal angle */ 2016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cosalpha = dp1 * inv_vect_length[seq[1]]; 2026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn maxcos = (cosalpha > maxcos) ? (main_element = 1, cosalpha) : maxcos; 2036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cosalpha = dp2 * inv_vect_length[seq[2]]; 2046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn maxcos = (cosalpha > maxcos) ? (main_element = 2, cosalpha) : maxcos; 2056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cosalpha = dp3 * inv_vect_length[seq[3]]; 2066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn maxcos = (cosalpha > maxcos) ? (main_element = 3, cosalpha) : maxcos; 2076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /*rotate calipers*/ 2096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 2106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn //get next base 2116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int pindex = seq[main_element]; 2126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float lead_x = vect[pindex].x*inv_vect_length[pindex]; 2136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float lead_y = vect[pindex].y*inv_vect_length[pindex]; 2146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn switch( main_element ) 2156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 2166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn case 0: 2176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn base_a = lead_x; 2186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn base_b = lead_y; 2196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 2206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn case 1: 2216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn base_a = lead_y; 2226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn base_b = -lead_x; 2236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 2246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn case 2: 2256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn base_a = -lead_x; 2266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn base_b = -lead_y; 2276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 2286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn case 3: 2296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn base_a = -lead_y; 2306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn base_b = lead_x; 2316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 2326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn default: assert(0); 2336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 2346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 2356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* change base point of main edge */ 2366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn seq[main_element] += 1; 2376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn seq[main_element] = (seq[main_element] == n) ? 0 : seq[main_element]; 2386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn switch (mode) 2416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 2426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn case CV_CALIPERS_MAXHEIGHT: 2436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 2446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* now main element lies on edge alligned to calipers side */ 2456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* find opposite element i.e. transform */ 2476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* 0->2, 1->3, 2->0, 3->1 */ 2486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int opposite_el = main_element ^ 2; 2496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float dx = points[seq[opposite_el]].x - points[seq[main_element]].x; 2516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float dy = points[seq[opposite_el]].y - points[seq[main_element]].y; 2526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float dist; 2536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( main_element & 1 ) 2556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn dist = (float)fabs(dx * base_a + dy * base_b); 2566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 2576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn dist = (float)fabs(dx * (-base_b) + dy * base_a); 2586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( dist > max_dist ) 2606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn max_dist = dist; 2616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 2636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 2646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn case CV_CALIPERS_MINAREARECT: 2656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* find area of rectangle */ 2666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 2676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float height; 2686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float area; 2696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* find vector left-right */ 2716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float dx = points[seq[1]].x - points[seq[3]].x; 2726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float dy = points[seq[1]].y - points[seq[3]].y; 2736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* dotproduct */ 2756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float width = dx * base_a + dy * base_b; 2766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* find vector left-right */ 2786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn dx = points[seq[2]].x - points[seq[0]].x; 2796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn dy = points[seq[2]].y - points[seq[0]].y; 2806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* dotproduct */ 2826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn height = -dx * base_b + dy * base_a; 2836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn area = width * height; 2856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( area <= minarea ) 2866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 2876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float *buf = (float *) buffer; 2886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn minarea = area; 2906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* leftist point */ 2916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ((int *) buf)[0] = seq[3]; 2926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn buf[1] = base_a; 2936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn buf[2] = width; 2946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn buf[3] = base_b; 2956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn buf[4] = height; 2966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* bottom point */ 2976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ((int *) buf)[5] = seq[0]; 2986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn buf[6] = area; 2996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 3016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } /*switch */ 3036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } /* for */ 3046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn switch (mode) 3066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 3076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn case CV_CALIPERS_MINAREARECT: 3086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 3096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float *buf = (float *) buffer; 3106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float A1 = buf[1]; 3126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float B1 = buf[3]; 3136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float A2 = -buf[3]; 3156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float B2 = buf[1]; 3166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float C1 = A1 * points[((int *) buf)[0]].x + points[((int *) buf)[0]].y * B1; 3186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float C2 = A2 * points[((int *) buf)[5]].x + points[((int *) buf)[5]].y * B2; 3196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float idet = 1.f / (A1 * B2 - A2 * B1); 3216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float px = (C1 * B2 - C2 * B1) * idet; 3236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float py = (A1 * C2 - A2 * C1) * idet; 3246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn out[0] = px; 3266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn out[1] = py; 3276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn out[2] = A1 * buf[2]; 3296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn out[3] = B1 * buf[2]; 3306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn out[4] = A2 * buf[4]; 3326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn out[5] = B2 * buf[4]; 3336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 3356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn case CV_CALIPERS_MAXHEIGHT: 3366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 3376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn out[0] = max_dist; 3386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 3406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvFree( &vect ); 3436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvFree( &inv_vect_length ); 3446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 3456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL CvBox2D 3486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvMinAreaRect2( const CvArr* array, CvMemStorage* storage ) 3496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 3506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvMemStorage* temp_storage = 0; 3516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvBox2D box; 3526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvPoint2D32f* points = 0; 3536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvMinAreaRect2" ); 3556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn memset(&box, 0, sizeof(box)); 3576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 3596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int i, n; 3616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSeqReader reader; 3626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvContour contour_header; 3636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSeqBlock block; 3646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSeq* ptseq = (CvSeq*)array; 3656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvPoint2D32f out[3]; 3666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( CV_IS_SEQ(ptseq) ) 3686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 3696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !CV_IS_SEQ_POINT_SET(ptseq) && 3706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (CV_SEQ_KIND(ptseq) != CV_SEQ_KIND_CURVE || !CV_IS_SEQ_CONVEX(ptseq) || 3716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_SEQ_ELTYPE(ptseq) != CV_SEQ_ELTYPE_PPOINT )) 3726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsUnsupportedFormat, 3736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn "Input sequence must consist of 2d points or pointers to 2d points" ); 3746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !storage ) 3756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn storage = ptseq->storage; 3766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 3786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 3796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( ptseq = cvPointSeqFromMat( 3806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_SEQ_KIND_GENERIC, array, &contour_header, &block )); 3816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( storage ) 3846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 3856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( temp_storage = cvCreateChildMemStorage( storage )); 3866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 3886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 3896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( temp_storage = cvCreateMemStorage(1 << 10)); 3906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !CV_IS_SEQ_CONVEX( ptseq )) 3936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 3946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( ptseq = cvConvexHull2( ptseq, temp_storage, CV_CLOCKWISE, 1 )); 3956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else if( !CV_IS_SEQ_POINT_SET( ptseq )) 3976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 3986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSeqWriter writer; 3996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !CV_IS_SEQ(ptseq->v_prev) || !CV_IS_SEQ_POINT_SET(ptseq->v_prev)) 4016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsBadArg, 4026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn "Convex hull must have valid pointer to point sequence stored in v_prev" ); 4036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvStartReadSeq( ptseq, &reader ); 4046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvStartWriteSeq( CV_SEQ_KIND_CURVE|CV_SEQ_FLAG_CONVEX|CV_SEQ_ELTYPE(ptseq->v_prev), 4056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sizeof(CvContour), CV_ELEM_SIZE(ptseq->v_prev->flags), 4066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn temp_storage, &writer ); 4076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < ptseq->total; i++ ) 4096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 4106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvPoint pt = **(CvPoint**)(reader.ptr); 4116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_WRITE_SEQ_ELEM( pt, writer ); 4126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 4136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ptseq = cvEndWriteSeq( &writer ); 4156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 4166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn n = ptseq->total; 4186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( points = (CvPoint2D32f*)cvAlloc( n*sizeof(points[0]) )); 4206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvStartReadSeq( ptseq, &reader ); 4216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( CV_SEQ_ELTYPE( ptseq ) == CV_32SC2 ) 4236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 4246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < n; i++ ) 4256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 4266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvPoint pt; 4276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_READ_SEQ_ELEM( pt, reader ); 4286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn points[i].x = (float)pt.x; 4296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn points[i].y = (float)pt.y; 4306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 4316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 4326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 4336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 4346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < n; i++ ) 4356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 4366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_READ_SEQ_ELEM( points[i], reader ); 4376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 4386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 4396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( n > 2 ) 4416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 4426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn icvRotatingCalipers( points, n, CV_CALIPERS_MINAREARECT, (float*)out ); 4436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn box.center.x = out[0].x + (out[1].x + out[2].x)*0.5f; 4446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn box.center.y = out[0].y + (out[1].y + out[2].y)*0.5f; 4456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn box.size.height = (float)sqrt((double)out[1].x*out[1].x + (double)out[1].y*out[1].y); 4466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn box.size.width = (float)sqrt((double)out[2].x*out[2].x + (double)out[2].y*out[2].y); 4476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn box.angle = (float)atan2( -(double)out[1].y, (double)out[1].x ); 4486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 4496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else if( n == 2 ) 4506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 4516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn box.center.x = (points[0].x + points[1].x)*0.5f; 4526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn box.center.y = (points[0].y + points[1].y)*0.5f; 4536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double dx = points[1].x - points[0].x; 4546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double dy = points[1].y - points[0].y; 4556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn box.size.height = (float)sqrt(dx*dx + dy*dy); 4566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn box.size.width = 0; 4576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn box.angle = (float)atan2( -dy, dx ); 4586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 4596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 4606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 4616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( n == 1 ) 4626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn box.center = points[0]; 4636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 4646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn box.angle = (float)(box.angle*180/CV_PI); 4666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 4686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvReleaseMemStorage( &temp_storage ); 4706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvFree( &points ); 4716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return box; 4736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 4746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 475