如何确定一个 3 维向量是否包含在由其他三个向量形成的锐角区域内?

How do I determine whether a 3-dimensional vector is contained within the acute region formed by three other vectors?

我正在用 C# 开发一个项目,我在 R3 中有三个向量,我需要查明这些向量形成的区域内是否包含第三个向量。三个基向量中任意两个之间的夹角最大为90度,均在单位球面上归一化。它们可以是负数。

到目前为止,我已经尝试了矩阵向量乘法来找到向量的变换坐标。从那里,我检查所有三个组件是否都是积极的。

此方法适用于大多数情况,但在处理特定向量集时存在一些问题。问题似乎出在基向量的顺序上。基向量的处理没有特定顺序。我需要一种方法按 (x, y, z) 顺序对这三个基向量进行排序,以确保转换正确地将我的目标向量映射到 space 的正区域,当它是 "inside" 这些向量时,并在 "outside".

时进入 space 的负区域

非常感谢所有帮助。

二维相关讨论:How to determine if a vector is between two other vectors?

编辑:这些是我最终使用的解决方案。第一个非常接近 Edward 的解决方案,第二个为了在我的项目中保持一致而略有改动。

public bool Vec3Between(Vector3 s, Vector3 p, Vector3 q, Vector3 r)
{
    Vector3 cross = Vector3.Cross(q, r);
    float ds = cross.x * s.x + cross.y * s.y + cross.z * s.z;
    float dp = cross.x * p.x + cross.y * p.y + cross.z * p.z;
    bool same_qr = (ds * dp >= 0);

    cross = Vector3.Cross(r, p);
    ds = cross.x * s.x + cross.y * s.y + cross.z * s.z;
    float dq = cross.x * q.x + cross.y * q.y + cross.z * q.z;
    bool same_rp = (ds * dq >= 0);

    cross = Vector3.Cross(p, q);
    ds = cross.x * s.x + cross.y * s.y + cross.z * s.z;
    float dr = cross.x * r.x + cross.y * r.y + cross.z * r.z;
    bool same_pq = (ds * dr >= 0);

    return same_qr && same_rp && same_pq;
}

public bool Vec3Between(Vector3 vTarget, Vector3[] vRef)
{
    bool same_side = true;
    for (int i = 0; i < 3; i++)
    {
        int i1 = (i < 2) ? (i + 1) : 0;
        int i2 = (i > 0) ? (i - 1) : 2;
        Vector3 cross = Vector3.Cross(vRef[i1], vRef[i2]);
        float plane_vTarget = cross.x * vTarget.x + cross.y * vTarget.y + cross.z * vTarget.z;
        float plane_vRef = cross.x * vRef[i].x + cross.y * vRef[i].y + cross.z * vRef[i].z;
        same_side = same_side && (plane_vTarget * plane_vRef >= 0);
    }
    return same_side;
}

如果您发布一些示例,也许还有一些代码,那就太好了。

在没有这些信息的情况下,让我建议另一种方法。令定义space区域的三个向量为p=(p1,p2,p3)q=(q1,q2,q3)r=(r1,r2,r3)和第四个点s=(s1,s2,s3)。我们需要执行 3 个测试:

1) spqr形成的平面的同一侧吗?

2) s是否与rp形成的平面的q在同一侧?

3) s是否与pq形成的平面的r在同一侧?

所有三个问题的答案都是肯定的,这相当于您正在寻找的几何 属性。我会告诉你如何回答 1)。那么2)和3)类推。

我们通过叉积q x r = (q2*r3-q3*r2, q3*r1-q1*r3, q1*r2-q2*r1) = (a,b,c)找到通过q、r和原点的平面。那么平面的方程就是a*x + b*y + c*z = 0.

我们把s的坐标代入上式的lhs,得到表达式a*s1 + b*s2 + c*s3,它有一些值ds,比如说。我们把p的坐标代入上面公式的lhs,得到表达式a*p1 + b*p2 + c*p3,它有一些值dp,比如说

如果dsdp符号相同,则sp在平面的同一侧。如果 dsdp 符号不同,则 sp 在平面的两侧。

这是一个用于整体测试的布尔表达式:

( 
 ((q2*r3-q3*r2)*s1 + (q3*r1-q1*r3)*s2 + (q1*r2-q2*r1)*s3)
*((q2*r3-q3*r2)*p1 + (q3*r1-q1*r3)*p2 + (q1*r2-q2*r1)*p3)
> 0
)
&&
( 
 ((r2*p3-r3*p2)*s1 + (r3*r1-p1*r3)*s2 + (r1*p2-r2*p1)*s3)
*((r2*p3-r3*p2)*q1 + (r3*p1-r1*p3)*q2 + (r1*p2-r2*p1)*q3)
> 0
)
&&
( 
 ((p2*q3-p3*q2)*s1 + (p3*q1-p1*q3)*s2 + (p1*q2-p2*q1)*s3)
*((p2*q3-p3*q2)*r1 + (p3*q1-p1*q3)*r2 + (p1*q2-p2*q1)*r3)
> 0
)