【Matlab】判断点和多面体位置关系的两种方法实现
分别是向量判别法(算法来自他人论文)、体积判别法(code 是我从网上找的)。
方法一: 向量判别法
方法来自一会议论文:《判断点与多面体空间位置关系的一个新算法_石露》2008年,知网、万方、百度学术有收录。
优点:
- 适合任意多面体
- 计算简单
- 速度快
算法原理

Matlab 实现
主函数为InPolyhedronByVJM(Nodes,P),当前仅支持ABAQUS 四面体和五面体单元,其余有需要的可自行在switch语句添加函数。
输入:
- Nodes:包含节点顺序和坐标的N x 3的矩阵
- P:1x3的行向量
这是我根据ABAQUS单元规则编写的函数,因此其他软件的网格信息文件还需要重写。
function flag = InPolyhedronByVJM(Nodes,P)
% 根据向量判别法,判断点和多面体的位置关系.
% 算法依据:石露,白冰,李小春. 判断点与多面体空问位置关系的一个新算法[C].
% 输入:
% + Nodes: n x 3 matrix
% + P : 1 x 3 row vector
% 单元节点顺序需要满足ABAQUS的约定。
% Nodes是一个n x 3的数值矩阵,每一行表示多面体的一个节点的空间坐标。
% 点在多面体内部的充分必要条件:每个face上任一点到点P的向量和该face法向量的数量积都
% 小于等于0,否则在体外。
NumOfNode = size(Nodes, 1);
switch NumOfNode
case 4
flag = InTetrahedron(Nodes, P);
disp('tetra')
case 5
flag = InPyramid(Nodes, P);
disp('parymid')
end
end
针对C3D4类单元的判别函数
function flag = InTetrahedron(Nodes, P)
% tetra elem have 4 face.
% ABAQUS rule about node ordering and face numbering on element
FaceIDX = [1 2 3;
1 4 2;
2 4 3;
3 4 1];
for faceId = 1 : 1 : size(FaceIDX, 1)
% judge face i: node 1-node 2-node 3 face
% get face normal vector(outside)
n = -1 .* GetNormVector(Nodes(FaceIDX(faceId, 1), :), Nodes(FaceIDX(faceId, 2), :), Nodes(FaceIDX(faceId, 3), :));
% calculate dot product of P and normal vector n
N1P = P - Nodes(FaceIDX(faceId, 1), :);
f = dot(N1P, n);
if f > 0
flag = 0;
return
end
end
flag=1;
end
针对C3D5类单元的判别函数
function flag = InPyramid(Nodes, P)
% Pyramid elem have 5 face.
% ABAQUS rule about node ordering and face numbering on element
FaceIDX = [1 2 3 4;
1 5 2 0;
2 5 3 0;
3 5 4 0;
4 5 1 0];
for faceId = 1 : 1 : size(FaceIDX, 1)
% judge face i: node 1-node 2-node 3 face
% get face normal vector(outside)
n = -1 .* GetNormVector(Nodes(FaceIDX(faceId, 1), :), Nodes(FaceIDX(faceId, 2), :), Nodes(FaceIDX(faceId, 3), :));
% calculate dot product of P and normal vector n
N1P = P - Nodes(FaceIDX(faceId, 1), :);
f = dot(N1P, n);
if f > 0
flag = 0;
return
end
end
flag = 1;
end
求面法向向量的函数
function NormalVector = GetNormVector(p1, p2, p3)
% function return a Normal Vector,base on RightHand Rule, according to three point (row vector)
% NormalVector=cross product of (p2-p1) and (p3-p1)
% check
if (~isrow(p1)) || (~isrow(p2)) || (~isrow(p3))
return
end
p1p2 = p2 - p1;
p1p3 = p3 - p1;
NormalVector = cross(p1p2, p1p3);
end
附:abqus四面体和五面体单元的节点约定


