确定具有已知法线的两个点是否彼此面对(matlab)

时间:2018-03-06 13:59:00

标签: matlab space points normals

我正在尝试找到以下问题的解决方案,但目前尚不清楚如何解决它。想象一下,我在空间中有以下几点,如下图所示:

enter image description here

如果我认为我唯一已知的信息是点位置和它们的法线,我想确定两点(作为参考,第一点的位置)是否相互面对。例如,从上面的点abcde的图片我有:

a面向点ce,但不包括点bd

b面向点de,但不包括点ac

c面向点a但不包括点bde

d面向点be,但不包括点ac

和最终

e面向点abd,但不是点c

我的第一个问题是通过使用提出的解here来解决每对中两个法向量之间的有符号角度,但这适用于某些对而不适用于其他对。关于两个点彼此面对的想法是,如果我们将一个点视为原点,那么如果另一个点位于原点的180度视场内并且其法向量向内(其类型为“朝着“)起点。

任何有用的想法。

感谢。

更新

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

enter image description here

示例点:

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];

1 个答案:

答案 0 :(得分:2)

您可以使用一些简单的dot products ...

来解决您的问题

根据您的说明,如果b的法线之间的角度(即a,则点a位于另一个点na的视野(FOV)内从ab的向量小于或等于90度。如上所述here,可以通过b-ana的{​​{3}}除以b-a的{​​{3}}来找到角度(和假设na的长度已经为1),并取结果的dot product。将它放入length,你有:

isInFOV = @(b, a, na) (acosd(dot(b-a, na)./norm(b-a)) <= 90);

如果b的组件(a的正常)沿着向量运行,则可以将点nb定义为“指向”另一个点bba是积极的。如上所述inverse cosine,可以通过a-bnb anonymous function并除以a-b的{​​{3}}来找到该组件(和假设nb的长度已经为1)。将它放入here,你有:

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));

请注意,我使用了dot product &&,因为如果isPointingToward已经评估为isInFOV,则不需要评估false

向量化

您可以使用length之类的函数或使用标准矩阵运算替换对anonymous function的调用来重新构造上述方程以对操作进行矢量化。这将允许您检查给定点面对的集合中的哪些点。函数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

实施例

使用问题中的示例数据:

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