求凸多边形外接圆最大半径

点击查看代码
#include<cstdio>
#include<cmath>
#pragma warning(disable:4996)
const double PI = acos(-1.0);
const double eps = 1e-5;//比较精度

//求圆心角之和
double totalCornerAngles(double edges[], int n, double r){
    double sum = 0.0;
    for (int i = 0; i < n; i++) {
        sum += asin(edges[i] / 2 / r) * 2;
    }                          
    return sum;
}

//二分法求半径
int main(){
    double edges[10];//存储每条边长度,最多10条边
    int N;//边数
    scanf("%d", &N);//输入边数 

    double sum;//圆心角之和
    double maxAngle = 0.0;//最长边对应的圆心角
    double maxEdge = 0.0;//最长边

    //初始化edges
    for (int i = 0; i < N; i++) {
        scanf("%lf", &edges[i]); //读取每条边的长度
        if (edges[i] > maxEdge)
            maxEdge = edges[i];//保存最长边
    }
    //以最长边为直径求圆心角之和,若为2pi则直接返回
    sum = totalCornerAngles(edges, N, maxEdge / 2);
    if (fabs(sum - PI * 2) < eps) {
        printf("外接圆的最大半径是最大边的一半:%.2f", maxEdge / 2);
        return 0;
    }

    //半径大于最大边的一半(即斜边大于直角边)
    double left = maxEdge / 2, right = 10000000, mid;
    double other = 0;

    //在误差范围内循环求解
    while (right - left > eps) {
        mid = (right + left) / 2;
        maxAngle = asin(maxEdge / 2 / mid) * 2;//求出最大边对应的圆心角
        sum = totalCornerAngles(edges, N, mid);
        other = sum - maxAngle;
        //如果除去最大圆心角的其他圆心角之和小于pi,说明圆心在多边形外面
        if (other < PI){
            sum = other + 2 * PI - maxAngle;
            if (sum < 2 * PI)
                left = mid;
            else
                right = mid;
        }
        //圆心在多边形里面
        else {
            if (sum > 2 * PI)
                left = mid;
            else
                right = mid;
        }
    }
    printf("外接圆的最大半径是:%.2f", mid);
    return 0;
}

posted @ 2022-09-28 22:17  zhaoo_o  阅读(11)  评论(0编辑  收藏  举报