测试Matlab的速度和准确度
%% vector judge method test tetra elem (not include)
Nodes = [40033.883285119, 264.5168630711 , 460.70942035982;
40038.586165682, 269.82366853938, 464.20374836087;
40032.364670267, 268.77493858153, 464.18513138978;
40035.61509136 , 262.38393588741, 466.45744915188];
P = sum(Nodes)/4+[100 0 0];
tic
disp('vector judge method test tetra elem(not include)')
flag = InPolyhedronByVJM(Nodes, P);
disp(flag)
toc
clear
%% volume judge method test tetra elem (not include)
Nodes = [40033.883285119, 264.5168630711 , 460.70942035982;
40038.586165682, 269.82366853938, 464.20374836087;
40032.364670267, 268.77493858153, 464.18513138978;
40035.61509136 , 262.38393588741, 466.45744915188];
P = sum(Nodes)/4+[100 0 0];
tic
disp('volume judge method test tetra elem(not include)')
flag = inpolyhedronByVolCal(Nodes, P);
disp(flag)
toc
clear
%% vector judge method test tetra elem (include)
Nodes = [40033.883285119, 264.5168630711 , 460.70942035982;
40038.586165682, 269.82366853938, 464.20374836087;
40032.364670267, 268.77493858153, 464.18513138978;
40035.61509136 , 262.38393588741, 466.45744915188];
P = sum(Nodes)/4;
tic
disp('vector judge method test tetra elem(include)')
flag = InPolyhedronByVJM(Nodes, P);
disp(flag)
toc
clear
%% volume judge method test tetra elem (include)
Nodes = [40033.883285119, 264.5168630711 , 460.70942035982;
40038.586165682, 269.82366853938, 464.20374836087;
40032.364670267, 268.77493858153, 464.18513138978;
40035.61509136 , 262.38393588741, 466.45744915188];
P = sum(Nodes)/4;
tic
disp('volume judge method test tetra elem(include)')
flag = inpolyhedronByVolCal(Nodes, P);
disp(flag)
toc
clear
%% vector judge method test parymid elem
% node connectivity satisfy abaqus rule
Nodes = [40074.01489458, 184.27859731629, 355.37056669335;
40081.032227826, 179.72253222636, 357.32796879472;
40080.400160415, 184.49866619658, 366.02835222196;
40073.363546048, 189.104242665, 363.93134923301;
40077.379811862, 179.07892353029, 363.81547779482; ];
P = [40077.2381281462+100 183.336592386904 361.294742947572];
tic
disp('test parymid elem')
flag = InPolyhedronByVJM(Nodes, P);
disp(flag)
toc
clear

