分别是向量判别法(算法来自他人论文)、体积判别法(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】判断点和多面体位置关系的两种方法实现的更多相关文章

  1. 获取用户当前位置信息的两种方法——H5、微信

    在之前的 调用百度地图API的总结 中获取当前位置信息我用的是 H5 ,其实微信也提供了获取用户地理位置的方法,现将这两种方法都贴出来,看情况选择使用. 一.H5 获取当前地理位置得到经纬度 // H ...

  2. ASP判断一个字符是否为汉字的两种方法

    有的时候我们要求用户一定要输入汉字的信息,比如姓名和地址.那么,如何判断一个字符是不是汉字呢?其实在asp中至少有两种方法: 一.直接将某字符用asc转为ascii码,如果是英文,他应该是0-127的 ...

  3. 判断iPhone的WiFi是否打开的两种方法 之是否连接上 WiFi

    iOS中用来查询当前连接的网络信息的API即CNCopyCurrentNetworkInfo 这个API位于SystemConfiguration.framework里面,使用时需要增加.h和包含库文 ...

  4. 判断一个字符是否为数字的两种方法(C/C++)

    在平时,我们经常遇见判断字符是否为数字这种题目,虽然感觉还是很简单,不过我是个更喜欢用函数的人,因为我觉得这样更便捷,所以我更推荐第二种方式. 1.直接判断 #include <stdio.h& ...

  5. jQuery事件函数位置放置的两种方法

    jQuery 事件函数 jQuery 事件处理方法是 jQuery 中的核心函数. 事件处理程序指的是当 HTML 中发生某些事件时所调用的方法. 通常会把 jQuery 代码放到 <head& ...

  6. Delphi Windows API判断文件共享锁定状态(OpenFile和CreateFile两种方法)

    一.概述 锁是操作系统为实现数据共享而提供的一种安全机制,它使得不同的应用程序,不同的计算机之间可以安全有效地共享和交换数据.要保证安全有效地操作共享数据,必须在相应的操作前判断锁的类型,然后才能确定 ...

  7. Java判断一个字符是否是数字的几种方法的代码

    在工作期间,将写内容过程经常用到的一些内容段做个记录,下面内容是关于Java判断一个字符是否是数字的几种方法的内容,希望能对码农们有好处. public class Test{ public stat ...

  8. applicationContext.xml的文件位置就可以有两种默认实现

    ContextLoaderListener的作用就是启动Web容器时,自动装配ApplicationContext的配置信息.因为它实现了ServletContextListener这个接口,在web ...

  9. JavaScript实现判断图片是否加载完成的3种方法整理

    JavaScript实现判断图片是否加载完成的3种方法整理 有时候我们在前端开发工作中为了获取图片的信息,需要在图片加载完成后才可以正确的获取到图片的大小尺寸,并且执行相应的回调函数使图片产生某种显示 ...

  10. 【java基础 13】两种方法判断hashmap中是否形成环形链表

    导读:额,我介绍的这两种方法,有点蠢啊,小打小闹的那种,后来我查了查资料,别人都起了好高大上的名字,不过,本篇博客,我还是用何下下的风格来写.两种方法,一种是丢手绢法,另外一种,是迷路法. 这两种方法 ...

随机推荐

  1. 开启Word、Excel、PPT时速度很慢的一种解决方法

      本文介绍基于修改加载项,解决Microsoft Office系列软件开启速度较慢的办法.   最近,发现Excel软件的打开速度越来越慢,会在一定程度上影响工作效率.因此尝试对此加以解决.其中,本 ...

  2. ScheduleServerRunnable2

    package com.xx.schedule.thrift.server; import com.xx.schedule.thrift.service.ScheduleService; import ...

  3. Qt音视频开发18-不同视频打开无缝切换

    一.前言 在轮询视频的时候,通常都是需要将之前的视频全部关闭,然后打开下一组视频,在这个切换的过程中,如果是按照常规的做法,比如先关闭再打开新的视频,肯定会出现空白黑屏之类的过度空白区间,如何避免这个 ...

  4. Qt编写物联网管理平台31-用户权限管理

    一.前言 随着需求的不断变化,功能的增多,在用户信息这块,除了需要用户登录退出验证以外,还需要有个简单的用户权限逻辑处理,比如限定某些用户只有查看权限,没有删除记录.清空记录.系统设置的权限,与之相对 ...

  5. Qt编写的项目作品17-自定义曲线图柱状图

    一.功能特点 可设置X轴Y轴范围值. 可设置背景颜色.文本颜色.网格颜色. 可设置三条曲线颜色.颜色集合. 可设置是否显示十字定位线,支持分别开启横向或者纵向定位线. 可设置十字定位线的宽度.颜色. ...

  6. IM跨平台技术学习(六):网易云信基于Electron的IM消息全文检索技术实践

    本文作者网易云信高级前端开发工程师李宁,本文有修订. 1.引言 在IM客户端的使用场景中,基于本地数据的全文检索功能扮演着重要的角色,最常用的比如:查找聊天记录.联系人等. 类似于IM中的聊天记录查找 ...

  7. 第十二章 ArrayList&LinkedList源码解析

    一.对于ArrayList需要掌握的七点内容 ArrayList的创建:即构造器 往ArrayList中添加对象:即add(E)方法 获取ArrayList中的单个对象:即get(int index) ...

  8. biancheng-Redis教程

    目录http://c.biancheng.net/redis/ 1Redis是什么2Windows下载安装Redis3Ubuntu下载安装Redis4Redis配置文件5Redis数据类型6Redis ...

  9. 动态添加html事件无响应

    问题描述:在页面中动态使用js添加的html中设置了onclick事件,生产页面后点击事件无效并提示:Cannot read property 'xxx' of undefined 如: $('.te ...

  10. KafKa动态分组ID

    背景说明:做这个的原因主要是因为懒,KafKa监听没有独立项目出去,由于KafKa没有组内广播模式,这就造成了一个问题:项目多处启动的时候,就只有一个地方能接收信息.这个时候就要手懂修改分组ID了. ...