【判断点与多边形的位置关系的方法——射线法】

【回锅肉的修炼】C++下使用射线法判断点与多边形的位置关系

判断点与多边形的位置关系的方法——射线法

射线法的思想是:以目标点为端点引一条射线,计算这条射线和多边形所有边的交点数目。如果交点个数为奇数,则点在多边形部,反之则在多边形外部。

以图为例说明原理

在这里插入图片描述
O点在多边形内部,P点在多边形外部,内部点O无论向左或向右,始终与多边形的交点数目为奇数个,外部点P无论向左或向右,始终与多边形的交点数目为偶数个,这里切记射线法,关键在于单向发射

给一段C++代码

下面展示一些 内联代码片

#include <iostream>
#include <vector>
using namespace std;
struct Point {
    double x, y;
};
// 计算叉积
double cross(Point A, Point B, Point C) {
    double BAx = A.x - B.x;
    double BAy = A.y - B.y;
    double BCx = C.x - B.x;
    double BCy = C.y - B.y;
    return BAx * BCy - BAy * BCx;
}
// 判断点是否在多边形内部
int isPointInPolygon(vector<Point> polygon, Point P) {
    int wn = 0;
    int n = polygon.size();
    for (int i = 0; i < n; i++) {
        Point A = polygon[i];
        Point B = polygon[(i + 1) % n];
        if (A.y <= P.y) {
            if (B.y > P.y && cross(B, P, A) > 0) wn++;  // 从下往上穿过线段
            } 
        else {
            if (B.y <= P.y && cross(B, P, A) < 0) wn--;  // 从上往下穿过线段
        }
    }
    return wn == 0 ? 2 : 0;
}

int main() {
    // 多边形顶点坐标
    vector<Point> polygon = {{0, 0}, {2, 0}, {1, 2}};
    // 待判断点的坐标
    Point P = {1, 1};
    // 判断点与多边形的位置关系
    int res = isPointInPolygon(polygon, P);
    if (res == 0) {
        cout << "Point P is inside the polygon." << endl;
    } else if (res == 1) {
        cout << "Point P is on the edge of the polygon." << endl;
    } else {
        cout << "Point P is outside the polygon." << endl;
    }
    return 0;
}

代码解释

当点P沿着水平方向向右移动时,通过该点的射线会与多边形相交,交点的个数即为点P是否在多边形内部的判断条件。此算法的基本思想是通过射线法遍历多边形的每条边,统计与射线相交的边的个数,最后根据交点的个数判断点是否在多边形内部。
具体实现过程如下:

1.确定一个从点P向右射出的射线,计算该射线与多边形的每条边的交点,并统计交点的个数。

2. 如果交点的个数是奇数,则点P在多边形内部;如果交点的个数是偶数,则点P在多边形外部。

3.在计算交点时,只有当射线与边有交点时才需要进行计算,此时需要判断交点是否在点P的左侧

cross()函数解释:
这段代码实现了计算三个点 A、B 和 C 所形成的两条线段 AB 和 BC 的叉积。
在二维空间中,叉积可以用来计算向量的大小、方向和垂直性。对于向量 a = (a1, a2) 和向量 b = (b1, b2),它们的叉积为 a × b = a1 * b2 - a2 * b1。其中,向量 a 和向量 b 所张成的平行四边形的面积等于向量 a × b 的大小。
在计算几何中,利用向量的叉积可以方便地计算两条线段的位置关系,具体方法是计算它们所张成的平行四边形的面积是否为零,若为零则两条线段共线。
具体来说,假设有三个点 A(x1, y1), B(x2, y2) 和 C(x3, y3),则 BA 向量为 (x1-x2, y1-y2),BC 向量为 (x3-x2, y3-y2),因此它们的叉积可以用上面提到的公式计算得到。
在这个代码中,函数 cross() 接受三个参数 A、B 和 C,其中 B 是三角形的一个顶点,A 和 C 是三角形的另外两个顶点。函数中先计算出向量 BA 和向量 BC,然后使用上面的公式计算出它们的叉积。如果叉积大于 0,则说明 AB 和 BC 所张成的角度是小于 180 度的,也就是 AB 和 BC 处于 B 顶点的同侧,可以认为点 C 在直线 AB 的逆时针方向;如果叉积小于 0,则说明 AB 和 BC 所张成的角度是大于 180 度的,也就是 AB 和 BC 处于 B 顶点的异侧,可以认为点 C 在直线 AB 的顺时针方向;如果叉积等于 0,则说明 AB 和 BC 共线,可以通过其他方法来判断它们的位置关系。

关于叉积的解释
叉积

  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
射线(Ray Casting)是计算机图形学中常用的一种技术,其中以Python实现射线的话可以通过以下步骤进行: 1. 导入所需的库:首先需要导入Python的数学库(如math)和图形库(如matplotlib)进行计算和显示。 2. 定义射线和物体:在射线中,我们需要定义一个起始点和一个方向向量来表示一条射线。同时,我们也需要定义场景中的物体,比如球体或三角形等。可以通过定义类或数据结构来表示射线和物体。 3. 实现光线与物体的相交测试:对于每条光线,需要判断其是否与场景中的物体相交。这可以通过求解光线与物体之间的交点来实现。具体的相交测试算会根据不同的物体类型而有所区别。 4. 计算光照强度:当光线与物体相交时,需要计算交点处的光照强度。这可以通过考虑光线与光源之间的遮挡关系和物体表面的材质属性来实现。常用的光照模型包括漫反射和镜面反射。 5. 进行光线追踪:通过对场景中的每条光线进行相交测试和光照计算,可以得到每个像素的颜色值。可以从屏幕上的每个像素位置发射一条光线,并追踪该光线与场景中的物体的相交情况,最终得到物体的渲染结果。 6. 显示渲染结果:最后,可以使用图形库(如matplotlib)将渲染结果显示出来,形成最终的图像。可以将相交测试和光照计算的结果映射到像素值上,来表示物体的颜色。 以上是一个简单的射线的Python实现步骤。具体的实现细节和功能可以根据实际需求进行调整和扩展。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值