确定两个法线已知的点是否相互面对(matlab)

确定两个法线已知的点是否相互面对(matlab),matlab,space,points,normals,Matlab,Space,Points,Normals,我正试图找到以下问题的解决方案,但不清楚如何解决。假设我在空间中有以下几点,如下图所示: 如果我认为我唯一知道的信息是点位置和它们的法线,我想确定两个点(考虑作为第一点的位置的参考)是否彼此面对。例如,从上图中,对于点a、b、c、d和e我有: 点a面向点c和e,而不是点b和d 点b面向点d和e,而不是点a和c 点c面向点a,而不是点b、d和e 点d面向点b和e,而不是点a和c 最后 点e面向点a、b和d,但不面向点c 我的第一个想法是使用提出的解决方案来处理每一对的两个法向量之间的有符号角度,

我正试图找到以下问题的解决方案,但不清楚如何解决。假设我在空间中有以下几点,如下图所示:

如果我认为我唯一知道的信息是点位置和它们的法线,我想确定两个点(考虑作为第一点的位置的参考)是否彼此面对。例如,从上图中,对于点
a
b
c
d
e
我有:

a
面向点
c
e
,而不是点
b
d

b
面向点
d
e
,而不是点
a
c

c
面向点
a
,而不是点
b
d
e

d
面向点
b
e
,而不是点
a
c

最后

e
面向点
a
b
d
,但不面向点
c

我的第一个想法是使用提出的解决方案来处理每一对的两个法向量之间的有符号角度,但这对某些对有效,而对其他对无效。关于两个点彼此面对的思想是,如果我们考虑一个点作为原点,那么如果另一个点在原点的180度视场内,它的法线向量向内(朝向“朝向”),则它面对另一个点。 任何有帮助的想法

谢谢


更新:

试着更清楚一点,回答下面的一些评论。原则上,其在空间中的点对应于面的质心。但是,我事先没有这些信息(即,每个点对应于面中心,或面及其顶点列表)。因此,在更高的层次上,如果我们处理面,问题是如何确定两个面是否彼此可见,但正如我所说,我现在掌握的唯一信息是空间中的实际点及其法线

样本点:

a = [26415.3720833199 11986.0504166605 739];
na = [0 0 1];

b = [27263.8100000023 11103.1983333336 1512.50000000021];
nb = [0.102791963903622 -0.994702876318771 0];

c = [28059.5700000001 11185.4316666667 962.499999999998];
nc = [-0.102791963903623 0.994702876318771 -9.06557542353252e-16];

d = [26606.7112499615 10390.7487916521 739];
nd = [0 0 1];

e = [27792.4499999996 9225.36499999984 2782];
ne = [0 0 -1];

你可以用一些简单的方法来解决你的问题

根据您的描述,如果
a
(即
na
)的法线与从
a
b
的向量之间的角度小于或等于90度,则点
b
在另一点
a
的视野(FOV)内。如上所述,可以通过取
b-a
na
的值,除以
b-a
的值(并且假设
na
的长度已经为1)并取结果的值来找到角度。将其放入一个数据库中,您有:

isInFOV = @(b, a, na) (acosd(dot(b-a, na)./norm(b-a)) <= 90);
isPointingToward = @(b, nb, a) (dot(a-b, nb)./norm(a-b) > 0);
然后,我们可以将点
a
是否“面向”另一点
b
定义为:

isFacing = @(a, na, b, nb) (isInFOV(b, a, na) && isPointingToward(b, nb, a));
请注意,我使用了
和&
,因为如果
isInFOV
的计算结果已经为
false
,则不需要对
isPointingToward
进行计算

矢量化 您可以使用诸如或将对的调用替换为标准矩阵运算之类的函数,重新格式化上述方程以将运算矢量化。这将允许您检查给定点所面对的集合中的哪些点。函数
isFacing
的矢量化版本如下所示:

function index = isFacing(a, na, b, nb)

  V = bsxfun(@minus, b, a);                     % Compute b-a for all b
  V = bsxfun(@rdivide, V, sqrt(sum(V.^2, 2)));  % Normalize each row
  index = (acosd(V*na.') <= 90);                % Find points in FOV of a
  index(index) = (sum(V(index, :).*nb(index, :), 2) < 0);  % Of those points in FOV,
                                                           %   find those pointing
                                                           %   towards a

end

我不懂规则。为什么a面对的是c和e而不是b和d?从图片上看不清楚,我不明白“我们面对的是什么”。对我来说,有两点是永远要面对的。此外,还为我定义了相对于曲面的法线。请解释一下。请提供一个例子,其中有3个点(应该足够了,如果没有,请提供更多),它们的坐标以及您试图实现的目标。@我添加了更多信息@Ander Biguri
a
面对
c
e
,因为如果我们在点
a
设置一个平面,其法线与点
a
相同,那么这两个平面都在180度视野内并指向内部。另一方面,点
b
位于视野内,但指向外侧,点
d
位于同一平面上,并且指向与点
a
相同的方向@PTRK当我说“面对”时,根据他们的正常状态是不是在看对方。所有点都是相互面对的,这是对的,但根据它们的法线,其中一些点不应该相互面对。我希望我是清楚的。@ThT虽然我真的不明白,但你只是描述了你需要解决它的数学方法。定义
isinFOV(a,b)
pointingDirection(a,b,na,nb)
,您就得到了answer@AnderBiguri您如何定义
指针方向(a、b、na、nb)
您能详细说明一下吗。@非常感谢gnovice,非常简洁的解决方案:-)。如果未来的读者想自己尝试,我还为他们添加了示例点。我还学习了匿名函数。我对他们一无所知。非常感谢。@gnovice我可以将isFacing(匿名)作为输入传递给bsxfun,以便将一个点的逻辑输出与所有其余点矢量化,在这里,我将所有其他点的坐标和法线作为两个
nx3
向量提供。因此,要避免for循环。我现在正在尝试,但似乎不起作用。@ThT:在这种情况下,将
bsxfun
应用于匿名函数将不起作用。您必须修改基本方程以考虑多个点。我在答案中添加了矢量化版本。@gnovice我明白了。也感谢您提供的矢量化解决方案;-)。
pointMat = [26415.3720833199 11986.0504166605 739; ...               % Point a
            27263.8100000023 11103.1983333336 1512.50000000021; ...  % Point b
            28059.5700000001 11185.4316666667 962.499999999998; ...  % Point c
            26606.7112499615 10390.7487916521 739];                  % Point d
normalMat = [0 0 1; ...
             0.102791963903622 -0.994702876318771 0; ...
             -0.102791963903623 0.994702876318771 -9.06557542353252e-16; ...
             0 0 1];
p = [27792.4499999996 9225.36499999984 2782];  % Point e
np = [0 0 -1];

>> isFacing(p, np, pointMat, normalMat)

ans =

  4×1 logical array

   1    % Facing a
   1    % Facing b
   0    % Not facing c
   1    % Facing d