【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中是否形成环形链表
导读:额,我介绍的这两种方法,有点蠢啊,小打小闹的那种,后来我查了查资料,别人都起了好高大上的名字,不过,本篇博客,我还是用何下下的风格来写.两种方法,一种是丢手绢法,另外一种,是迷路法. 这两种方法 ...
随机推荐
- 2021年最新js手机号正则验证 最全全部号段
手机号验证正则 /^1[3-9]\d{9}$/ js的例子 isphone.html <html> <body> <input id="Tel" ty ...
- Qt/C++动态启用地图功能/地图拖曳/键盘操作/滚轮缩放/双击放大/连续缩放等
一.前言说明 地图组件为了方便用户的操作,一般会满足各种需求场景,比如用鼠标拖曳地图,实体键盘按键上下左右移动,鼠标滚轮缩放地图大小,双击放大地图,这些常规的操作可以极大的方便用户操作,问题是,有时候 ...
- Qt数据库应用9-数据导出组件使用方法
一.使用方法 1.1 第一步:引入组件 组件中所有代码文件是一个整体,不支持单个代码文件拆分使用,因为很多通用的方法都放在一个代码文件中,复用很多代码. datehead是本组件用到的头文件以及通用的 ...
- Qt音视频开发42-人脸识别客户端
一.前言 人脸识别客户端程序,不需要和人脸识别相关的库在一起,而是通过协议通信来和人脸识别服务端通信交互,人脸识别客户端和服务端程序框架,主要是为了提供一套通用的框架,按照定好的协议,实现人脸识别的相 ...
- java通过apache poi框架读取2007版Excel文件
java系读写excel文件既可以用jxl库,也可以用POI库,但是,jxl库只支持低版本的excel2003,不支持更高版本,无法直接输出*.xlsx文件,只能输出*.xls文件,另外,更新也不频繁 ...
- 使用 NodeLocalDNS 提升集群 DNS 性能和可靠性
本文主要分享如何使用 NodeLocal DNSCache 来提升集群中的 DNS 性能以及可靠性,包括部署.使用配置以及原理分析,最终通过压测表明使用后带来了高达 50% 的性能提升. 1.背景 什 ...
- Dynamic CRM插件程序集中引入第三方dll合并打包
有时候 在插件程序集不可避免的需要使用第三方的dlll 但crm插件平台注册时 只能注册一个dll 即项目自身的dll 第三方的dll无法正常在注册后使用 查找官方资料 找到如下方法 合并打包成一个d ...
- Netty的实现原理、特点与优势、以及适用场景
Netty 1.介绍 Netty是由JBOSS提供的一个java开源框架. Netty是一个高性能.异步事件驱动的NIO框架,它提供了对TCP.UDP和文件传输的支持.作为当前最流行的NIO框架,Ne ...
- 推荐几个不错的 Linux 服务器管理工具
前言 选择一款好的 Linux 服务器管理工具能够极大地提高运维效率,保障业务连续性.今天大姚给大家分享3款不错的 Linux 服务器管理工具,希望可以帮助到有需要的同学. 1Panel 1Panel ...
- 面试题:关于StringBuffer()源码的深度理解Debug分析
import org.junit.Test; /** * @author CH * @create 2021 上午 11:23 */ public class IDEADebug { @Test pu ...