UVA 478 Points in Figures: Rectangles…(判定点在多边形内)
题意:
有n(n<=10)个图形,可能是三角形或矩形或圆.现在给你多个点,然后要你判断每个点分别在哪些图形内? 如果正好在图形边上,不算.
分析:
对于三角形,直接判断指定点与三角形三边的叉积是否同时大于0或同时小与0即可(也可以用点在多边形内的模板判断).
对于矩形,只要给定点的x和y坐标属于(x1,x2)与(y1,y2)这两个开区间即可.
对于圆,只要给定点到圆心的距离小于半径即可说该点在圆内.
程序中对于每个点依次用3种类别的所有图形去匹配该点,因为图形数目很少,所以只要该点在图形i内,那么标记数组的in[i]=true即可.
AC代码:
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
const int maxn=10+5;
const double eps=1e-10;
int dcmp(double x)
{
if(fabs(x)<eps) return 0;
return x<0?-1:1;
}
struct Point
{
double x,y;
Point(){}
Point(double x,double y):x(x),y(y){}
};
typedef Point Vector;
Vector operator-(Point A,Point B)
{
return Vector(A.x-B.x,A.y-B.y);
}
double Cross(Vector A,Vector B)
{
return A.x*B.y-A.y*B.x;
}
struct Rectangle
{
int id;
double x1,y1,x2,y2;//注意这里y1表示最小y坐标,y2表示最大y坐标,与输入不同
Rectangle(int id,double x1,double y1,double x2,double y2):id(id),x1(x1),y1(y1),x2(x2),y2(y2){}
bool InRectangle(Point p)
{
return p.x<x2&&p.x>x1&&p.y>y1&&p.y<y2;
}
};
struct Triangle
{
int id;
Point a1,a2,a3;
Triangle(int id,Point a1,Point a2,Point a3):id(id),a1(a1),a2(a2),a3(a3){}
bool InTriangle(Point p)
{
int v1=dcmp(Cross(a1-a2,p-a2));
int v2=dcmp(Cross(a2-a3,p-a3));
int v3=dcmp(Cross(a3-a1,p-a1));
return (v1<0&&v2<0&&v3<0) || (v1>0&&v2>0&&v3>0);
}
};
struct Circle
{
int id;
double x,y;
double r;
Circle(int id,double x,double y,double r):id(id),x(x),y(y),r(r){}
bool InCircle(Point p)
{
double dist2= (p.x-x)*(p.x-x)+(p.y-y)*(p.y-y);
return dist2<r*r;
}
};
vector<Rectangle> R;//保存所有矩形
vector<Triangle> T; //保存所有三角形
vector<Circle> C; //保存所有圆
int main()
{
char type;
int n=0;
while(scanf(" %c",&type)==1 && type!='*')
{
if(type=='r')
{
double x1,y1,x2,y2;
scanf("%lf%lf%lf%lf",&x1,&y2,&x2,&y1);
R.push_back(Rectangle(++n,x1,y1,x2,y2));
}
else if(type=='t')
{
Point p1,p2,p3;
scanf("%lf%lf%lf%lf%lf%lf",&p1.x,&p1.y,&p2.x,&p2.y,&p3.x,&p3.y);
T.push_back(Triangle(++n,p1,p2,p3));
}
else if(type=='c')
{
double x,y,r;
scanf("%lf%lf%lf",&x,&y,&r);
C.push_back(Circle(++n,x,y,r));
}
}
int num=1;
Point p;
while(scanf("%lf%lf",&p.x,&p.y)==2)
{
if(dcmp(p.x-9999.9)==0 && dcmp(p.y-9999.9)==0 ) break;
bool in[maxn];
memset(in,0,sizeof(in));
bool flag=false;//flag==true表示该点至少在一个图形内
for(int i=0;i<R.size();++i)
if(R[i].InRectangle(p)) in[R[i].id]=flag=true;
for(int i=0;i<T.size();++i)
if(T[i].InTriangle(p)) in[T[i].id]=flag=true;
for(int i=0;i<C.size();++i)
if(C[i].InCircle(p)) in[C[i].id]=flag=true;
if(!flag) printf("Point %d is not contained in any figure\n",num);
else
{
for(int i=1;i<=n;++i)if(in[i])
printf("Point %d is contained in figure %d\n",num,i);
}
++num;
}
return 0;
}