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