I know that question has been asked a few times before, but none of the solutions seem to work for me.
I have two different points(A,B) in 3D space. Between those to points I calculate the direction vector.
I would like to calculate the perpendicular vector to the direction vector.
Right now I have something like this:
Unfortunately, that does not work. The angle between the direction vector and my supposedly perpendicular vector is always smaller than 90 degrees.
Generally speaking the perpendicular vector of a vector(x,y,z) should be (x,z,-y) if I am not mistaken. But that does not seem to work here. Can anyone help me out?
The method which is used to calculate the perpendicular vector is Vector3.Cross. It takes two parameters. Both of them are direction vectors. The easiest way to comprehend it is to remember that Unity uses “left-hand rule”. When you arrange your fingers as in the picture, the index finger (pointing upwards) is the direction vector which you supply as the first parameter. Thumb is the finger which represents the direction vector supplied as the second parameter. This way, Vector3.Cross returns the third vector (middle finger), which is also direction vector. And, this is your perpendicular vector.
So, let me reproduce my workflow.
At first, create three empty gameobjects, name them “A”, “B” and “C”. Then put the script on one of them (I put it on “A”), and assign all of them to “public Transform points” in the inspector. Next, set their positions in the inspector as follows: A(0, 0, -1), B(0, 0, 0), C(0, 1, 0). Now, your points (A and B) are connected with the blue line (represented by thumb and this is the second parameter). The red line is your perpendicular vector. And, the green one (from point B to C) represents the direction vector which you need to pass as the first parameter to Vector3.Cross. Here’s the picture and the code:
// points A, B and C
public Transform[] points;
// Lerp Value slider used to set the tail of the perpendicular vector
[Range(0f, 1.0f)] public float lerpValue = 1.0f;
// radius of each wire sphere
public float radius = 0.1f;
private void OnDrawGizmos()
{
if (points==null || points.Length < 3) return;
// I assigned each gameobject position to appropriate point
Vector3 A = points[0].position;
Vector3 B = points[1].position;
Vector3 C = points[2].position;
// This draws wire spheres for debugging purpose
Gizmos.DrawWireSphere(A, radius);
Gizmos.DrawWireSphere(B, radius);
Gizmos.DrawWireSphere(C, radius);
// this is the direction between A and B vectors. Thumb finger. It is the Vector3.Cross second parameter.
Vector3 thumb = B - A;
// this is the tail of the perpendicular vector. You can manipulate the position of the tail as you wish, using Lerp Value slider in the inspector.
Vector3 tail = Vector3.Lerp(A, B, lerpValue);
// this is the first parameter of Vector3.Cross. Direction vector. Index finger.
Vector3 indexFinger = C - B;
// middleFinger is your perpendicular vector. It's the direction.
Vector3 middleFinger = Vector3.Cross(indexFinger, thumb);
// This draws blue line from point A to point B. In other words from point A in the direction of point B.
Gizmos.color = Color.blue;
Gizmos.DrawRay(A, thumb);
// This draws green line from point B to point C. In other words from point B in the direction of point C.
Gizmos.color = Color.green;
Gizmos.DrawRay(B, indexFinger);
// This draws red line from where the tail is in the direction of perpendicular vector. This is your vector.
Gizmos.color = Color.red;
Gizmos.DrawRay(tail, middleFinger);
}