圆形是否与多边形重叠

c++

Posted by YiMiTuMi on December 22, 2023

圆形是否与多边形重叠

只需要计算多边形的每个顶点,和每个顶点的连线是否小于圆的半径就可以了。

注意:判断点到每条边的最短距离用的线是线段而不是直线。

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))  //判断是否重叠
	{
		//没有重叠,换下一个区域
		
	}	
}