判断圆与三角形是否有交点
2015-10-03 10:32
495 查看
#include <bits/stdc++.h>
using namespace std;
const double eps = 1e-7;
struct Point
{
double x,y;
Point (double x = 0,double y = 0):x(x),y(y) {} };
typedef Point Vector;
Vector operator+ (Vector A,Vector B)
{
return Vector(A.x+B.x,A.y+B.y);
}
Vector operator- (Vector A,Vector B)
{
return Vector(A.x-B.x,A.y-B.y);
}
Vector operator* (Vector A,double p)
{
return Vector(A.x*p,A.y*p);
}
Vector operator/ (Vector A,double p)
{
return Vector(A.x/p,A.y/p);
}
bool operator<(const Point& a,const Point& b)
{
return a.x<b.x||(a.x==b.x&&a.y<b.y);
}
int dcmp(double x)
{
if (fabs(x)<eps) return 0;
return x<0?-1:1;
}
bool operator== (const Point& a,const Point& b)
{
return dcmp(a.x-b.x)==0 && dcmp(a.y-b.y)==0;
}
//极角 = atan2(y,x); 单位弧度
double Dot(Vector A,Vector B)
{
return A.x*B.x+A.y*B.y; //cos符号一致
}
double Length(Vector A)
{
return sqrt(Dot(A,A));
}
double Angle(Vector A,Vector B)
{
return acos(Dot(A,B)/Length(A)/Length(B)); //向量ab的夹角,范围为在0,pi
}
double Cross(Vector A,Vector B)
{
return A.x*B.y-A.y*B.x; //sin符号一致
}
double Area2(Point A,Point B,Point C)
{
return Cross(B-A,C-A);
}
Vector Rotate(Vector A,double rad)
{
return Vector(A.x*cos(rad)-A.y*sin(rad),A.x*sin(rad)+A.y*cos(rad));
}
Vector Normal(Vector A)
{
double L = Length(A); //法向量
return Vector(-A.y/L,A.x/L);
}
//圆相关
struct Line
{
Point p;
Vector v;
double ang; // 极角,即从x正半轴旋转到向量v所需要的角(弧度)
Line() {}
Line(Point P, Vector v):p(P),v(v)
{
ang = atan2(v.y, v.x);
}
Point point (double t)
{
return Point(p+v*t);
}
Line Move(double d)
{
return Line(p + Normal(v)*d, v); //平移
}
bool operator < (const Line& L) const
{
return ang < L.ang;
}
};
struct Circle
{
Point c;
double r;
Circle(Point c,double r) :c(c),r(r) {};
Point point (double a)
{
return Point(c.x+cos(a)*r,c.y+sin(a)*r);
}
};
//直线和圆的交点
int getLineCircleIntersection(Line L,Circle C,double &t1,double &t2,vector<Point>& sol)//返回交点的个数
{
double a = L.v.x, b = L.p.x - C.c.x, c = L.v.y, d = L.p.y - C.c.y;
double e = a*a + c*c,f = 2*(a*b+c*d),g= b*b+d*d-C.r*C.r;
double delta = f*f - 4*e*g;
if (dcmp(delta)<0) return 0;
if (dcmp(delta)==0)
{
t1 = t2 = -f/(2*e);
sol.push_back(L.point(t1));
return 1;
}
t1 = (-f-sqrt(delta))/(2*e);
sol.push_back(L.point(t1));
t2 = (-f+sqrt(delta))/(2*e);
sol.push_back(L.point(t2));
return 2;
}
int f(Point a,Point b,Circle c)
{
Vector v = (Vector)
{
b.x-a.x,b.y-a.y
};
Line l(a,v);
vector<Point>sol;
double t1,t2;
int ans = getLineCircleIntersection(l,c,t1,t2,sol);
if (!ans) return 0;
if (ans==1)
{
return ( dcmp(t1)>=0 && dcmp(t1-1)<=0 );
}
else if (ans==2)
{
return ( dcmp(t1)>=0 && dcmp(t1-1)<=0 )||( dcmp(t2)>=0 && dcmp(t2-1)<=0 );
}
return 0;
}
int main()
{
Point o,a,b,c;
double r;
int T ;
cin>>T;
while (T--)
{
cin>>o.x>>o.y>>r;
Circle C(o,r);
cin>>a.x>>a.y;
cin>>b.x>>b.y;
cin>>c.x>>c.y;
if ( f(a,b,C) || f(a,c,C)||f(b,c,C))
puts("Yes");
else puts("No");
}
return 0;
}
using namespace std;
const double eps = 1e-7;
struct Point
{
double x,y;
Point (double x = 0,double y = 0):x(x),y(y) {} };
typedef Point Vector;
Vector operator+ (Vector A,Vector B)
{
return Vector(A.x+B.x,A.y+B.y);
}
Vector operator- (Vector A,Vector B)
{
return Vector(A.x-B.x,A.y-B.y);
}
Vector operator* (Vector A,double p)
{
return Vector(A.x*p,A.y*p);
}
Vector operator/ (Vector A,double p)
{
return Vector(A.x/p,A.y/p);
}
bool operator<(const Point& a,const Point& b)
{
return a.x<b.x||(a.x==b.x&&a.y<b.y);
}
int dcmp(double x)
{
if (fabs(x)<eps) return 0;
return x<0?-1:1;
}
bool operator== (const Point& a,const Point& b)
{
return dcmp(a.x-b.x)==0 && dcmp(a.y-b.y)==0;
}
//极角 = atan2(y,x); 单位弧度
double Dot(Vector A,Vector B)
{
return A.x*B.x+A.y*B.y; //cos符号一致
}
double Length(Vector A)
{
return sqrt(Dot(A,A));
}
double Angle(Vector A,Vector B)
{
return acos(Dot(A,B)/Length(A)/Length(B)); //向量ab的夹角,范围为在0,pi
}
double Cross(Vector A,Vector B)
{
return A.x*B.y-A.y*B.x; //sin符号一致
}
double Area2(Point A,Point B,Point C)
{
return Cross(B-A,C-A);
}
Vector Rotate(Vector A,double rad)
{
return Vector(A.x*cos(rad)-A.y*sin(rad),A.x*sin(rad)+A.y*cos(rad));
}
Vector Normal(Vector A)
{
double L = Length(A); //法向量
return Vector(-A.y/L,A.x/L);
}
//圆相关
struct Line
{
Point p;
Vector v;
double ang; // 极角,即从x正半轴旋转到向量v所需要的角(弧度)
Line() {}
Line(Point P, Vector v):p(P),v(v)
{
ang = atan2(v.y, v.x);
}
Point point (double t)
{
return Point(p+v*t);
}
Line Move(double d)
{
return Line(p + Normal(v)*d, v); //平移
}
bool operator < (const Line& L) const
{
return ang < L.ang;
}
};
struct Circle
{
Point c;
double r;
Circle(Point c,double r) :c(c),r(r) {};
Point point (double a)
{
return Point(c.x+cos(a)*r,c.y+sin(a)*r);
}
};
//直线和圆的交点
int getLineCircleIntersection(Line L,Circle C,double &t1,double &t2,vector<Point>& sol)//返回交点的个数
{
double a = L.v.x, b = L.p.x - C.c.x, c = L.v.y, d = L.p.y - C.c.y;
double e = a*a + c*c,f = 2*(a*b+c*d),g= b*b+d*d-C.r*C.r;
double delta = f*f - 4*e*g;
if (dcmp(delta)<0) return 0;
if (dcmp(delta)==0)
{
t1 = t2 = -f/(2*e);
sol.push_back(L.point(t1));
return 1;
}
t1 = (-f-sqrt(delta))/(2*e);
sol.push_back(L.point(t1));
t2 = (-f+sqrt(delta))/(2*e);
sol.push_back(L.point(t2));
return 2;
}
int f(Point a,Point b,Circle c)
{
Vector v = (Vector)
{
b.x-a.x,b.y-a.y
};
Line l(a,v);
vector<Point>sol;
double t1,t2;
int ans = getLineCircleIntersection(l,c,t1,t2,sol);
if (!ans) return 0;
if (ans==1)
{
return ( dcmp(t1)>=0 && dcmp(t1-1)<=0 );
}
else if (ans==2)
{
return ( dcmp(t1)>=0 && dcmp(t1-1)<=0 )||( dcmp(t2)>=0 && dcmp(t2-1)<=0 );
}
return 0;
}
int main()
{
Point o,a,b,c;
double r;
int T ;
cin>>T;
while (T--)
{
cin>>o.x>>o.y>>r;
Circle C(o,r);
cin>>a.x>>a.y;
cin>>b.x>>b.y;
cin>>c.x>>c.y;
if ( f(a,b,C) || f(a,c,C)||f(b,c,C))
puts("Yes");
else puts("No");
}
return 0;
}
相关文章推荐
- [经济学原理|政治部分]劳动价值理论
- 1.3.3 打开A20,实现32位寻址
- Linux中的查看已挂载的文件系统命令
- 图的邻接链表
- HDU 2520 我是菜鸟,我怕谁(水~)
- 字符函数lpad,rpad,ltrim,rtrim,substr使用
- [Qt] qtcreator 中打开console
- wamp下配置Smarty
- linux进程间通信方式之匿名管道http://blog.csdn.net/guoyang1007/article/details/4720984
- Repeated DNA Sequences
- HTTP协议笔记
- webstorm9.3 安装less 编译css教程
- HTML初步学习10
- n皇后问题
- HDU 2519 新生晚会(水~)
- 86. Partition List (List)
- 1.3.2 设置中断描述符表和全局描述符表
- MySql存储过程 MySql存储过程详解
- 日经春秋 20151003
- JS中的定时器