我正在尝试找到以下问题的解决方案,但目前尚不清楚如何解决它。想象一下,我在空间中有以下几点,如下图所示:
如果我认为我唯一已知的信息是点位置和它们的法线,我想确定两点(作为参考,第一点的位置)是否相互面对。例如,从上面的点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
。
我的第一个问题是通过使用提出的解here来解决每对中两个法向量之间的有符号角度,但这适用于某些对而不适用于其他对。关于两个点彼此面对的想法是,如果我们将一个点视为原点,那么如果另一个点位于原点的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];
答案 0 :(得分:2)
您可以使用一些简单的dot products ...
来解决您的问题根据您的说明,如果b
的法线之间的角度(即a
,则点a
位于另一个点na
的视野(FOV)内从a
到b
的向量小于或等于90度。如上所述here,可以通过b-a
和na
的{{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
定义为“指向”另一个点b
从b
到a
是积极的。如上所述inverse cosine,可以通过a-b
和nb
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