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

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

最佳答案

通过一些简单的dot products就可以解决您的问题...

根据您的描述,一点b在另一个点的视野 (FOV) 内 a如果 a 法线之间的角度(即 na )和来自 a 的向量至b小于或等于90度。如上所述here ,可以通过dot product求得角度的b-ana ,除以lengthb-a (假设na的长度已经是1),并取inverse cosine结果。将其放入anonymous function ,你有:

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

然后您可以定义一个点b作为“指向”另一点a如果 nb 的组件(b 的法线)沿着从 b 出发的向量运行至a是积极的。如上所述here ,可以通过 dot product 找到该组件的a-bnb并除以lengtha-b (假设 nb 的长度已经是 1)。将其放入anonymous function ,你有:

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

请注意,我使用了 logical short circuit AND operator &&isPointingToward如果 isInFOV 则不需要评估已计算为 false .

矢量化

您可以使用 bsxfun 等函数重新表述上述方程以向量化运算。或将调用替换为 dot 与标准矩阵运算。这将允许您检查给定点面向集合中的哪些点。函数 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

关于matlab - 确定法线已知的两个点是否面对面(matlab),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49132597/

相关文章:

mysql - 在数据库中选择较小形状的问题

SQL:指向矩形的点列表

c++ - Eigen-3.3.5 上的 DiagonalPreconditioner 包装器,用于无矩阵稀疏求解器 CG

matlab - matlab中的滤波器矩阵

matlab - 如何为输出参数为零的函数重载 subsref/numArgumentsFromSubscript?

matlab - 如何利用支持向量机提高分类精度

java - 从字符串末尾提取子字符串,直到遇到第一个空格?

c++ - 如何从 OpenCV 中的散点构建网格?

java - 在字符之间添加空格

python - 这个矩阵在什么空间?