平面中判断点在三角形内算法(重心法)

简介: 平面中判断点在三角形内算法(重心法)

平面中判断点在三角形内算法(重心法)

目录

1. 概述

在文章《判断点是否在三角形内》中还提到了一种判断点在三角形内外的算法——重心法。这种算法同样用到了三角形的空间向量方程,但是值得注意的是,这种算法却只能判断平面中点在三角形的内外关系(已知空间向量方程,是可以判断三维空间关系的:空间中判断点在三角形内算法(方程法))。

2. 详论

2.1. 原理

重心法的推导过程与空间中判断点在三角形内算法(方程法))的推导过程比较相似。对于三个顶点为V0,V1,V2组成的空间三角形,对于三角形内的任一点P,有如下参数方程:

P=(1uv)V0+uV1+vV2P→=(1−u−v)V0→+uV1→+vV2→

变换位置,我们可以将其调整为:

V0P=u(V0V1)+v(V0V2)V0P→=u(V0V1→)+v(V0V2→)

将上式分别点乘V0V1V0V1→V0V2V0V2→,有:

{V0PV0V1=u(V0V1V0V1)+v(V0V2V0V1)V0PV0V2=u(V0V1V0V2)+v(V0V2V0V2){V0P→⋅V0V1→=u(V0V1⋅V0V1→→)+v(V0V2→⋅V0V1→)V0P→⋅V0V2→=u(V0V1→⋅V0V2→)+v(V0V2→⋅V0V2→)

很显然,这是个2行2列的线性方程组,通过克莱姆法则来求解:

⎪ ⎪ ⎪⎪ ⎪ ⎪D=(V0V1V0V1)(V0V2V0V2)(V0V2V0V1)(V0V1V0V2)D1=(V0PV0V1)(V0V2V0V2)(V0V2V0V1)(V0PV0V2)D2=(V0V1V0V1)(V0PV0V2)(V0PV0V1)(V0V1V0V2){D=(V0V1⋅V0V1→→)∗(V0V2→⋅V0V2→)−(V0V2→⋅V0V1→)∗(V0V1→⋅V0V2→)D1=(V0P→⋅V0V1→)∗(V0V2→⋅V0V2→)−(V0V2→⋅V0V1→)∗(V0P→⋅V0V2→)D2=(V0V1⋅V0V1→→)∗(V0P→⋅V0V2→)−(V0P→⋅V0V1→)∗(V0V1→⋅V0V2→)

{u=D1/Dv=D2/D{u=D1/Dv=D2/D

2.2. 实现

详细的代码实现如下:

//空间三角形
//按照逆时针顺序插入值并计算法向量
template <class T>
class Triangle
{
public:
    Vec3<T> v0;
    Vec3<T> v1;
    Vec3<T> v2;
    Triangle()
    {
    }
    Triangle(Vec3<T> v0, Vec3<T> v1, Vec3<T> v2)
    {
        this->v0 = v0;
        this->v1 = v1;
        this->v2 = v2;     
    }
    void Set(Vec3<T> v0, Vec3<T> v1, Vec3<T> v2)
    {
        this->v0 = v0;
        this->v1 = v1;
        this->v2 = v2;    
    }
    // 判断平面点P是否在平面三角形内(重心法)
    bool PointInTriangle2D(Vec3<T>& P)
    {
        auto v01 = v1 - v0 ;
        auto v02 = v2 - v0 ;
        auto v0p = P - v0 ;
        double dot00 = v01 * v01 ;
        double dot01 = v01 * v02 ;
        double dot02 = v01 * v0p ;
        double dot11 = v02 * v02 ;
        double dot12 = v02 * v0p ;
        double D = (dot00 * dot11 - dot01 * dot01);
        if(D == 0.0)
        {
            return false;
        }
        double inverDeno = 1 / D ;
        double u = (dot11 * dot02 - dot01 * dot12) * inverDeno ;
        if (u < 0 || u > 1)
        {
            return false ;
        }
        double v = (dot00 * dot12 - dot01 * dot02) * inverDeno ;
        if (v < 0 || v > 1)
        {
            return false ;
        }
        return u + v <= 1 ;
    }
};

2.3. 总结

本质上,这个算法与空间中判断点在三角形内算法(方程法)是同一种算法的不同推导,都是通过空间三角形中点的向量方程来求解的,但是是采用了不同的解法。不过为什么一个可以判断空间关系,一个只能判断平面关系呢?关键在于点是否能让向量方程成立,这个求解算法可以求解u,v,但没有保证空间内的向量方程能够成立。

3. 参考

  1. 判断点是否在三角形内
  2. 空间中判断点在三角形内算法(方程法))

详细代码

分类: 计算几何

标签: 算法 , 三角形 , 计算几何 ,


相关文章
|
3月前
|
算法 Java
LeetCode经典算法题:矩阵中省份数量经典题目+三角形最大周长java多种解法详解
LeetCode经典算法题:矩阵中省份数量经典题目+三角形最大周长java多种解法详解
50 6
|
3月前
|
数据采集 算法
基于PSO粒子群算法的三角形采集堆轨道优化matlab仿真
该程序利用PSO算法优化5个4*20矩阵中的模块采集轨迹,确保采集的物品数量及元素含量符合要求。在MATLAB2022a上运行,通过迭代寻优,选择最佳模块组合并优化轨道,使采集效率、路径长度及时间等综合指标最优。具体算法实现了粒子状态更新、需求量差值评估及轨迹优化等功能,最终输出最优轨迹及其相关性能指标。
|
3月前
|
算法 C++
空间中判断点在三角形内算法(方程法)
空间中判断点在三角形内算法(方程法)
58 0
|
3月前
|
算法
平面中判断点在三角形内算法(同向法)
平面中判断点在三角形内算法(同向法)
26 0
|
3月前
|
算法 C++ Windows
空间射线与三角形相交算法的两种实现
空间射线与三角形相交算法的两种实现
40 0
|
6月前
|
算法 机器人 Python
Python实现教程:平面最短路径算法
Python实现教程:平面最短路径算法
101 1
|
6月前
|
机器学习/深度学习 算法 数据安全/隐私保护
基于DCT变换和位平面分解的数字水印嵌入提取算法matlab仿真
这是一个关于数字水印算法的摘要:使用MATLAB2022a实现,结合DCT和位平面分解技术。算法先通过DCT变换将图像转至频域,随后利用位平面分解嵌入水印,确保在图像处理后仍能提取。核心程序包括水印嵌入和提取,以及性能分析部分,通过PSNR和NC指标评估水印在不同噪声条件下的鲁棒性。
|
6月前
|
算法
【优选算法】——Leetcode——611. 有效三角形的个数
【优选算法】——Leetcode——611. 有效三角形的个数
|
24天前
|
算法 安全 数据安全/隐私保护
基于game-based算法的动态频谱访问matlab仿真
本算法展示了在认知无线电网络中,通过游戏理论优化动态频谱访问,提高频谱利用率和物理层安全性。程序运行效果包括负载因子、传输功率、信噪比对用户效用和保密率的影响分析。软件版本:Matlab 2022a。完整代码包含详细中文注释和操作视频。