叉积_判断点与三角形的位置关系 P1355 神秘大三角

题目描述

判断一个点与已知三角形的位置关系。

输入输出格式

输入格式:

 

前三行:每行一个坐标,表示该三角形的三个顶点

第四行:一个点的坐标,试判断该点与前三个点围成三角形的位置关系

(详见样例)

所有坐标值均为整数。

 

输出格式:

 

若点在三角形内(不含边界),输出1;

若点在三角形外(不含边界),输出2;

若点在三角形边界上(不含顶点),输出3;

若点在三角形顶点上,输出4。

 

输入输出样例

输入样例#1: 复制
(0,0)
(3,0)
(0,3)
(1,1)
输出样例#1: 复制
1

说明

【数据规模与约定】

对于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;
}

 

posted @ 2018-05-11 10:39  whymhe  阅读(978)  评论(0编辑  收藏  举报