计算几何-hdoj-1221-Rectangle and Circle

Rectangle and Circle

 

Problem Description
Given a rectangle and a circle in the coordinate system(two edges of the rectangle are parallel with the X-axis, and the other two are parallel with the Y-axis), you have to tell if their borders intersect.

Note: we call them intersect even if they are just tangent. The circle is located by its centre and radius, and the rectangle is located by one of its diagonal.

计算几何-hdoj-1221-Rectangle and Circle_第1张图片

 

Input
The first line of input is a positive integer P which indicates the number of test cases. Then P test cases follow. Each test cases consists of seven real numbers, they are X,Y,R,X1,Y1,X2,Y2. That means the centre of a circle is (X,Y) and the radius of the circle is R, and one of the rectangle's diagonal is (X1,Y1)-(X2,Y2).
Output
For each test case, if the rectangle and the circle intersects, just output "YES" in a single line, or you should output "NO" in a single line.
Sample Input
 
   
2 1 1 1 1 2 4 3 1 1 1 1 3 4 4.5

Sample Output
 
   
YES NO
 
Source
杭州电子科技大学第三届程序设计大赛
 

分析:圆与矩形有交点的充分必要条件是:点到四个线段的最短距离dmin<=radius && 点到四个线段的最长距离dmax>=radius。

//1221 ac 
#include 
#include 
#include 
#include  
using namespace std;
struct Point{
	double x,y;
	Point(double x=0,double y=0);
};
typedef Point Vector;
Point::Point(double x,double y){
	this->x=x,this->y=y;
}
//向量与向量的+ - 点积 叉积   
Vector operator +(const Vector& A,const Vector& B){
	return Vector(A.x+B.x,A.y+B.y);
}
Vector operator -(const Vector& A,const Vector& B){
	return Vector(A.x-B.x,A.y-B.y);
}
double Dot(const Vector& A,const Vector& B){
	return (A.x*B.x+A.y*B.y);
}
double Cross(const Vector& A,const Vector& B){//叉积结果仍为向量,这里是模 
	return (A.x*B.y-B.x*A.y);
}
//向量间关系运算符
bool operator < (const Vector& A,const Vector& B){
	if(A.x0) return Length(v3);
	else return fabs(Cross(v1,v2))/Length(v1);
}
double DistanceMaxToSegment(Point P,Point A,Point B){//点到线段最远距离 
	Vector v2=P-A,v3=P-B;
	return min(Length(v2),Length(v3));
}


//线段是否“正规相交”,即交点不在四个端点上 
bool SegmentProperIntersection(Point a1,Point a2,Point b1,Point b2){
	double c1=Cross(a2-a1,b1-a1),c2=Cross(a2-a1,b2-a1),
	       c3=Cross(b2-b1,a1-b1),c4=Cross(b2-b1,a2-b1);
    return dcmp(c1)*dcmp(c2)<0&&dcmp(c3)*dcmp(c4)<0;
} 
bool OnSegment(Point p,Point a1,Point a2){ //点是否在线段上 
	return dcmp(Cross(a1-p,a2-p))==0&&dcmp(Dot(a1-p,a2-p))<0;
}

int ncase;
Point circle,v1,v2,v3,v4;
double radius;
void f_init(){
	cin>>circle.x>>circle.y>>radius;
   	cin>>v1.x>>v1.y>>v3.x>>v3.y;
   	v2.x=v3.x,v2.y=v1.y;
   	v4.x=v1.x,v4.y=v3.y;
}
bool f_calc(){
	double dis[4],dis_max[4];
	dis[0]=DistanceToSegment(circle,v1,v2);
	dis[1]=DistanceToSegment(circle,v2,v3);
	dis[2]=DistanceToSegment(circle,v3,v4);
	dis[3]=DistanceToSegment(circle,v4,v1);
	sort(dis,dis+4);
	dis_max[0]=DistanceMaxToSegment(circle,v1,v2);
	dis_max[1]=DistanceMaxToSegment(circle,v2,v3);
	dis_max[2]=DistanceMaxToSegment(circle,v3,v4);
	dis_max[3]=DistanceMaxToSegment(circle,v4,v1);
	sort(dis_max,dis_max+4);
	if(dis[0]radius||dcmp(dis_max[3]-radius)==0)
	    return true;
	
	return false;
}
int main(int argc, char *argv[])
{
    //ifstream in("in.txt"); cin.rdbuf(in.rdbuf());
    cin>>ncase;
    while(ncase--){
    	f_init();
    	if(f_calc()) cout<<"YES\n";
    	else cout<<"NO\n";
    }
    return 0;
}


 

你可能感兴趣的:(计算几何-hdoj-1221-Rectangle and Circle)