首页 > 其他分享 >【Matlab】判断点和多面体位置关系的两种方法实现

【Matlab】判断点和多面体位置关系的两种方法实现

时间:2023-07-29 16:46:37浏览次数:45  
标签:disp 判断 end mat flag points 多面体 Matlab Nodes

分别是向量判别法(算法来自他人论文)、体积判别法(code 是我从网上找的)。

方法一: 向量判别法

方法来自一会议论文:《判断点与多面体空间位置关系的一个新算法_石露》2008年,知网、万方、百度学术有收录。
优点:

  • 适合任意多面体
  • 计算简单
  • 速度快

算法原理

img

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四面体和五面体单元的节点约定
img

img

测试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

标签:disp,判断,end,mat,flag,points,多面体,Matlab,Nodes
From: https://www.cnblogs.com/aksoam/p/17590039.html

相关文章

  • 基于matlab实现无人机自适应控制
    ✅作者简介:热爱科研的Matlab仿真开发者,修心和技术同步精进,matlab项目合作可私信。......
  • 【无人机控制】基于线性二次型调节器LQR实现无人机飞行控制附matlab代码
    ✅作者简介:热爱科研的Matlab仿真开发者,修心和技术同步精进,matlab项目合作可私信。......
  • 基于LSTM深度学习网络的时间序列预测matlab仿真
    1.算法理论概述       时间序列预测是一类重要的预测问题,在很多领域都有着广泛的应用,如金融、交通、气象等。然而,由于时间序列数据本身具有时序性和相关性,因此预测难度较大。传统的时间序列预测方法大多采用统计学方法,如ARIMA模型、指数平滑法等,但这些方法在处理非线性、......
  • javaScript判断数据类型的几种方法
    1:typeof返回数据类型,包含这7种:number、boolean、symbol、string、object、undefined、function。typeofnull返回类型错误,返回object。引用类型,除了function返回function类型外,其他均返回object。其中,null有属于自己的数据类型Null,引用类型中的数组、日期、正则也都有......
  • 基于双目人脸图像ORB特征提取匹配的人脸三维点云提取和建模的matlab仿真
    1.算法理论概述      三维人脸建模是计算机视觉领域的一个重要研究方向。传统的人脸建模方法通常基于单张图像,难以准确地获取人脸的三维信息。而基于双目图像的人脸建模方法则可通过多视角的信息获取,实现更加精确的三维人脸建模。本文提出了一种基于双目人脸图像ORB特征提......
  • m基于OFDM+QPSK和turbo编译码以及MMSE信道估计的无线图像传输matlab仿真
    1.算法仿真效果matlab2022a仿真结果如下:    2.算法涉及理论知识概要       基于OFDM+QPSK和Turbo编码以及MMSE信道估计的无线图像传输是一种高效可靠的无线通信系统,广泛应用于图像传输领域。该系统利用正交频分复用(OFDM)技术,将图像数据分成多个子载波进行传输,......
  • m基于OFDM+QPSK和turbo编译码以及LS信道估计的无线图像传输matlab仿真
    1.算法仿真效果matlab2022a仿真结果如下:   2.算法涉及理论知识概要       正交频分复用(OFDM)技术将图像数据分成多个子载波进行传输,使用QPSK调制对信号进行调制,通过Turbo编码增强信号的纠错能力,并采用LS信道估计技术来估计信道状态。 系统原理:    ......
  • shell条件判断 | shell if语句
    摘要shell的if语句shell的elif语句一、基本语法if[condition]then 程序fi注意:condition前后要有空格condition的语法见这篇博客多条分支如下if[condition1]then 程序elif[condition2]then 程序2fi二、快速入门1.if案例1:"ok"是否等于"ok"(判断语......
  • linux shell判断条件
    摘要shell的if或者while语句中的判断条件,可以用于if,for,while语句中判断条件判断类型符号说明举例字符串比较=字符串比较(数字比较不用=)"ok"="ok"整数比较-ltlittle小于1-lt2-lelittleequal小于等于1-lt1-eqequal等于1-lt1-......
  • Java 判断是否可以转化为数字
    Java判断是否可以转化为数字在Java中,我们经常需要判断一个字符串是否可以转化为数字。这在处理用户输入、数据校验以及数据转换等场景下十分常见。本文将介绍几种常用的方法来判断字符串是否可以转化为数字,并提供相关的代码示例。方法一:使用正则表达式正则表达式是一种强大的文......