- Home /
Find Vector3 perpendicular to Vector3 A in direction of Vector3 B
I haven't been able to find much help on the matter of finding a perpendicular vector using two inputed vectors. Sure I've found help with just the perpendicular part, but not in a given direction.
I'm trying to calculate a new XYZ axis for movement on my game. The Y axis is given by the surface normal (lets say this is Vector A:(0,0.7,-0.7) a slope that goes up if moving forward). To be simple the forward direction (Vector B) will be (0,0,1.0), however this could be any combination depending onthe rotation of the player. I need to find the Vector perpendicular to the normal (Vector A) but in the direction of my players forward (Vector B).
How could I go about doing this?
Answer by Bunny83 · Jun 18, 2014 at 09:15 PM
You just need to project your vector B onto the plane with the normal vector A
All you actually need is the dot product, however your vector A need to be normalized. Unity provides a well optimised method which projects a vector onto a given normal, even when it's not normalized: Vector3.Project().
All you need to do is subtract the projected vector B from the original vector B:
// C# / UnityScript
var vec = B - Vector3.Project(B,A);
If you want the new "vec" to have the same length as the old B you can do this afterwards of course:
vec = vec.normalized * B.magnitude;
edit
Since the question got already bumped i should add that Unity recently added a dedicated method for this kind of projection: Vector3.ProjectOnPlane.
The method literaly is implemented the same way as my solution above, so it's just a bit simpler to use:
var vec = Vector3.ProjectOnPlane(B,A)
Wow, strange how much nonsense you find when searching for "project vector onto plane", however here's a good visualization of the process:
Just got it working, you saved me a lot of frustation working with dot products. Thank you!
@$$anonymous$$oyaAdam: Great you got it working. Does that mean your question is answered? In that case:
:) thx
I love you!! <3 I didn't even know what a projection was, but now I do, thanks! +1
@Bunny83 Unsure if this is what I am looking for. Would you $$anonymous$$d clarifying using my example visual? In the short clip there are two points being placed. The first point is green, the second red. The desire is to calculate the depth of the indent on this model. The first solution that comes to $$anonymous$$d is to select a point in the depth of the indent and another outside of it. Now using these two points and the distance between them can we use ProjectOnPlane() to calculate the third point going parallel from the point outside the indent, and vertical from the point in the indent? I'm thinking if this is possible it's than a distance calculation between the point inside the indent and this third point to deter$$anonymous$$e the depth of the indent. Again, unsure if this is entirely too complicated but this is, part of, the solution that comes to $$anonymous$$d. Please advise, if on the right track, how to use the method properly, or if not, if there's an alternative solution I'm not seeing. As of now, using ProjectOnPlane to create a third point but it's not appearing where I'd expect this third point to be.
I think your confusing two things (which technically are the same but represent something else): The position of your two spheres are points in space. Project / ProjectOnPlane works with direction vectors only. Passing just two position vectors to any of those function most likely won't give you what you want. $$anonymous$$eep in $$anonymous$$d that position vectors start at the world origin.
It's hard to see in your gif but it looks like the object is not flat in that area where the indent is located. This would make it quite difficult to pick proper reference points / reference space.
I guess you have a mesh collider, otherwise this wouldn't make much sense. The best result you would get by grabbing the surface normal of one of the hit points as normal vector. Then just use Vector3.Project(hit2,point - hit1.point, hit1.normal)
this gives you the depth of the indent. It may be negative, depending on where you place the first and the second point. To get a positive result with this example the first point need to be in the indent, the second outside. Though you may simply want to use $$anonymous$$athf.Abs()
.
If you don't want to use the normal of one of the hits, you would need to place 4 points in total in order to get any meaningful reference frame and a point to test. Two points define just a single direction in space. 3 points which define 2 linearly independent directions form a coordinate space which can be used as reference. However those 3 initial points would dictate the orientation of the coordinate system. So their placement is crucial. Using the surface normal is much easier. Though since your mesh is not flat the placement of the two points must not be too far apart, otherwise the curvyness of the mesh produces errors.
Please, if you need any further help, ask a seperate question.
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Getting the distance in a known direction 2 Answers
How to get lateral normals of a bezier curve 1 Answer
Drawing a Mandelbrot Set problem 0 Answers