[趣味算法]如何判断一个点是在三角形的内部还是外部?

8 篇文章 3 订阅
3 篇文章 1 订阅

问题描述

问题描述:判断二维平面上一个点P是在三角形ABC的内部还是外部。

这里写图片描述

前辈们给我们总结了许多办法,这里我给出一个比较直观也比较简单的办法。
在讲这个办法之前,我们先看另一个问题。

如果给定一条线段AB和点C,能否判断出来C和AB的位置关系呢?
这里的位置关系是指C是在线段AB上,还是在AB的左边,又或者是在AB的右边呢?
也许我们对左边还是右边的定义不明确,给一个图体会一下:

这里写图片描述

这里的C就是我们说的在AB的左边,就是你用你的右手四指指向AB的朝向,然后大拇指那边就是“左边”了。

那么我们如何判断C和AB的位置关系呢?

先给出代码,然后给予解释:

判断点是否在线段AB的左侧

typedef struct
{
    float x;
    float y;
}Point;

//input  : 直线s->e,点p
//return : 
//> 0 p is left of the line
//= 0 p is on the line
//< 0 p is right of the line

bool IsLeftPoint(Point s, Point e, Point p)
{
    return ((e.x - s.x) * (p.y - s.y)) > ((p.x - s.x) * (e.y - s.y));
}

让我们解释一下上述代码。

这个函数很短,这个形式有点奇怪,为什么这样就能判断呢?
我们把return的那行重写一下:

((e.x - s.x) * (p.y - s.y)) - ((p.x - s.x) * (e.y - s.y)) > 0 //等价

而这个式子的样子,和叉乘意外的有点相似。
我们接触叉乘的时候都是在三维空间,那么这个二维空间的形似叉乘的式子是怎么来的?
其实你可以把二维向量看做是第三维为0的三维向量,这样你套叉乘的公式,可以得到:

(x1,y1,0) X (x2,y2,0) = (0, 0, x1y2 – y1x2)

但是我们一般取的是这个向量的最后一维x1y2 - y1x2,这样看起来好像就是叉乘的结果是一个数量而非向量了。
再回到我们的IsLeftPoint函数,实际上我们就是根据三个点构造了两个向量然后做了一次叉乘的运算,我们是用的向量se叉乘向量sp

其实,这个x1y2 - y1x2还有一个比较神奇的特点:
如果x1y2 - y1x2的结果为负,那么说明sep三个点必定是按照逆时针顺序排列的

判断点是否在三角形外

我们已经知道了如何判断一个点是否在直线的左侧,那么如何利用这个来判断点是否在三角形外呢?
其实不难想到,如果我们把三角形的点顺序按照顺时针方向排列,也就是ABC的顺序:
这里写图片描述

如果三角形ABP、BCP、CAP都是按照逆时针的方向排列的,那么P必然在ABC的外部。

float IsInTriangle(float x, float y, float ax, float ay, float bx, float by, float cx, float cy)
{
    return  (bx - ax) * (y - ay) > (by - ay) * (x - ax) &&
            (cx - bx) * (y - by) > (cy - by) * (x - bx) &&
            (ax - cx) * (y - cy) > (ay - cy) * (x - cx) ? false : true;
}
  • 22
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
### 回答1: 一种常见的方法是使用"射线法"来确定一个点是否在多边形内部。这种方法的基本思想是:从该向多边形任意方向做一条射线,如果与多边形的边相交的次数为奇数,则该在多边形内部;如果相交次数为偶数,则该在多边形外部。 代码实现也相对简单,例如使用 Python 的 `matplotlib.path` 库,可以直接调用 `contains_point` 方法,并将多边形的顶和待测作为参数即可。 ### 回答2: 要确定一个点是否在多边形内部,可以采用射线法(Ray Casting)。 首先,假设我们有一个多边形,该多边形由一组有序的顶坐标组成。 然后,选取一条由该沿着x轴正方向射出的射线。 接着,遍历多边形的每条边,判断射线是否与每条边相交: - 如果与边相交的次数为奇数,说明该在多边形内部; - 如果与边相交的次数为偶数,说明该在多边形外部。 最后,返回结果即可。 以下是使用Python进行该操作的示例代码: ```python def point_in_polygon(point, polygon): x, y = point n = len(polygon) inside = False p1x, p1y = polygon[0] for i in range(n + 1): p2x, p2y = polygon[i % n] if min(p1y, p2y) < y <= max(p1y, p2y): if x <= max(p1x, p2x): if p1y != p2y: xinters = (y - p1y) * (p2x - p1x) / (p2y - p1y) + p1x if p1x == p2x or x <= xinters: inside = not inside p1x, p1y = p2x, p2y return inside ``` 以上代码可以判断一个点是否在一个由多边形顶坐标组成的列表中表示的多边形内部。 ### 回答3: 要确定一个点是在多边形的内部还是外部,可以使用射线法。 射线法的基本思路是,以待确定的为起,向任意方向发射一条射线,统计射线与多边形的交个数。如果交个数为奇数,则在多边形内部;如果交个数为偶数,则在多边形外部。 具体实现步骤如下: 1. 遍历多边形的每一条边,并记录每条边的起和终坐标(或将多边形的坐标按顺时针或逆时针排列)。 2. 以待确定的为起,向任意方向发射一条射线。例如,射线可以沿着x轴正方向发射。 3. 统计射线与边的交个数。如果射线与边相交,且交的y坐标位于边的两个顶的y坐标之间,则交个数加1。 4. 若交个数为奇数,则在多边形内部;若交个数为偶数,则在多边形外部。 需要注意的是,在实际编程中应考虑特殊情况,如在多边形的边上或顶上的情况,并对算法进行相应的优化,以提高效率和准确性。 综上所述,使用射线法可以较为准确地确定一个点是否在多边形的内部还是外部

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值