如何确定一个 3 维向量是否包含在由其他三个向量形成的锐角区域内? [英] How do I determine whether a 3-dimensional vector is contained within the acute region formed by three other vectors?

查看:22
本文介绍了如何确定一个 3 维向量是否包含在由其他三个向量形成的锐角区域内?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在用 C# 进行一个项目,其中我在 R3 中有三个向量,我需要找出第三个向量是否包含在由这些向量形成的区域内.三个基向量任意两个之间的夹角最大为90度,并且都在单位球面上进行了归一化处理.它们可能是负面的.

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

此方法在大多数情况下都有效,但在处理特定向量集时存在一些问题.问题似乎来自基向量的顺序.基向量的处理没有特定的顺序.我需要一种方法以 (x, y, z) 顺序对这三个基向量进行排序,以确保转换正确地将我的目标向量映射到空间的正区域(当它在这些向量内部"时),并映射到空间的负区域当它在外面"时的空间.

非常感谢所有帮助.

二维相关讨论:如何确定一个向量是否在其他两个向量之间?

这些是我最终使用的解决方案.第一个非常接近 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);返回 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);}返回 same_side;}

解决方案

如果你能贴出一些例子,也许还有一些代码就好了.

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

1) sqr 形成的平面的p 是否在同一侧?

2) srp 形成的平面的 q 是否在同一侧?

3) spq 形成的平面的 r 是否在同一侧?

对所有三个问题都回答是"相当于您正在寻找的几何属性.我会告诉你如何回答 1).那么 2) 和 3) 是类似的.

我们通过取叉积找到通过q、r和原点的平面qxr = (q2*r3-q3*r2, q3*r1-q1*r3, q1*r2-q2*r1) =(a,b,c).那么平面的方程为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)

I'm working on a project in C# where I have three vectors in R3, and I need to find out if a third vector is contained within the region formed by those vectors. The three basis vectors have a maximum angle of 90 degrees between any two of them, and they are all normalized on the unit sphere. They can be negative.

So far, I've tried matrix-vector multiplication to find the transformed coordinates of the vector. From there, I check whether all three components are positive.

This method works in most cases, but it has some issues working with specific sets of vectors. The issue seems to come from the order of the basis vectors. The basis vectors are processed in no specific order. I need a way to sort these three basis vectors in (x, y, z) order to ensure that the transformation correctly maps my target vector into the positive region of space when it is "inside" these vectors, and into a negative region of space when it is "outside".

All help is greatly appreciated.

Related discussion in 2D: How to determine if a vector is between two other vectors?

Edit: These are the solutions I ended up using. The first is very close to Edward's solution, and the second is slightly changed for consistency in my project.

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

解决方案

It would be nice if you posted some examples, and maybe some code.

In the absence of that information, let me suggest another approach. Let the three vectors defining the region of space be p=(p1,p2,p3), q=(q1,q2,q3), r=(r1,r2,r3), and the fourth point s=(s1,s2,s3). We need to perform 3 tests:

1) Is s on the same side as p of the plane formed by q and r?

2) Is s on the same side as q of the plane formed by r and p?

3) Is s on the same side as r of the plane formed by p and q?

A yes to all three questions is equivalent to the geometric property you are looking for. I'll show you how to answer 1). Then 2) and 3) are analogous.

We find the plane through q, r and the origin by taking the cross product q x r = (q2*r3-q3*r2, q3*r1-q1*r3, q1*r2-q2*r1) = (a,b,c). Then the equation of the plane is a*x + b*y + c*z = 0.

We put the coordinates of s into the lhs of the above formula and get the expression a*s1 + b*s2 + c*s3, which has some value ds, say. We put the coordinates of p into the above lhs of the above formula and get the expression a*p1 + b*p2 + c*p3, which has some value dp, say.

If ds and dp have the same sign, then s and p are on the same side of the plane. If ds and dp have different signs, then s and p are on opposite sides of the plane.

Here's a boolean expression for the overall test:

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

这篇关于如何确定一个 3 维向量是否包含在由其他三个向量形成的锐角区域内?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