1298 圆与三角形(板子)

给出圆的圆心和半径,以及三角形的三个顶点,问圆同三角形是否相交。相交输出"Yes",否则输出"No"。(三角形的面积大于0)。
在这里插入图片描述
在这里插入图片描述
输入
第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)
输出
共T行,对于每组输入数据,相交输出"Yes",否则输出"No"。
输入样例

2
0 0 10
10 0
15 0
15 5
0 0 10
0 0
5 0
5 5
输出样例
Yes
No
板子来源

#include<bits/stdc++.h>
using namespace std;
struct Point{//点 
	double x,y;
	Point(){};
	Point(double x,double y):x(x),y(y){}
	Point operator - (const Point &a)const //向量减
	{
	 return Point(x-a.x,y-a.y); 
	} 
	double operator ^(const Point &a)const//向量积sin
	{
	 return x*a.y-y*a.x;
	} 
	double operator *(const Point &a)const//点积cos
	{
	 return x*a.x+y*a.y;	
	} 
};
struct Circle{//圆 
	double x,y,r;
	Circle(){}
	Circle(double x,double y,double r):x(x),y(y),r(r){}
};
//默认 是 返还true  否 返回false 
bool Cross(const Point&p1,const Point&p2,const Point&p3,const Point&p4) 
{
//判断向量p1p2是否跨立p3p4 
 double a1=(p3-p1)^(p2-p1);
 double a2=(p4-p1)^(p2-p1);
 if(a1*a2>0)//同向
  return false;
 return true;	
}
//判断线段p1p2与圆是否相交 
bool Lcc(Point p1,Point p2,Circle c)
{
 bool flag1=(p1.x-c.x)*(p1.x-c.x)+(p1.y-c.y)*(p1.y-c.y)<=c.r*c.r;
 //判断点p1是否在圆内
 bool flag2=(p2.x-c.x)*(p2.x-c.x)+(p2.y-c.y)*(p2.y-c.y)<=c.r*c.r;
 //判断点p2是否在圆内
 if(flag1&&flag2)//两点都在圆内,不相交 
  return false; 
 if(flag1||flag2)//一点在圆内,一点在圆外,相交 
  return true; 
 //两点在圆外,判断形成的线段是否与圆相交
 double A,B,C,dis1,dis2,angle1,angle2;
 //将直线p1p2化为一般式:Ax+By+C=0的形式,先化为两点式,然后由两点式得出一般式 
 A=p1.y-p2.y;
 B=p2.x-p1.x;
 C=p1.x*p2.y-p2.x*p1.y;
 //使用距离公式判断圆心到直线ax+by+c=0的距离是否大于半径
 dis1=A*c.x+B*c.y+C;
 dis1*=dis1;
 dis2=(A*A+B*B)*c.r*c.r;
 if(dis1>dis2)//距离大于半径 
  return false; 
 angle1=(c.x-p1.x)*(p2.x-p1.x)+(c.y-p1.y)*(p2.y-p1.y);//c-p1与p1p2夹角
 angle2=(c.x-p2.x)*(p1.x-p2.x)+(c.y-p2.y)*(p1.y-p2.y);//c-p2与p1p2夹角  
 if(angle1>0&&angle2>0)//都是锐角 相交 
  return true;
 return false; 
} 
int main()
{
 int t;
 cin>>t;
 while(t--)
 {
 	Point p1,p2,p3;
 	Circle c;
	cin>>c.x>>c.y>>c.r; 
 	cin>>p1.x>>p1.y>>p2.x>>p2.y>>p3.x>>p3.y;
    if(Lcc(p1,p2,c)||Lcc(p2,p3,c)||Lcc(p1,p3,c))
 	 cout<<"Yes\n";
 	else cout<<"No\n";
 }
 return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值