任意给出平面上n个点的坐标,试求覆盖这n个点的圆的最小半径。写C语言程序
时间: 2024-02-15 15:02:07 浏览: 64
最小圆覆盖算法(C#)
以下是使用C语言实现Welzl算法求解最小圆覆盖问题的代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#define MAX_POINTS 1000
struct Point {
double x, y;
};
struct Circle {
struct Point center;
double radius;
};
double distance(struct Point a, struct Point b) {
double dx = a.x - b.x;
double dy = a.y - b.y;
return sqrt(dx*dx + dy*dy);
}
struct Circle circle_from_points(struct Point a, struct Point b) {
struct Circle circle;
circle.center.x = (a.x + b.x) / 2;
circle.center.y = (a.y + b.y) / 2;
circle.radius = distance(a, b) / 2;
return circle;
}
struct Circle circle_from_points_3(struct Point a, struct Point b, struct Point c) {
double A = a.x - b.x;
double B = a.y - b.y;
double C = a.x - c.x;
double D = a.y - c.y;
double E = A*(a.x + b.x) + B*(a.y + b.y);
double F = C*(a.x + c.x) + D*(a.y + c.y);
double G = 2*(A*(c.y - b.y) - B*(c.x - b.x));
if (G == 0) {
struct Circle circle = { {0, 0}, INFINITY };
return circle;
}
double center_x = (D*E - B*F) / G;
double center_y = (A*F - C*E) / G;
struct Point center = { center_x, center_y };
double radius = distance(center, a);
struct Circle circle = { center, radius };
return circle;
}
struct Circle circle_from_points_bounding(struct Point* points, int n, struct Point p) {
struct Circle circle = { p, 0 };
for (int i = 0; i < n; i++) {
if (distance(circle.center, points[i]) > circle.radius) {
if (circle.center.x == p.x && circle.center.y == p.y) {
circle = circle_from_points(points[i], p);
} else {
circle = circle_from_points_3(points[i], p, points[(i+1)%n]);
}
}
}
return circle;
}
struct Circle welzl(struct Point* points, struct Point* boundary, int n, int b) {
struct Circle circle = { {0, 0}, INFINITY };
if (b == 3) {
circle = circle_from_points_3(boundary[0], boundary[1], boundary[2]);
} else if (n == 0 && b == 2) {
circle = circle_from_points(boundary[0], boundary[1]);
} else if (n == 1 && b == 1) {
circle.center = points[0];
circle.radius = 0;
} else if (n == 0 && b == 1) {
circle.center = boundary[0];
circle.radius = 0;
} else {
n--;
struct Circle d = welzl(points+1, boundary, n, b);
if (distance(d.center, points[0]) > d.radius) {
boundary[b++] = points[0];
circle = welzl(points+1, boundary, n, b-1);
b--;
} else {
circle = d;
}
}
return circle;
}
struct Circle min_circle(struct Point* points, int n) {
struct Point boundary[3];
srand(time(NULL));
for (int i = 0; i < 3; i++) {
boundary[i] = points[i];
}
return welzl(points+3, boundary, n-3, 3);
}
int main() {
int n;
printf("Enter the number of points: ");
scanf("%d", &n);
struct Point points[MAX_POINTS];
printf("Enter the coordinates of the points:\n");
for (int i = 0; i < n; i++) {
scanf("%lf %lf", &points[i].x, &points[i].y);
}
struct Circle circle = min_circle(points, n);
printf("Minimum circle: center = (%.2lf, %.2lf), radius = %.2lf\n", circle.center.x, circle.center.y, circle.radius);
return 0;
}
```
注意,该程序假设输入的点集中至少有三个点,且不会进行输入校验。
阅读全文