Perpendicular to a 3D direction vector


I’m trying to figure out how to create a vector that is perpendicular to a 3D direction vector that is to the left or right of the source position.

If you look at the image below, I have two position vectors, A and B. Getting the direction and delta angle between those two is simple enough, but I’m trying to get a Perp vector from B that is 90 degrees from the direction between the two (the magenta line in the illustration), as well, the direction of that perp vector is either left or right depending on whether or not the delta angle is positive or negative.

This is really just a 2D calculation (X/Z) because Y will always be zero, but I am working in 3D if it makes a difference.

I’ve tried looking at Vector3.Project() and looking at other posts that calculate Normals but I’m clearly not doing something correctly. If anyone has a solution to this they’re willing to share I would appreciate it.


Simply do:

Vector3 dir = B-A;
Vector3 left = Vector3.Cross(dir, Vector3.up).normalized;

//Vector3 right = -left;
//Vector3 right = Vector3.Cross(Vector3.up, dir).normalized;
//Vector3 right = Vector3.Cross(-dir, Vector3.up).normalized;
//Vector3 right = Vector3.Cross(dir, -Vector3.up).normalized;

All the commented out examples will give you the opposite direction to the right. Since Unity uses a left-handed-system you have to use the “left-hand-rule” (Cross(Thumb, index finger) == middle finger). Make sure your thumb and index finger form an “L” and the middle finger is perpendicular to the other two.

Also note that the “length” of the cross product is the area of the parallelogram defined by the two given vectors. Since we only search a direction the length usually doesn’t matter. So you usually want to normalize the result.

Keep in mind if the two given vectors of a cross product point in the same or exact opposite direction the result will be (0,0,0)

In 2d it’s way simpler to get a vector that is 90° to a given direction. Just swap the two components (X and Z) and invert one of them. Which one you invert defines if you rotate clockwise or counter-clockwise.

// clockwise
Vector3 Rotate90CW(Vector3 aDir)
    return new Vector3(aDir.z, 0, -aDir.x);
// counter clockwise
Vector3 Rotate90CCW(Vector3 aDir)
    return new Vector3(-aDir.z, 0, aDir.x);

So a direction that is 90 rotated could be calculated like this:

Vector3 left = Rotate90CCW(B-A).normalized;
Vector3 right = Rotate90CW(B-A).normalized;

A single 3D vector has an infinite amount of vectors perpendicular to it. Vector3.up for example is perpendicular to any non-zero vector that has y == 0.

Besides that technicality, what you are looking for is cross product.

Vector3.Cross (a, b);

returns a vector that is perpendicular to the plane defined by vectors a and b, as long as they define a plane (they are not collinear)

Looking at your image, you want the cross product between vectors AB and Vector3.up (if the y-coordinate of both points are guaranteed to be the same), but i guess the image can be misleading… If A and B can be anything, without limitations or rules, you need to provide more information about the situation so we can determine which b vector to use in our cross product. Otherwise the magenta vector can be rotated around axis AB and it’ll always be perpendicular to it.