叉积_判断点与三角形的位置关系 P1355 神秘大三角
题目描述
判断一个点与已知三角形的位置关系。
输入输出格式
输入格式:
前三行:每行一个坐标,表示该三角形的三个顶点
第四行:一个点的坐标,试判断该点与前三个点围成三角形的位置关系
(详见样例)
所有坐标值均为整数。
输出格式:
若点在三角形内(不含边界),输出1;
若点在三角形外(不含边界),输出2;
若点在三角形边界上(不含顶点),输出3;
若点在三角形顶点上,输出4。
输入输出样例
说明
【数据规模与约定】
对于100%数据,0<=所有点的横、纵坐标<=100
//Pro: P1355 神秘大三角 //Strategy: cross product //叉积判断点与三角形的位置关系,精度高 //若点在三角形内(不含边界),输出1; //若点在三角形外(不含边界),输出2; //若点在三角形边界上(不含顶点),输出3; //若点在三角形顶点上,输出4。 //设三角形三个顶点是A,B,C,要判断的点是P //由于输入的是整数,所以就比较容易了,不用担心精度问题。 //点:判断在不在点上直接判就好了 //边:如果P在三角形的边所在直线上,那么P与边的端点构成的向量的叉积==0,如果P的坐标还在端点之间,那就在线段上了 //内外:将每条边看成是一个向量,那么可以有三条不同终点的向量 //在这儿规定这三个向量是AB,BC,CA,那么P指向这三个向量的终点,也可以对应得到三个向量PA,PB,PC //如果对应的向量的叉积(如AB*PA)的值里有任意一个是负的,那么P就在三角形外, //否则若都是正的,就在三角形内 #include<iostream> #include<cstdio> #include<algorithm> using namespace std; struct Point //存点 { int x,y; Point(int x=0,int y=0){this->x=x,this->y=y;} Point operator + (const Point &a) { return Point(this->x+a.x,this->y+a.y); } Point operator - (const Point &a) { return Point(this->x-a.x,this->y-a.y); } int operator * (const Point &a) { return this->x*a.y-this->y*a.x; } }A,B,C,P; bool On_Point() //在端点上 { if(P.x-A.x==0&&P.y-A.y==0) return true; if(P.x-B.x==0&&P.y-B.y==0) return true; if(P.x-C.x==0&&P.y-C.y==0) return true; return false; } bool On_Edge() //在边上 { if((P-A)*(P-B)==0&&min(A.x,B.x)<=P.x&&min(A.y,B.y)<=P.y&&max(A.x,B.x)>=P.x&&max(A.y,B.y)>=P.y) return true; if((P-B)*(P-C)==0&&min(B.x,C.x)<=P.x&&min(B.y,C.y)<=P.y&&max(B.x,C.x)>=P.x&&max(B.y,C.y)>=P.y) return true; if((P-A)*(P-C)==0&&min(A.x,C.x)<=P.x&&min(A.y,C.y)<=P.y&&max(A.x,C.x)>=P.x&&max(A.y,C.y)>=P.y) return true; return false; } bool inside() //在不在三角形内 { if((B-A)*(P-A)<0) return false; if((C-B)*(P-B)<0) return false; if((A-C)*(P-C)<0) return false; return true; } char c; int main() { scanf("%*c%d%*c%d%*c",&A.x,&A.y); getchar();getchar(); scanf("%*c%d%*c%d%*c",&B.x,&B.y); getchar();getchar(); scanf("%*c%d%*c%d%*c",&C.x,&C.y); getchar();getchar(); scanf("%*c%d%*c%d%*c",&P.x,&P.y); if((B-A)*(C-A)<0) //重构三角形的顶点,让三角形当A在上时,B左C右 swap(A,B); if(On_Point()) puts("4"); else if(On_Edge()) puts("3"); else if(!inside()) puts("2"); else puts("1"); return 0; }