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