如何判断点与三角形的位置关系

这个问题比较容易,写这篇文章的目的在于记录模板

  • 如下图,点和三角形之间的位置关系有下面几种
    在这里插入图片描述
  • 其中点在三角形边上或者是在顶点上判断起来比较容易,只要枚举每一条边,如果发现这个点到两个端点之间的距离等于边长,那就是说这个点在三角形的一条边上,特判一下点和其他点重合的情况即可
  • 那么如何判断点是在三角形外部还是内部呢?
  • 如果从高中数学的角度来看,我们可能会想去把这三条直线方程写出来,通过看这个点是不是在这三条直线中间来判断,可能笔算起来比较容易,但是如果编程实现,那就太复杂了,不说点在直线两侧的若干情况需要讨论,直线方程也需要讨论斜率是否存在,除非山穷水尽实在没办法,我们不考虑这种办法
  • 我们能够发现如果一个点在三角形内部,那么它和三个顶点的连线与原三角形的边构成的三个三角形的面积和等于原三角形的面积,如下图
    在这里插入图片描述
  • 如果一个点在三角形的外部,那么它和三个顶点的连线与原三角形的边构成的三个三角形的面积和大于原三角形,如下图
    在这里插入图片描述
  • 通过这个性质我们可以很方便的判断,编程细节,三角形面积通过海伦公式和向量叉积来求取,放个海伦公式复习一下,设三条边长分别为 a , b , c a,b,c a,b,c p = 1 2 ( a + b + c ) p=\frac{1}{2}(a+b+c) p=21(a+b+c),那么三角形面积为
    S = p × ( p − a ) × ( p − b ) × ( p − c ) S=\sqrt {p\times(p-a)\times(p-b)\times(p-c)} S=p×(pa)×(pb)×(pc)
    上一道例题
    https://www.luogu.com.cn/problem/P1355
#include <bits/stdc++.h>
using namespace std;
inline int read(){
    int x = 0, f = 1;char c = getchar();
    while(c < '0' || c > '9'){if(c == '-') f = -1;c = getchar();}
    while(c >= '0' && c <= '9'){x = (x << 1) + (x << 3) + (c ^ 48);c=getchar();}
    return x*f;
}
const double eps = 1e-8;
const int MAXN = 1e6 + 100;
int sgn(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){}
    bool operator == (const Point &B)const{
        return x == B.x && y == B.y;
    }
    Point operator - (const Point &B)const{
        return Point(x - B.x, y - B.y);
    }
}s[MAXN];
typedef Point Vector;
double Cross(Vector A, Vector B){
    return A.x * B.y - A.y * B.x;
}
double distance(Point A, Point B){
    return hypot(A.x - B.x, A.y - B.y);
}
void solve(){
    double a, b;
    a = 1.0 * read();
    b = 1.0 * read();
    double p = 0.0;
    for(int i=0;i<3;i++){
        if(Point(a, b) == s[i]){
            cout << 4;
            return;
        }
        p += distance(s[i], s[(i + 1) % 3]);
    }
    p /= 2;
    for(int i=0;i<3;i++){
        if(sgn(distance(s[i], s[(i + 1) % 3]) - distance(Point(a, b), s[i]) - distance(Point(a, b), s[(i + 1) % 3])) == 0){
            cout << 3;
            return;
        }
    }
    double S2 = 0.0;
    double x = distance(s[0], s[1]);
    double y = distance(s[1], s[2]);
    double z = distance(s[2], s[0]);
    double S = sqrt(p * (p - x) * (p - y) * (p - z));
    for(int i=0;i<3;i++){
        S2 += fabs(Cross(Point(a, b) - s[i], Point(a, b) - s[(i + 1) % 3]));
    }
    S2 /= 2;
    if(sgn(S - S2) == 0) cout << 1;
    else if(sgn(S - S2) < 0) cout << 2;
}
int main(){
    for(int i=0;i<3;i++){
        s[i].x = 1.0 * read();
        s[i].y = 1.0 * read();
    }
    solve();
    return 0;
}
  • 注意向量叉积的正负性
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
### 回答1: 要判断一个三角形位置关系,可以使用以下方法: 1. 计算该三角形每个顶的距离,如果有一个距离为0,则该在该顶上,直接返回该三角形内。 2. 计算该三角形每个边的距离,如果有一个距离为0,则该在该边上,直接返回该三角形内。 3. 如果上述两种情况都不满足,则该三角形内部的条件为:该三角形任意一的向量与三角形任意一边的向量的叉积方向相同,且该三角形每个顶的向量与该三角形任意一的向量的叉积方向相同。 如果该三角形内部,则返回三角形内;如果该三角形外部,则返回三角形外。 ### 回答2: 要判断一个三角形位置关系,可以使用一些几何知识和计算方法。 首先,判断是否在三角形内部,可以使用面积法。如果一个在一个三角形的内部,那么以这个为顶的三个三角形的面积之和应该等于这个三角形的面积。通过计算三角形的面积,并将三个面积相加,如果等于三角形的面积,则可以判断三角形内部。 其次,判断是否在三角形的边上。可以通过判断是否在三条边的延长线上来进行判断。如果在某条边上,那么与这条边的两个端所构成的向量与该边所构成的向量应该成正比例关系。 最后,判断是否在三角形的外接圆内部。可以通过计算三角形的三个顶的距离,并将这三个距离与三角形的三边的长度进行比较。如果该到三个顶的距离均小于三边的长度,则可以判断三角形的外接圆内。 通过以上的判断方法,可以获得三角形位置关系。但需要注意的是,如果三角形是等腰或等边三角形,需要单独处理,因为在这种情况下判断条件会有所不同。 ### 回答3: 要判断一个三角形位置关系,我们可以采取以下方法: 首先,我们可以利用向量的知识来求解三角形位置关系。通过计算三角形的每个顶所连成的向量与三角形每个边的法向量的积,可以判断三角形内部还是外部。如果三角形的每个顶所连成的向量与三角形每个边的法向量的积都小于零,则可以确定三角形的内部。反之,如果有任意一个积大于等于零,则可以确定三角形的外部。 其次,我们可以利用叉乘来判断三角形位置关系。通过计算三角形每两个相邻顶所连成的向量的叉乘,可以得到三个法向量,分别指向每个三角形的边。然后,计算三角形每个顶的向量与对应边法向量的积,如果三角形的每个顶所连成的向量与对应边法向量的积都小于等于零,则可以确定三角形的内部。反之,如果有任意一个积大于零,则可以确定三角形的外部。 最后,我们还可以通过三角形面积的方法来判断三角形位置关系。可以利用三角形每两个相邻顶所连成的向量的叉乘来计算每个小三角形的面积,然后将这些小三角形的面积累加起来,得到整个三角形的面积。如果三角形的每个小三角形的面积之和等于整个三角形的面积,则可以确定三角形的内部。反之,如果面积之和大于整个三角形的面积,则可以确定三角形的外部。 通过以上方法,我们可以较为准确地判断三角形位置关系

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Clarence Liu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值