double fermat_point(Point pt[], int n, Point& ptres){ Point u, v; double step = 0.0, curlen, explen, minlen; int i, j, k, idx; bool flag; u.x = u.y = v.x = v.y = 0.0; for(i = 0; i < n; ++i){ step += fabs(pt[i].x) + fabs(pt[i].y); u.x += pt[i].x; u.y += pt[i].y; } u.x /= n; u.y /= n; flag = 0; while(step > 1e-10){ for(k = 0; k < 10; step /= 2, ++k) for(i = -1; i <= 1; ++i) for(j = -1; j <= 1; ++j){ v.x = u.x + step*i; v.y = u.y + step*j; curlen = explen = 0.0; for(idx = 0; idx < n; ++idx){ curlen += pt_distance(u, pt[idx]); explen += pt_distance(v, pt[idx]); } if(curlen > explen){ u = v; minlen = explen; flag = 1; } } } ptres = u; return flag ? minlen : curlen; }
/** * Calculate the box->box distance. */ static double box2df_distance(const BOX2DF *a, const BOX2DF *b) { /* Check for overlap */ if ( box2df_overlaps(a, b) ) return 0.0; if ( box2df_left(a, b) ) { if ( box2df_above(a, b) ) return pt_distance(a->xmax, a->ymin, b->xmin, b->ymax); if ( box2df_below(a, b) ) return pt_distance(a->xmax, a->ymax, b->xmin, b->ymin); else return b->xmin - a->xmax; } if ( box2df_right(a, b) ) { if ( box2df_above(a, b) ) return pt_distance(a->xmin, a->ymin, b->xmax, b->ymax); if ( box2df_below(a, b) ) return pt_distance(a->xmin, a->ymax, b->xmax, b->ymin); else return a->xmin - b->xmax; } if ( box2df_above(a, b) ) { if ( box2df_left(a, b) ) return pt_distance(a->xmax, a->ymin, b->xmin, b->ymax); if ( box2df_right(a, b) ) return pt_distance(a->xmin, a->ymin, b->xmax, b->ymax); else return a->ymin - b->ymax; } if ( box2df_below(a, b) ) { if ( box2df_left(a, b) ) return pt_distance(a->xmax, a->ymax, b->xmin, b->ymin); if ( box2df_right(a, b) ) return pt_distance(a->xmin, a->ymax, b->xmax, b->ymin); else return b->ymin - a->ymax; } return MAXFLOAT; }