【问题标题】:determine whether two points with known normals are facing each other or not (matlab)确定具有已知法线的两个点是否彼此面对(matlab)
【发布时间】:2018-03-06 13:59:00
【问题描述】:

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

如果我认为我唯一已知的信息是点位置及其法线,我想确定两个点(将第一个点的位置作为参考)是否彼此面对。例如从上图中的点abcde 我有:

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

b 面对点 de,但不面对点 ac

c 面向点 a,但不面向点 bde

d 面对点 be,但不面对点 ac

最后

e 面向点 abd,但不面向点 c

我的第一个想法是通过使用here 提出的解决方案来处理每对的两个法线向量之间的符号角度,但这对某些对有效,而对其他对无效。关于什么两点相互面对的想法是,如果我们将一个点视为原点,那么如果另一点在原点的 180 度视野内并且其法线向量向内移动(类似于“向") 原点。

任何可以提供帮助的想法。

谢谢。


更新:

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

样本点:

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面对c和e而不是b和d?图片看不清楚
  • 我没有得到“点正对”。对我来说,两点总是面对。还为我定义了相对于表面的法线。请解释。请提供一个包含 3 个点的示例(应该足够了,如果没有,请提供更多)、它们的坐标以及您要达到的目标。
  • @all 我添加了更多信息。 @Ander Biguri a 面对 ce,因为如果我们在点 a 设置一个平面,其法线与点 a 相同,那么两者都在 180 度 FOV 内并指向内部。另一方面,b 点位于 FOV 内,但指向外部,d 点位于同一平面上,并且也指向与点 a 相同的方向。 @PTRK 当我说“面对”时,根据他们的正常情况,他们是否看到对方。您是对的,所有点都彼此面对,但根据它们的法线,其中一些不应该。我希望我很清楚。
  • @ThT 虽然我不太明白,但您只是描述了解决它所需的数学方法。定义isinFOV(a,b)pointingDirection(a,b,na,nb),你就得到了答案
  • @AnderBiguri 你怎么定义pointingDirection(a,b,na,nb) 能详细说明一下吗?

标签: matlab space points normals


【解决方案1】:

你可以通过几个简单的dot products来解决你的问题...

根据您的描述,如果a 的法线(即na)与从@ 出发的向量之间的角度,则b 点位于另一点a 的视野(FOV)内987654338@到b小于等于90度。如here所述,可以通过取b-anadot product,除以b-alength(假设na的长度已经是1)来找到角度,并获取结果的inverse cosine。将其放入anonymous function,您有:

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

然后,如果nb 的分量(b 的法线)沿着从ba 的向量运行,则您可以将一个点b 定义为“指向”另一个点a是积极的。如here 所述,可以通过取a-bnbdot product 并除以a-blength 来找到该组件(并假设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 &amp;&amp;,因为如果isInFOV 已经评估为false,则不需要评估isPointingToward

矢量化

您可以使用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

【讨论】:

  • @gnovice 非常感谢,非常好的解决方案:-)。如果他们想自己尝试,我也为未来的读者添加了示例点。我还了解了匿名函数。我对他们一无所知。非常感谢。
  • @gnovice 我可以将 isFacing(匿名)作为输入传递给 bsxfun,以便我将一个点的逻辑输出与我提供坐标和法线的所有其余点矢量化所有其他点作为两个n x 3 向量。因此,要避免 for 循环。我现在正在尝试,但它似乎不起作用。
  • @ThT:在这种情况下,将bsxfun 应用于匿名函数将不起作用。您必须修改基础方程以考虑多个点。我在答案中添加了一个矢量化版本。
  • @gnovice 我明白了。也感谢您提供矢量化解决方案;-)。
猜你喜欢
  • 1970-01-01
  • 2018-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-23
  • 1970-01-01
  • 2014-05-18
  • 1970-01-01
相关资源
最近更新 更多