C#实现的最小圆覆盖算法。给定一个点(x,y)的列表,返回圆心坐标和半径
时间: 2024-03-08 21:51:30 浏览: 81
最小圆覆盖算法(C#)
以下是C#实现的最小圆覆盖算法:
```csharp
using System;
using System.Collections.Generic;
public class Point
{
public double X { get; set; }
public double Y { get; set; }
public Point(double x, double y)
{
X = x;
Y = y;
}
}
public class Circle
{
public Point Center { get; set; }
public double Radius { get; set; }
public Circle(Point center, double radius)
{
Center = center;
Radius = radius;
}
}
public static class MinimumEnclosingCircle
{
public static Circle GetMinimumEnclosingCircle(List<Point> points)
{
if (points.Count == 0)
{
throw new ArgumentException("List of points must not be empty");
}
else if (points.Count == 1)
{
return new Circle(points[0], 0);
}
else if (points.Count == 2)
{
double radius = Math.Sqrt(Math.Pow(points[1].X - points[0].X, 2) + Math.Pow(points[1].Y - points[0].Y, 2)) / 2;
double centerX = (points[0].X + points[1].X) / 2;
double centerY = (points[0].Y + points[1].Y) / 2;
return new Circle(new Point(centerX, centerY), radius);
}
else
{
// Initialize circle
Circle circle = GetCircleFromThreePoints(points[0], points[1], points[2]);
// Iterate over remaining points
for (int i = 3; i < points.Count; i++)
{
Point p = points[i];
// If point is outside circle, create new circle with this point on the boundary
if (PointDistance(p, circle.Center) > circle.Radius)
{
circle = GetCircleFromPointsOnBoundary(points.GetRange(0, i + 1), p);
}
}
return circle;
}
}
private static Circle GetCircleFromThreePoints(Point p1, Point p2, Point p3)
{
double a = p2.X - p1.X;
double b = p2.Y - p1.Y;
double c = p3.X - p1.X;
double d = p3.Y - p1.Y;
double e = a * (p1.X + p2.X) + b * (p1.Y + p2.Y);
double f = c * (p1.X + p3.X) + d * (p1.Y + p3.Y);
double g = 2 * (a * (p3.Y - p2.Y) - b * (p3.X - p2.X));
if (g == 0)
{
throw new Exception("Points are colinear");
}
double centerX = (d * e - b * f) / g;
double centerY = (a * f - c * e) / g;
double radius = Math.Sqrt(Math.Pow(p1.X - centerX, 2) + Math.Pow(p1.Y - centerY, 2));
return new Circle(new Point(centerX, centerY), radius);
}
private static Circle GetCircleFromPointsOnBoundary(List<Point> boundaryPoints, Point p)
{
Circle circle = GetCircleFromTwoPoints(boundaryPoints[0], p);
for (int i = 1; i < boundaryPoints.Count; i++)
{
Point q = boundaryPoints[i];
if (PointDistance(q, circle.Center) > circle.Radius)
{
circle = GetCircleFromThreePoints(boundaryPoints[0], q, p);
for (int j = 0; j < i; j++)
{
Point r = boundaryPoints[j];
if (PointDistance(r, circle.Center) > circle.Radius)
{
circle = GetCircleFromThreePoints(r, q, p);
}
}
}
}
return circle;
}
private static Circle GetCircleFromTwoPoints(Point p1, Point p2)
{
double radius = Math.Sqrt(Math.Pow(p2.X - p1.X, 2) + Math.Pow(p2.Y - p1.Y, 2)) / 2;
double centerX = (p1.X + p2.X) / 2;
double centerY = (p1.Y + p2.Y) / 2;
return new Circle(new Point(centerX, centerY), radius);
}
private static double PointDistance(Point p1, Point p2)
{
return Math.Sqrt(Math.Pow(p2.X - p1.X, 2) + Math.Pow(p2.Y - p1.Y, 2));
}
}
```
该算法的思路是:先通过三个点构建一个圆,然后逐个添加剩余的点,并且检查它们是否在圆内。如果新加入的点不在圆内,则创建一个新的圆,将新点置于边界上,然后将前面的点添加到边界上,直到新圆包含所有的点。
要使用该算法,只需将点列表传递给 `GetMinimumEnclosingCircle` 方法即可。该方法将返回一个 Circle 对象,其中包含圆心坐标和半径。
阅读全文