圆形是否与多边形重叠
只需要计算多边形的每个顶点,和每个顶点的连线是否小于圆的半径就可以了。
注意:判断点到每条边的最短距离用的线是线段而不是直线。
typedef struct {
int x, y;
} Point;
//点到点的距离
double distanceT(Point p1, Point p2)
{
return sqrt(pow(p2.x - p1.x, 2) + pow(p2.y - p1.y, 2));
}
//获取点到线段的距离
double distanceToLineSegment(Point start, Point end, Point external)
{
double len = distanceT(start, end);
if (len == 0) { // 线段长度为0,即线段为点
return distanceT(external, start);
}
double r = ((external.x - start.x) * (end.x - start.x) + (external.y - start.y) * (end.y - start.y)) / pow(len, 2);
if (r <= 0) { // 垂足在p1处
return distanceT(external, start);
}
else if (r >= 1) { // 垂足在p2处
return distanceT(external, end);
}
else { // 垂足在线段上
Point foot = { start.x + r * (end.x - start.x), start.y + r * (end.y - start.y) };
return distanceT(external, foot);
}
}
double distance(Point p1, Point p2)
{
return sqrt(pow(p2.x - p1.x, 2) + pow(p2.y - p1.y, 2));
}
bool is_inside_polygon(Point point, std::vector<Point>& polygon, int n) {
int count = 0;
for (int i = 0, j = n - 1; i < n; j = i++) {
if (((polygon[i].y > point.y) != (polygon[j].y > point.y)) &&
(point.x < (polygon[j].x - polygon[i].x) * (point.y - polygon[i].y) / (polygon[j].y - polygon[i].y) + polygon[i].x)) {
count++;
}
}
return count % 2 == 1;
}
bool is_overlap_with_polygon(Point circleCenter, int radius, std::vector<Point>& polygon)
{
for (int i = 0; i < polygon.size(); ++i)
{
//判断边
for (int j = i + 1; j < polygon.size(); j++)
{
double b = distanceToLineSegment(polygon[i], polygon[j], circleCenter);
if (b <= radius)
{
return true;
}
}
//判断点
if (is_inside_polygon(polygon[i], polygon, polygon.size()))
{
if (distance(circleCenter, polygon[i]) <= radius)
{
return true;
}
}
}
return false;
}
mian函数
int mian()
{
Point circleCenter; //圆的坐标
int iRadial = 1600; //圆的半径
std::vector<Point> polygon; //保存区域顶点坐标
if (!is_overlap_with_polygon(circleCenter, iRadial, polygon)) //判断是否重叠
{
//没有重叠,换下一个区域
}
}