点的覆盖圆

1.问题提出
已知平面上8个点的坐标为:(3,6) (7,2) (9,5) (1,7) (3,1) (8,2) (4,5) (2,8),试求覆盖8个点的覆盖圆的最小半径。

2.设计思路
①若最小圆的圆周上只有两个点,则这两个点的连线定为圆的走私。
②若最小贺的圆周上有3个(或3个以上)点,则最小圆为这3个(或3个以上)点的外接圆。
求外接圆的步骤如下:
⑴求出两点(x1,y1)、(x2,y2)的距离L1:
L1=sqrt((x1-x2)^2+(y1-y2)^2)
⑵已知三边长L1、L2、L3,求三角形面积:
L=(L1+L2+L3)/2 (半周长)
⑶据公式4SR=L1*L2*L3,求外接圆半径R:
R=L1*L2*L3/(4*S)
因此,求覆盖n个点的最小圆,只要分别求出所有3点组合覆盖的最小圆,取其中半径最大者即为所求。
确定覆盖3点的最小圆:若存在一边的平方和大于或等于另两边的平方和,即为3点组成直角或钝角三角形,或3点共线,此时,最小圆的直径为最长边。
否则,3点组成锐角三角形,最小圆为3点的外接圆。
通过设置循环对n个点穷举所有的3点组合,比较所有最小圆半径取其最大值。

3.代码实现

// 点的覆盖圆的程序设计 // 求覆盖n个点的最小圆 #include <math.h> #include <stdio.h> int main(void) { int i, n, a, b, c, a0, b0, c0, am, bm, cm, t, w; double L, L1, L2, L3, r, s, max = 0; double x[50], y[50]; printf("输入点数n:"); // 确定已知点的点数 scanf("%d", &n); for (i = 1; i <= n; i++) { printf("请输入第%d个点的坐标:", i); scanf("%lf%lf", &x[i], &y[i]); } // a, b, c三重循环穷举所有三点组合 for (a = 1; a <= n - 2; a++) { for (b = a + 1; b <= n -1; b++) for (c = b + 1; c <= n; c++) { L1 = sqrt((x[b] - x[c]) * (x[b] - x[c]) + (y[b] - y[c]) * (y[b] - y[c])); L2 = sqrt((x[a] - x[c]) * (x[a] - x[c]) + (y[a] - y[c]) * (y[a] - y[c])); L3 = sqrt((x[b] - x[a]) * (x[b] - x[a]) + (y[b] - y[a]) * (y[b] - y[a])); L = (L1 + L2 + L3) / 2; s = sqrt(L * (L - L1) * (L - L2) * (L - L3)); // 三角形面积 // 直角钝角或共线时,r为最长边的一半 if (L2 * L2 + L3 * L3 <= L1 * L1) { r = L1 / 2; b0 = b; c0 = c; t = 1; } else if (L3 * L3 + L1 * L1 <= L2 * L2) { r = L2 / 2; a0 = a; c0 = c; t = 2; } else if (L1 * L1 + L2 * L2 <= L3 * L3) { r = L3 / 2; a0 = a; b0 = b; t = 3; } else { r = L1 * L2 * L3 / (4 * s); // 求外接圆半径r a0 = a; b0 = b; c0 = c; t = 0; } if (r > max) { max = r; w = t; am = a0; bm = b0; cm = c0; } } } printf("以上%d个点覆盖圆的最小半径为:%.4f/n", n, max); printf("在覆盖圆的圆周上的点分别为:"); if (!w) // w= 0最小圆为三点外接圆 printf("(%g,%g), (%g, %g), (%g, %g)", x[am], y[am], x[bm], y[bm], x[cm], y[cm]); else if (1 == w) printf("(%g,%g), (%g, %g)", x[bm], y[bm], x[cm], y[cm]); else if (2 == w) printf("(%g,%g), (%g, %g)", x[am], y[am], x[cm], y[cm]); else if (3 == w) printf("(%g,%g), (%g, %g)", x[am], y[am], x[bm], y[bm]); putchar('/n'); return 0; }

你可能感兴趣的:(c)