方法二:体积判别法
这个代码是我在网上找的,出处已经忘了。
Matlab实现(仅限四面体)
function inflag = inpolyhedronByVolCal(points_mat, p_detected)
% input:
% + points_set : 4 point's x y z coordinate,integrated in a 4X3 matrix
% + p_detected : a point needed to detect ,1X3 matrix contain x y z
% coordinate
% return : inflag: 0 or 1
D0 = det([points_mat(1, :) 1;
points_mat(2, :) 1;
points_mat(3, :) 1;
points_mat(4, :) 1]);
D1 = det([p_detected 1;
points_mat(2, :) 1;
points_mat(3, :) 1;
points_mat(4, :) 1]);
D2 = det([points_mat(1, :) 1;
p_detected 1;
points_mat(3, :) 1;
points_mat(4, :) 1]);
D3 = det([points_mat(1, :) 1;
points_mat(2, :) 1;
p_detected 1;
points_mat(4, :) 1]);
D4 = det([points_mat(1, :) 1;
points_mat(2, :) 1;
points_mat(3, :) 1;
p_detected 1]);
if (D0 < 0 && D1 < 0 && D2 < 0 && D3 < 0 && D4 < 0) || ((D0 > 0 && D1 > 0 && D2 > 0 && D3 > 0 && D4 > 0))
inflag = 1;
else
inflag = 0;
end
end
【Matlab】判断点和多面体位置关系的两种方法实现的更多相关文章
- 获取用户当前位置信息的两种方法——H5、微信
在之前的 调用百度地图API的总结 中获取当前位置信息我用的是 H5 ,其实微信也提供了获取用户地理位置的方法,现将这两种方法都贴出来,看情况选择使用. 一.H5 获取当前地理位置得到经纬度 // H ...
- ASP判断一个字符是否为汉字的两种方法
有的时候我们要求用户一定要输入汉字的信息,比如姓名和地址.那么,如何判断一个字符是不是汉字呢?其实在asp中至少有两种方法: 一.直接将某字符用asc转为ascii码,如果是英文,他应该是0-127的 ...
- 判断iPhone的WiFi是否打开的两种方法 之是否连接上 WiFi
iOS中用来查询当前连接的网络信息的API即CNCopyCurrentNetworkInfo 这个API位于SystemConfiguration.framework里面,使用时需要增加.h和包含库文 ...
- 判断一个字符是否为数字的两种方法(C/C++)
在平时,我们经常遇见判断字符是否为数字这种题目,虽然感觉还是很简单,不过我是个更喜欢用函数的人,因为我觉得这样更便捷,所以我更推荐第二种方式. 1.直接判断 #include <stdio.h& ...
- jQuery事件函数位置放置的两种方法
jQuery 事件函数 jQuery 事件处理方法是 jQuery 中的核心函数. 事件处理程序指的是当 HTML 中发生某些事件时所调用的方法. 通常会把 jQuery 代码放到 <head& ...
- Delphi Windows API判断文件共享锁定状态(OpenFile和CreateFile两种方法)
一.概述 锁是操作系统为实现数据共享而提供的一种安全机制,它使得不同的应用程序,不同的计算机之间可以安全有效地共享和交换数据.要保证安全有效地操作共享数据,必须在相应的操作前判断锁的类型,然后才能确定 ...
- Java判断一个字符是否是数字的几种方法的代码
在工作期间,将写内容过程经常用到的一些内容段做个记录,下面内容是关于Java判断一个字符是否是数字的几种方法的内容,希望能对码农们有好处. public class Test{ public stat ...
- applicationContext.xml的文件位置就可以有两种默认实现
ContextLoaderListener的作用就是启动Web容器时,自动装配ApplicationContext的配置信息.因为它实现了ServletContextListener这个接口,在web ...
- JavaScript实现判断图片是否加载完成的3种方法整理
JavaScript实现判断图片是否加载完成的3种方法整理 有时候我们在前端开发工作中为了获取图片的信息,需要在图片加载完成后才可以正确的获取到图片的大小尺寸,并且执行相应的回调函数使图片产生某种显示 ...
- 【java基础 13】两种方法判断hashmap中是否形成环形链表
导读:额,我介绍的这两种方法,有点蠢啊,小打小闹的那种,后来我查了查资料,别人都起了好高大上的名字,不过,本篇博客,我还是用何下下的风格来写.两种方法,一种是丢手绢法,另外一种,是迷路法. 这两种方法 ...
随机推荐
- 天地图接口Python代码详解
天地图是中国国家测绘地理信息局推出的一款权威.全面的在线地理信息系统,提供了丰富的卫星影像.地形.矢量图等地图资源.开发者可以通过天地图提供的API接口,实现地图的展示.搜索.定位等功能.本文将详细介 ...
- 【C#】【平时作业】习题-9-接口
1.什么是接口 为派生类提供因该遵守的标准结构,而本身只包含成员声明,不包含成员的定义 2.接口与抽象类有什么区别 3.设计IBluetooth. public interface IBluetoot ...
- 爬虫自动化脚本+AI赋能
简介 估计大家对网页爬取和数据抓取已经有所了解,市面上也有许多现成的软件可供使用.例如,前几天群里有位朋友利用爬虫技术抓取了AV网站,并搭建了一个磁力链接站点. 本文将介绍如何模拟手动操作,将一些繁琐 ...
- Windows下如何在当前目录下,打开cmd命令窗口
方法一: 在当前目录下,按下shift + 鼠标右键,会出现"在此处打开命令窗口"的字样,然后点击即可. 方法二: 在该文件夹上,按下shift + 鼠标右键,会出现"在 ...
- Qt项目架构经验总结
(一)通用规则 除了极小的微型demo级别项目外,其余项目建议用pri分门别类不同文件夹存放代码文件,方便统一管理和查找. 同类型功能的类建议统一放在一起,如果该目录下代码文件数量过多,也建议拆分多个 ...
- vue辅助函数mapState和mapGetter前面三个点到底是什么意思:对象展开运算符
import store from "./store" computed: { useName: function() { return store.state.userName ...
- Python库房管理系统开发指南
在现代仓储管理中,高效.准确的信息系统是提高运营效率的关键.Python作为一种强大且易于学习的编程语言,非常适合用来开发简易而功能齐全的库房管理系统.本文将详细介绍如何使用Python编写一个基本的 ...
- Python使用技巧2
python url网址拼接 在做爬虫中,经常会遇到需要把一个域名和网址路径进行拼接,在开发时一时没想到方法,特此记录下来. 利用parse.urljoin方法进行网址拼接 from urllib i ...
- 部署简单的单节点k8s
1.Kubernetes简介 Kubernetes,简称K8s,是用8代替名字中间的8个字符"ubernete"而成的缩写.Kubernetes是Google开源的一个容器编排引擎 ...
- 2025-01-18:施咒的最大总伤害。用go语言,一个魔法师掌握了多种不同的咒语,每个咒语对应一个伤害值,这些伤害值存储在数组 power 中,其中可能会有多个咒语具有相同的伤害值。 使用某个特定伤
2025-01-18:施咒的最大总伤害.用go语言,一个魔法师掌握了多种不同的咒语,每个咒语对应一个伤害值,这些伤害值存储在数组 power 中,其中可能会有多个咒语具有相同的伤害值. 使用某个特定伤 ...