欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

51Nod 1298 圆与三角形 计算几何

程序员文章站 2022-04-01 16:53:13
...

51Nod-1298-圆与三角形

给出圆的圆心和半径,以及三角形的三个顶点,问圆同三角形是否相交。相交输出"Yes",否则输出"No"。(三角形的面积大于0)。

Input

 第1行:一个数T,表示输入的测试数量(1 <= T <= 10000),之后每4行用来描述一组测试数据。

4-1:三个数,前两个数为圆心的坐标xc, yc,第3个数为圆的半径R。(-3000 <= xc, yc <= 3000, 1 <= R <= 3000)
4-2:2个数,三角形第1个点的坐标。
4-3:2个数,三角形第2个点的坐标。

4-4:2个数,三角形第3个点的坐标。(-3000 <= xi, yi <= 3000)

 Output 

 共T行,对于每组输入数据,相交输出"Yes",否则输出"No"。 

 Sample Input

2
0 0 10
10 0
15 0
15 5
0 0 10
0 0
5 0
5 5

Sample Output

Yes
No

分析:

样例1的解释

51Nod 1298 圆与三角形 计算几何

样例2的解释

51Nod 1298 圆与三角形 计算几何

1.三点全部在圆内,输出No 
2.三点全部在圆外
重点:判断三角形三条边是否存在和圆相交的点
问题就转化为判断线段是否与圆相交

3.其他情况全部是相交  

51Nod 1298 圆与三角形 计算几何

核心代码:

//判断线段是否和圆相交
bool seg_circle(Point p1, Point p2)
{
	ll a, b, c, dis1, dis2, angle1, angle2;//ax+by+c=0
	if (p1.x == p2.x)
	{
		a = 1;b = 0;c = -p1.x;//垂直于x轴 
	}
	else if (p1.y == p2.y) {
		a = 0;b = 1;c = -p1.y;//垂直于y轴 
	}
	else {
		a = p1.y - p2.y;
		b = p2.x - p1.x;
		c = p1.x*p2.y - p1.y*p2.x;
	}

	dis1 = a*o.x + b*o.y + c;
	dis1 *= dis1;
	dis2 = (a*a + b*b)*r*r;
	if (dis1>dis2)
		return 0;

	angle1 = (o.x - p1.x)*(p2.x - p1.x) + (o.y - p1.y)*(p2.y - p1.y);
	angle2 = (o.x - p2.x)*(p1.x - p2.x) + (o.y - p2.y)*(p1.y - p2.y);
	if (angle1>0 && angle2>0)
		return 1;

	return 0;
}

AC代码

#include<cstdio>
using namespace std;
typedef long long ll;
struct Point {
	ll x, y;
}p[4];
Point o;//圆心 
ll r;//半径 

	 //距离的平方 
ll distance(Point a, Point b)
{
	return (a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y);
}

//判断线段是否和圆相交
bool seg_circle(Point p1, Point p2)
{
	ll a, b, c, dis1, dis2, angle1, angle2;//ax+by+c=0
	if (p1.x == p2.x)
	{
		a = 1;b = 0;c = -p1.x;//垂直于x轴 
	}
	else if (p1.y == p2.y) {
		a = 0;b = 1;c = -p1.y;//垂直于y轴 
	}
	else {
		a = p1.y - p2.y;
		b = p2.x - p1.x;
		c = p1.x*p2.y - p1.y*p2.x;
	}

	dis1 = a*o.x + b*o.y + c;
	dis1 *= dis1;
	dis2 = (a*a + b*b)*r*r;
	if (dis1>dis2)
		return 0;

	angle1 = (o.x - p1.x)*(p2.x - p1.x) + (o.y - p1.y)*(p2.y - p1.y);
	angle2 = (o.x - p2.x)*(p1.x - p2.x) + (o.y - p2.y)*(p1.y - p2.y);
	if (angle1>0 && angle2>0)
		return 1;

	return 0;
}
//判断圆和三角形是否相交 
bool intersect()
{
	ll d0 = distance(o, p[0]), d1 = distance(o, p[1]),  d2 = distance(o, p[2]);
	ll r2 = r*r;

	//三点在圆内 
	if (d0<r2&&d1<r2&&d2<r2)
		return 0;

	//三点在圆外 
	else if (d0>r2&&d1>r2&&d2>r2)
		return seg_circle(p[0], p[1]) || seg_circle(p[0], p[2]) || seg_circle(p[1], p[2]);
	return 1;
}
int main()
{
	//ios::sync_with_stdio(0);
	int t;
	scanf("%d", &t);
	while (t--) {
		scanf("%lld%lld%lld", &o.x, &o.y, &r);
		for (int i = 0;i<3;i++)
			scanf("%lld%lld", &p[i].x, &p[i].y);
		printf("%s\n", intersect() ? "Yes" : "No");
	}
	return 0;
}