这就是:我在3D体积中有8个点/顶点。 我想知道一个点是否包含在框中,其顶点由8个点给出。
此外,我知道4个点位于平行的平面上(我们称之为A)到y轴,其他4个点也位于与y轴平行(B)的另一个平面上。
给定A和B,它们是顶点的4x3矩阵。
我计算连接两对顶点的线位于框的边界超平面上
LinesJoiningVertices =
[A(2,:) - A(1,:), B(1,:) - A(1,:);
A(1,:) - A(1,:), A(4,:) - A(1,:);
A(3,:) - A(4,:), B(4,:) - A(4,:);
A(2,:) - B(2,:), B(3,:) - B(2,:);
B(2,:) - B(1,:), B(4,:) - B(1,:);
A(1,:) - B(1,:), B(4,:) - B(1,:)]
我计算每个边界超平面的法线
for i = 1:6
normals(i,:) = cross(LinesJoiningVertices(i,1:3), LinesJoiningVertices(i,4:6))
end
理论上,框内的点x应该与每个法线有一个负点积(不应该吗?)。 实际上,它不起作用。我得到一个点x我知道是在框内,并且对于第一个,第三个和第五个法线,答案大于0。
我的代码中是否有错误? 我的数学有错误吗?
答案 0 :(得分:1)
您拥有不同点的所有位置以及点x
的位置。想象一个中心点是(0,0,0)
,你的点在它周围形成一个立方体。制作多维数据集的所有外观面,就像使用linesJoiningVertices
但使用faces
一样。你应该有6个外部faces
。
现在,您必须检查x
点是在每个face
多维数据集之前还是之后。如果该点在每个face
之前,则它包含在多维数据集中。这也适用于非立方体。
答案 1 :(得分:1)
对于两个平行平面,任何三维多边形包含两个位于这两个平面中的每个平面上的四个点的子集,只能用 6个点来识别,每个三个可以代表这个平面包含这个多面体中的一个。
对于平行于由{B_0,B_1,B_2}构成的平面的平面上的任何6个点{A_0,A_2,A_3},对于允许多边形的其余两个点需要条件,否则,我们可以面对任何不一致分布的坐标,这些坐标形成随机的非线性形状或圆形或任何东西。 this illustration显示哪两个两条相同颜色的线必须平行,以便将剩余的点作为这些线的交点。
作为一个开始,积分'坐标可以由系统生成:
syms x y z
P = [x,y,z]
left_x=0;right_x=4;
for j=0:1, for k=0:1, A((j)*2+k+1,1:3)=[left_x;floor(10*rand());floor(10*rand())];end,end
for j=0:1, for k=0:1, B((j)*2+k+1,1:3)=[right_x;floor(10*rand());floor(10*rand())];end,end
或手动输入
syms x y z
P = [x,y,z]
left_x=input('enter first x ');
for j=0:1, for k=0:1*~j, A((j)*2+k+1,1:3)=[left_x;input(['print y' char((j)*2+k+49) ' ']);input(['print z' char((j)*2+k+49) ' '])];end,end,
right_x=input('enter second x ');
for j=0:1, for k=0:1*~j, B((j)*2+k+1,1:3)=[right_x;input(['print y' char((j)*2+k+49) ' ']);input(['print z' char((j)*2+k+49) ' '])];end,end,
2-现在我们计算这些点中的哪一个更靠近y轴(更近),它们更靠近x-axix(更低),以找到由每3个点构成的4个虚拟平面的方程。
close_right_point=B((B(:,3)==min(B(:,3))),:)
far_right_point=B((B(:,3)==max(B(:,3))),:)
if(numel(close_right_point(:,1))==1)
temp=B((B(:,3)==min(B(B(:,3)~=min(B(:,3)),3))) ,:);
middler_points(2,:)=temp(1,:);
else
middler_points(2,:)=close_right_point(2,:);
end
closer_point=middler_points(middler_points(:,3)==min(middler_points(1,3),middler_points(2,3)),:)
if(numel(closer_point(:,1))==1)
further_point=middler_points(middler_points(:,3)==max(middler_points(1,3),middler_points(2,3)),:)
else
further_point=closer_point(2,:)
end
close_normal = cross(closer_point(1,:)-close_right_point(1,:), closer_point(1,:)-close_left_point(1,:))
close_plane=dot(close_normal,P-closer_point)
far_normal = cross(further_point-far_right_point(1,:), further_point-far_left_point(1,:))
far_plane=dot(far_normal,P-further_point)
low_left_point=A((A(:,2)==min(A(:,2))),:)
if(numel(low_left_point(:,1))==1)
temp=A((A(:,2)==min(A(A(:,2)~=min(A(:,2)),2))),:);
average_points(1,:)=temp(1,:);
else
average_points(1,:)=low_left_point(2,:);
end
high_left_point=A((A(:,2)==max(A(:,2))),:)
low_right_point=B((B(:,2)==min(B(:,2))),:)
high_right_point=B((B(:,2)==max(B(:,2))),:)
if(numel(low_right_point(:,1))==1)
temp=B((B(:,2)==min(B(B(:,2)~=min(B(:,2)),2))),:);
average_points(2,:)=temp(1,:);
else
average_points(2,:)=low_right_point(2,:);
end
lower_point=average_points(average_points(:,2)==min(average_points(1,2),average_points(2,2)),:)
if(numel(lower_point(:,1))==1)
higher_point=average_points(average_points(:,2)==max(average_points(1,2),average_points(2,2)),:)
else
higher_point=lower_point(2,:);
end
low_normal = cross( lower_point(1,:)-low_right_point(1,:), lower_point(1,:)-low_left_point(1,:))
low_plane=dot(low_normal,P-lower_point)
high_normal = cross( higher_point-high_right_point(1,:), higher_point-high_left_point(1,:))
high_plane=dot(high_normal,P-higher_point)
请注意,法线是它们所代表的平面的垂直向量,任何平面的方程都是从法线向量中提取的。
this是图表的显示方式,参见平行平面和6个充分构成任何3D多边形的动态点。
3-几乎已完成,继续下一阶段,我们通过用户输入接收所需点的坐标:
X=input('enter X ')
Y=input('enter Y ')
Z=input('enter Z ')
然后,检查该点是否超出了与y轴的两个平行平面相关的极右或左边
if (X>right_x)
'out-bounds'
return;
end
if (X<left_x)
'out-bounds'
return;
end
然后,在绘制一条穿过与y轴平行的点的虚线之后,我们确保该点始终保持在由该线与较高和较低虚拟平面的交点形成的线段之间{{3} }
if Z> str2num(char(regexp(evalc(['x=' num2str(X) ';y=' num2str(Y) ';' char(solve(far_plane,z))]),'(\d+.\d*)','match')))
'out-bounds'
return;
end
if Z< str2num(char(regexp(evalc(['x=' num2str(X) ';y=' num2str(Y) ';' char(solve(close_plane,z))]),'(\d+.\d*)','match')))
'out-bounds'
return;
end
if Y> str2num(char(regexp(evalc(['x=' num2str(X) ';z=' num2str(Z) ';' char(solve(high_plane,y))]),'(\d+.\d*)','match')))
'out-of-bounds'
return;
end
if Y< str2num(char(regexp(evalc(['x=' num2str(X) ';z=' num2str(Z) ';' char(solve(low_plane,y))]),'(\d+.\d*)','match')))
'out-of-bounds'
return;
end
4-完成所有这些后,您可以使用此数据输入集
检查此解决方案的有效性0
0
0
6
5.6
0
5.05
4
0
0
6.51
-0.16
6.33
3.59
然后浮点
1
2
3
成功!,您可以通过点击任意点,使用此this simulation shows查看/修改/检查结果,然后使用任何参数更改定义文本字段,也可以拖动点。