luogu 1355 神秘大三角 判断点和三角形的位置关系 面积法 叉积法

题目链接

题目描述

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

输入输出格式

输入格式:

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

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

(详见样例)

所有坐标值均为整数。

输出格式:

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

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

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

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

输入输出样例

输入样例#1:

(0,0)
(3,0)
(0,3)
(1,1)

输出样例#1:

1

法一:面积法

连结第四个点和三角形的三个顶点,得到三个三角形,若这三个三角形的面积之和等于原三角形面积,则该点在三角形内。

其他情况相应特判即可。

Code

#include 
#define eps 1e-6
using namespace std;
double dist(int x1, int y1, int x2, int y2) {
    return sqrt(pow(x2-x1,2) + pow(y2-y1,2));
}
double area(int x1, int y1, int x2, int y2, int x3, int y3) {
    double a = dist(x1,y1,x2,y2), b = dist(x1,y1,x3,y3), c = dist(x2,y2,x3,y3);
    double p = (a+b+c)/2;
    return sqrt(p*(p-a)*(p-b)*(p-c));
}
int main() {
    int x1,y1,x2,y2,x3,y3,x,y;
    scanf("(%d,%d)\n(%d,%d)\n(%d,%d)\n(%d,%d)", &x1, &y1, &x2, &y2, &x3, &y3, &x, &y);
    if ((x==x1&&y==y1) || (x==x2&&y==y2) || (x==x3&&y==y3)) { putchar('4'); return 0; }
    double s1 = area(x1,y1,x2,y2,x,y),
        s2 = area(x1,y1,x3,y3,x,y),
        s3 = area(x3,y3,x2,y2,x,y),
        s = area(x1,y1,x2,y2,x3,y3);
    if (s1+s2+s3-s>eps) { putchar('2'); return 0; }
    if (fabs(s1)

法二:叉积法

理论依据
\(\overrightarrow{P0P1}\times \overrightarrow{P0P2}\gt 0\leftrightarrow P1在P2的顺时针方向(相对P0)\)
\(\overrightarrow{P0P1}\times \overrightarrow{P0P2}\lt 0\leftrightarrow P1在P2的逆时针方向(相对P0)\)
\(\overrightarrow{P0P1}\times \overrightarrow{P0P2}= 0\leftrightarrow P1,P2,P0三点共线\)

仍然连结第四个点和三角形的三个顶点,算出三个叉积,如果同正或同负,则在三角形内;

如果有一个为\(0\),另两个同号,则在三角形边上。

Code

#include 
#define eps 1e-6
using namespace std;
int vec(int x1, int y1, int x2, int y2, int x0, int y0) {
    return (x1-x0) * (y2-y0) - (x2-x0) * (y1-y0);
}
int main() {
    int x1,y1,x2,y2,x3,y3,x,y;
    scanf("(%d,%d)\n(%d,%d)\n(%d,%d)\n(%d,%d)", &x1, &y1, &x2, &y2, &x3, &y3, &x, &y);
    if ((x==x1&&y==y1) || (x==x2&&y==y2) || (x==x3&&y==y3)) { putchar('4'); return 0; }
    int c1 = vec(x1, y1, x2, y2, x, y),
        c2 = vec(x2, y2, x3, y3, x, y),
        c3 = vec(x3, y3, x1, y1, x, y);
    if ((c1>0&&c2>0&&c3>0) || (c1<0&&c2<0&&c3<0)) { putchar('1'); return 0; }
    if ((c1==0&&c2*c3>0) || (c2==0&&c1*c3>0) || (c3==0&&(c1*c2>0))) putchar('3');
    else putchar('2');
    return 0;
}

转载于:https://www.cnblogs.com/kkkkahlua/p/7631316.html

你可能感兴趣的:(luogu 1355 神秘大三角 判断点和三角形的位置关系 面积法 叉积法)