【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中是否形成环形链表
导读:额,我介绍的这两种方法,有点蠢啊,小打小闹的那种,后来我查了查资料,别人都起了好高大上的名字,不过,本篇博客,我还是用何下下的风格来写.两种方法,一种是丢手绢法,另外一种,是迷路法. 这两种方法 ...
随机推荐
- 巧用mask属性创建一个纯CSS图标库
说明 mask 是CSS中的一个属性,它允许开发者在元素上设置图像作为遮罩层.这个属性的强大之处,在于它可以接受多种类型的值,包括关键字值.图像值.渐变色,甚至可以设置多个属性值. SVG(Scala ...
- Qt编写物联网管理平台49-设备模拟工具
一.前言 本系统专门配备了设备模拟工具,用来在没有外接真实设备的时候,模拟modbus协议数据,支持多个设备,支持串口和网络方式,可切换正常数据和报警数据,反应到主程序上.对应主程序中两种端口,一种是 ...
- Qt通用方法及类库10
函数名 //获取保存的文件 static QString getSaveName(const QString &filter, QString defaultDir = QCoreApplic ...
- 解决Failed to load module canberra-gtk-module错误
在Ubuntu环境里,通过./triangulation 1.png 2.png 命令运行高翔的ch7的triangulation程序时报错: Gtk-Message: 09:10:26.571: F ...
- 《深入理解Mybatis原理》MyBatis的sqlSession执行流程
sqlSessionFactory 与 SqlSession 正如其名,Sqlsession对应着一次数据库会话.由于数据库会话不是永久的,因此Sqlsession的生命周期也不应该是永久的,相反,在 ...
- 高通Android工程释放ADSP侧GPIO给AP侧(HLOS)解决uart只能收或者发,gpio 无法配置成输入或者输出
在许多sensor的调试过程中总是会遇到各种GPIO被占用的情况,特别是以下几种情况:UART 只能发或收,GPIO 配置了pinctl output但是gpio依旧为输入. 1.判断GPIO口状态 ...
- CDS标准视图:付款锁定原因描述 I_PaymentBlockingReasonText
视图名称:付款锁定原因描述 I_PaymentBlockingReasonText 视图类型:基础 视图代码: 点击查看代码 //Documentation about annotations can ...
- H5调用手机拨打电话的功能
里面加上: 我没有写也是可以的 <meta name="format-detection" content="telephone=yes"/> 该标 ...
- 深入理解Java泛型、协变逆变、泛型通配符、自限定
禁止转载 重写了之前博客写的泛型相关内容,全部整合到这一篇文章里了,把坑都填了,后续不再纠结这些问题了.本文深度总结了函数式思想.泛型对在Java中的应用,解答了许多比较难的问题. 纯函数 协变 逆变 ...
- 独立开发经验谈:如何借助 AI 辅助产品 UI 设计
我在业余时间开发了一款自己的独立产品:升讯威在线客服与营销系统.陆陆续续开发了几年,从一开始的偶有用户尝试,到如今线上环境和私有化部署均有了越来越多的稳定用户,在这个过程中,我也积累了不少如何开发运营 ...