inline static long double brutal(unsigned int q, unsigned int s) { long double res = (1 << 30), act = 0; std::pair<long double, long double> P; if(q + 1 == divs || s + 1 == points) { res = 0; P = findCircle(s, points).first; qPoint[q] = P; for(unsigned int p = s; p < points; ++ p) res = MAX(res, dist(P, point[p])); return res; } for(unsigned int e = s + 1; e < points; ++ e) { act = 0; P = findCircle(s, e).first; qPoint[q] = P; for(unsigned int p = s; p < e; ++ p) act = MAX(act, dist(P, point[p])); act = MAX(act, brutal(q + 1, e)); if(act == best) return act; res = MIN(res, act); } return res; }
static int findEnslosingCicle4pts_32f( Point2f* pts, Point2f& _center, float& _radius ) { int shuffles[4][4] = { {0, 1, 2, 3}, {0, 1, 3, 2}, {2, 3, 0, 1}, {2, 3, 1, 0} }; int idxs[4] = { 0, 1, 2, 3 }; int i, j, k = 1, mi = 0; float max_dist = 0; Point2f center; Point2f min_center; float radius, min_radius = FLT_MAX; Point2f res_pts[4]; center = min_center = pts[0]; radius = 1.f; for( i = 0; i < 4; i++ ) for( j = i + 1; j < 4; j++ ) { float dist = (float)norm(pts[i] - pts[j]); if( max_dist < dist ) { max_dist = dist; idxs[0] = i; idxs[1] = j; } } if( max_dist > 0 ) { k = 2; for( i = 0; i < 4; i++ ) { for( j = 0; j < k; j++ ) if( i == idxs[j] ) break; if( j == k ) idxs[k++] = i; } center = Point2f( (pts[idxs[0]].x + pts[idxs[1]].x)*0.5f, (pts[idxs[0]].y + pts[idxs[1]].y)*0.5f ); radius = (float)(norm(pts[idxs[0]] - center)*1.03); if( radius < 1.f ) radius = 1.f; if( pointInCircle( pts[idxs[2]], center, radius ) >= 0 && pointInCircle( pts[idxs[3]], center, radius ) >= 0 ) { k = 2; //rand()%2+2; } else { mi = -1; for( i = 0; i < 4; i++ ) { if( findCircle( pts[shuffles[i][0]], pts[shuffles[i][1]], pts[shuffles[i][2]], ¢er, &radius ) ) { radius *= 1.03f; if( radius < 2.f ) radius = 2.f; if( pointInCircle( pts[shuffles[i][3]], center, radius ) >= 0 && min_radius > radius ) { min_radius = radius; min_center = center; mi = i; } } } CV_Assert( mi >= 0 ); if( mi < 0 ) mi = 0; k = 3; center = min_center; radius = min_radius; for( i = 0; i < 4; i++ ) idxs[i] = shuffles[mi][i]; } } _center = center; _radius = radius; /* reorder output points */ for( i = 0; i < 4; i++ ) res_pts[i] = pts[idxs[i]]; for( i = 0; i < 4; i++ ) { pts[i] = res_pts[i]; CV_Assert( pointInCircle( pts[i], center, radius ) >= 0 ); } return k; }