确定具有已知法线的两个点是否相互面对(matlab)
determine whether two points with known normals are facing each other or not (matlab)
我正在尝试找到以下问题的解决方案,但不清楚如何解决。想象一下,我在 space 中有以下几点,如下图所示:
如果我认为我唯一已知的信息是点位置及其法线,我想确定两个点(考虑第一个点的位置作为参考)是否相互面对。例如,从上图中的点 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 度视野内并且其法向量向内(有点 "towards")原点。
任何有帮助的想法。
谢谢。
更新:
尝试更清楚一点并回答下面的一些评论。原则上它在 space 中的点对应于人脸的质心。但是,我事先没有这些信息(即每个点对应于面的中心,或面及其顶点的列表)。所以在更高的层次上,如果我们正在处理面孔,问题将是如何确定两张面孔是否彼此可见,但正如我所说,我现在拥有的唯一信息是 [=78= 中的实际点] 和他们的法线。
样本点:
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...
根据您的描述,如果 a
的法线之间的夹角(即 na
) 并且从 a
到 b
的矢量小于或等于 90 度。如所述 here, the angle can be found by taking the dot product of b-a
and na
, dividing by the length of b-a
(and assuming the length of na
is already 1), and taking the inverse cosine of the result. Putting it into an anonymous function,您有:
isInFOV = @(b, a, na) (acosd(dot(b-a, na)./norm(b-a)) <= 90);
然后您可以将一个点 b
定义为 "pointing toward" 另一个点 a
如果 nb
的分量(b
的法线)运行 沿着从 b
到 a
的向量是正的。如所述 here, the component can be found by taking the dot product of a-b
and nb
and dividing by the length of a-b
(and assuming the length of nb
is already 1). Putting it into an anonymous function,您有:
isPointingToward = @(b, nb, a) (dot(a-b, nb)./norm(a-b) > 0);
然后我们可以定义一个点 a
是否是 "facing" 另一个点 b
为:
isFacing = @(a, na, b, nb) (isInFOV(b, a, na) && isPointingToward(b, nb, a));
请注意,我使用了 logical short circuit AND operator &&
,因为如果 isInFOV
已经计算为 false
,则不需要计算 isPointingToward
。
矢量化
您可以使用 bsxfun
or replacing a call to 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
我正在尝试找到以下问题的解决方案,但不清楚如何解决。想象一下,我在 space 中有以下几点,如下图所示:
如果我认为我唯一已知的信息是点位置及其法线,我想确定两个点(考虑第一个点的位置作为参考)是否相互面对。例如,从上图中的点 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 度视野内并且其法向量向内(有点 "towards")原点。
任何有帮助的想法。
谢谢。
更新:
尝试更清楚一点并回答下面的一些评论。原则上它在 space 中的点对应于人脸的质心。但是,我事先没有这些信息(即每个点对应于面的中心,或面及其顶点的列表)。所以在更高的层次上,如果我们正在处理面孔,问题将是如何确定两张面孔是否彼此可见,但正如我所说,我现在拥有的唯一信息是 [=78= 中的实际点] 和他们的法线。
样本点:
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...
根据您的描述,如果 a
的法线之间的夹角(即 na
) 并且从 a
到 b
的矢量小于或等于 90 度。如所述 here, the angle can be found by taking the dot product of b-a
and na
, dividing by the length of b-a
(and assuming the length of na
is already 1), and taking the inverse cosine of the result. Putting it into an anonymous function,您有:
isInFOV = @(b, a, na) (acosd(dot(b-a, na)./norm(b-a)) <= 90);
然后您可以将一个点 b
定义为 "pointing toward" 另一个点 a
如果 nb
的分量(b
的法线)运行 沿着从 b
到 a
的向量是正的。如所述 here, the component can be found by taking the dot product of a-b
and nb
and dividing by the length of a-b
(and assuming the length of nb
is already 1). Putting it into an anonymous function,您有:
isPointingToward = @(b, nb, a) (dot(a-b, nb)./norm(a-b) > 0);
然后我们可以定义一个点 a
是否是 "facing" 另一个点 b
为:
isFacing = @(a, na, b, nb) (isInFOV(b, a, na) && isPointingToward(b, nb, a));
请注意,我使用了 logical short circuit AND operator &&
,因为如果 isInFOV
已经计算为 false
,则不需要计算 isPointingToward
。
矢量化
您可以使用 bsxfun
or replacing a call to 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