I have a vector math problem that is beyond me, I don’t really know how to begin solving it, but i’m certain it’d be no problem for someone out there.
Imagine a plane floating in 3D space, and its at a random orientation. I need to get the vector in that plane which is pointing closest to the world down direction. And it needs to be done in an efficient way ( ie using classic vector maths, not using iteration ).
I can solve the problem in english:
Convert the world down vector into the plane’s local coordinates. Then flatten that vector so that it’s within the plane. Convert vector back into world coordinates.
Hopefully that makes sense to you, and perhaps you know how to do this mathematically? Or perhaps you even know how you’d do this in code?
The following code is a fairly short and efficient way to do what you describe in your English description of the solution:-
var planeUp: Vector3;
var planeRight: Vector3;
var planeForward: Vector3;
Vector3.OrthoNormalize(planeUp, planeRight, planeForward);
vat mat: Matrix4x4;
mat.SetRow(0, planeRight);
mat.SetRow(1, planeUp);
mat.SetRow(2, planeForward);
var planeNearDown = mat.MultiplyPoint3x4(-Vector3.up);
planeNearDown.y = 0;
var worldNearDown = mat.inverse.MultiplyPoint3x4(planeNearDown);
I’m guessing that the orientation of your plane is determined by a vector normal to the face. The OrthoNormalize call just generates two other vectors at right angles to the normal to define a coordinate space for the plane. The first matrix multiplication transforms the world down vector to the plane’s space. The Y coordinate of the transformed point is then set to zero (ie, the vector is forced to be within the plane). The inverse matrix multiplication finally gets the vector back into world space.
I’m trying to solve a similar problem here.
I have 2 transforms (A, B) and I want to find the ‘horizontal’ direction from A to B.
So, using the examples in this thread I got it to work perfectly if A rotation stays at (0,0,0). Any rotation, even on Y will mess up the direction from A to B.
What could be the problem here?
Oddly - if I try to draw pW it will always be zero, I can only get a visual result if I use p.
This is what I’m using which is just a C# versions of what andeee posted - tomvds’s solution also has the same problems if the transform is rotated
void OnDrawGizmos()
{
Matrix4x4 mat = new Matrix4x4();
mat.SetRow(0, transform.right);
mat.SetRow(1, transform.up);
mat.SetRow(2, transform.forward);
Vector3 p = mat.MultiplyPoint3x4(t.position);
p.y =0;
Vector3 pW = mat.inverse.MultiplyPoint3x4(p);
Gizmos.DrawLine(transform.position, transform.position + pW);
}
hey bryan -
from what I understand that will return the angle between two vectors? I’m not sure how that would help in my case, could you explain a bit more?
Still having trouble with this… and seems to be with the rotations… both Transforms can move around freely and I’ll be able to get the direction vector projected into the first transforms local space - but rotate it and it’s all off!
Yes, that’s almost correct… transforming the direction to the target into object space, zero the Y…
It works perfect, as do the other solutions posted here that use Vector3.Project() and even using the Matrix alternative… works great until you rotate it!
If you try one of the examples you see the vector is indeed projected onto a plane defined by a transforms up vector… then try rotating it!
I do not understand why this is happening? I do admit i’m not that well versed in this sort of math!
You explained you wanted the direction between two Vectors, the angle will show the angle in degrees between two Vectors. Alternatively, if you don’t care about pitch you could use Vector2.Angle by leaving out one:
var angle=Vector2.Angle(Vector2(a.transform.position.x,a.transform.position.z),Vector2(b.transform.position.x,b.transform.position.z));
At least in theory, math is not my strong suit either. If you want distance, use Vector3.Distance…
Well, I’m not sure what I had missed on previous attempts but I got what I was after.
For a Transform transform, this will get the projected direction vector to target on transform’s local space XZ plane.
For a real world example, imagine a camera system where you can set constraints whilst within certain zones…
Well, one of these camera zones may restrict camera movement to its local XZ (or an abitrary plane for that matter)… in this case, I needed to get the local, projected direction vector to the target so that the camera knew which way it was allowed to move in world space.