平面中判断点在三角形内算法(重心法)
文章目录
- 1. 概述
- 2. 详论
- 2.1. 原理
- 2.2. 实现
- 2.3. 总结
- 3. 参考
1. 概述
在文章《判断点是否在三角形内》中还提到了一种判断点在三角形内外的算法——重心法。这种算法同样用到了三角形的空间向量方程,但是值得注意的是,这种算法却只能判断平面中点在三角形的内外关系(已知空间向量方程,是可以判断三维空间关系的:空间中判断点在三角形内算法(方程法))。
2. 详论
2.1. 原理
重心法的推导过程与空间中判断点在三角形内算法(方程法))的推导过程比较相似。对于三个顶点为V0,V1,V2组成的空间三角形,对于三角形内的任一点P,有如下参数方程:
P⃗=(1−u−v)V0⃗+uV1⃗+vV2⃗\vec{P} = (1 - u - v) \vec{V_0} + u \vec{V_1} + v \vec{V_2} P=(1−u−v)V0+uV1+vV2
变换位置,我们可以将其调整为:
V0P⃗=u(V0V1⃗)+v(V0V2⃗)\vec{V_0P} = u(\vec{V_0V_1}) + v(\vec{V_0V_2}) V0P=u(V0V1)+v(V0V2)
将上式分别点乘V0V1⃗\vec{V_0V_1}V0V1和V0V2⃗\vec{V_0V_2}V0V2,有:
{V0P⃗⋅V0V1⃗=u(V0V1⋅V0V1⃗⃗)+v(V0V2⃗⋅V0V1⃗)V0P⃗⋅V0V2⃗=u(V0V1⃗⋅V0V2⃗)+v(V0V2⃗⋅V0V2⃗)\begin{cases} \vec{V_0P} \cdot \vec{V_0V_1} = u(\vec{V_0V_1 \cdot \vec{V_0V_1}}) + v(\vec{V_0V_2} \cdot \vec{V_0V_1}) \\ \vec{V_0P} \cdot \vec{V_0V_2} = u(\vec{V_0V_1} \cdot \vec{V_0V_2}) + v(\vec{V_0V_2} \cdot \vec{V_0V_2}) \\ \end{cases} {V0P⋅V0V1=u(V0V1⋅V0V1)+v(V0V2⋅V0V1)V0P⋅V0V2=u(V0V1⋅V0V2)+v(V0V2⋅V0V2)
很显然,这是个2行2列的线性方程组,通过克莱姆法则来求解:
{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⃗)\begin{cases} D = (\vec{V_0V_1 \cdot \vec{V_0V_1}}) * (\vec{V_0V_2} \cdot \vec{V_0V_2}) - (\vec{V_0V_2} \cdot \vec{V_0V_1}) * (\vec{V_0V_1} \cdot \vec{V_0V_2}) \\ D1 = (\vec{V_0P} \cdot \vec{V_0V_1}) * (\vec{V_0V_2} \cdot \vec{V_0V_2}) - (\vec{V_0V_2} \cdot \vec{V_0V_1}) * (\vec{V_0P} \cdot \vec{V_0V_2}) \\ D2 = (\vec{V_0V_1 \cdot \vec{V_0V_1}}) * (\vec{V_0P} \cdot \vec{V_0V_2}) - (\vec{V_0P} \cdot \vec{V_0V_1}) * (\vec{V_0V_1} \cdot \vec{V_0V_2}) \\ \end{cases} ⎩⎪⎪⎨⎪⎪⎧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\begin{cases} u = D1 / D \\ v = D2 / D \\ \end{cases} {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. 参考
- 判断点是否在三角形内
- 空间中判断点在三角形内算法(方程法))
详细代码
平面中判断点在三角形内算法(重心法)相关推荐
- 几种方法判断平面点在三角形内
最近在做一个Unity实现的3D建模软件,其中需要在模型表面进行操作的时候,需要用到点和三角形位置关系的判定算法.由于一个模型往往是几千个三角片,所以这个判定算法必须高效,否则会影响最终程序的整体性能 ...
- 如何判断一点在三角形内
假定在右手坐标系中的三角形3点坐标为A,B,C,判断P是否在ABC之内 ( 主要来自 3D引擎研发QQ群(38224573 )的各位朋友的讨论 ,我仅仅算做个总结吧,特别感谢各位朋友的热情支持. ) ...
- 射线与三角形求交,并判断是否在三角形内的完整代码(带测试)
// Det.cpp : Defines the entry point for the console application. // #include "stdafx.h" # ...
- 平面中判断线段与矩形是否相交
文章目录 1. 原理 2. 实现 3. 参考 1. 原理 这个问题的算法思路挺简单的.分成两步来判断: 判断线段的两个端点是否在矩形内,如果两个端点至少有一个在矩形内,说明线段与矩形相交. 如果两个端 ...
- Qt 判断一个点是否落在三角形内(算法)
利用重心法判断一个点是否落在三角形面积内,三角形的三个点在同一个平面上,如果选中其中一个点,其他两个点不过是相对该点的位移而已,比如选择点A作为起点,那么点B相当于在AB方向移动一段距离得到,而点C相 ...
- c语言实现点在多边形内部,C语言中实现 点在多边形内 算法
来源: 天极网 作者: 若水 2008-05-15/01:29 本文是采用射线法判断点是否在多边形内的C语言程序.多年前,我自己实现了这样一个算法.但是随着时间的推移,我决定重写这个代码.参考周培德的 ...
- 阿里云天池超级码力在线编程大赛初赛 第2场 ABCD(A.计算几何 判断点在三角形内 D.大施罗德数/超级卡特兰数)
心得 打了一下被群友吐槽的比赛,阅读体验极差 阴间题面,读题1小时,AC5min,原题警告 思路来源 https://blog.csdn.net/PleasantlY1/article/details ...
- Day20200713—点在三角形内
Day20200713-点在三角形内 文章目录 Day20200713-点在三角形内 前言 参考 题目 描述 示例 解题 关键词与细节 条件 解题思路 算法实现 程序代码 运行截图 思考 后续 前言 ...
- 三角形填充算法(C实现)
算法及优化理论参考文章: 图形学底层探秘 - 更现代的三角形光栅化与插值算法的实现与优化 - 知乎 如何判断一个点在三角形内部_c语言判断点在三角形内_pdcxs007的博客-CSDN博客 代码实现如 ...
- [fzu 2273]判断两个三角形的位置关系
首先判断是否相交,就是枚举3*3对边的相交关系. 如果不相交,判断包含还是相离,就是判断点在三角形内还是三角形外.两边各判断一次. //http://acm.fzu.edu.cn/problem.ph ...
最新文章
- 【廖雪峰python入门笔记】变量
- 蓝松短视频经验分享----抠图和动画设计
- hdu1521 排列组合
- [转]移动应用统一化的谎言:一次编译,到处运行不可能
- SpringCloud教程-注册中心(Consul)(SpringCloud版本Greenwich.SR4)
- Python: 自定义类对象序列化为Json串
- ERP通用附件管理功能设计与实现
- SQL Server中的版本号
- iOS开发之常见的URLScheme
- 项目中遇到的各种bug和踩过的坑
- 基于ArcGIS和fragstats软件计算景观破碎度(一)
- wps excel 向下选中指定行数并填充根据公式计算好的数据
- 网络安全日志留存合规解决方案
- Common Electrical I/O (CEI)
- 无法获取目标服务器证书的SSL指纹--VMware VCSA
- perl php-serialization install,如何在PHP中反序列化Perl Data :: Dumper输出
- SE 例题recap
- w10系统服务器如何创建新用户,win10添加新用户的方法分享
- 128 黙齎 李貴 曷若親征
- Unicode、UTF-8、UTF-16,终于懂了
热门文章
- 580刷590bios_RX580 2048sp刷vbios降为RX570 用上黑苹果美滋滋
- 人工智能属于计算机科学研究方向,《人工智能》课程简介
- js 百度坐标和火星坐标的转换
- python 网盘多帐号_教你怎么拥有(很多)百度网盘2T账号
- 解析淘口令, 淘口令解析,淘口令检测,淘口令不弹原因
- VS2017自带打包软件
- CISSP考试回忆录 | 考试契机、曲折备考、考试现场回顾
- Java接口组装一台计算机编写各组件厂商分别实现CPU,EMS,HardDisk接口
- 10款超牛Vim插件,爱不释手了
- Windows与网络基础-15-本地安全策略