- Home /
Given a vector, how do i generate a random perpendicular vector?
Given a vector A, how do i calculate a randomic vector that is perpendicular to A? I've been trying to figure this out myself for some hours but i can't find a way.
Answer by Hellium · Apr 02, 2019 at 07:40 AM
Vector3 B = Vector3.ProjectOnPlane( Random.insideUnitSphere, A ).normalized;
https://docs.unity3d.com/ScriptReference/Vector3.ProjectOnPlane.html
Another solution
B = Vector3.Cross( Random.insideUnitSphere, A ).normalized;
https://docs.unity3d.com/ScriptReference/Vector3.Cross.html
I haven't compared the performances of the two solutions
with both of these approaches there is a chance that Random.insideUnitSphere will be parallel to A, in which case the result will be undefined.
i was also worried that the implementation of Random.insideUnitSphere might be poor, for example something like
while (true):
vec = Random.insideCube().
if (vec.length < 1.0)
return vec.
however i ran some tests and found it to be about 6% more performant than choosing a random point inside a cube, so, it seems good. insideUnitSphere was about 35% more performant than the method sketched above.
Answer by elenzil · Apr 02, 2019 at 06:30 PM
there are some good answers here, but as far as i can tell they all have a small chance of producing undefined results because they rely on being lucky in the choice of a second vector. if the second vector is very close to parallel (or anti-parallel) with A, there's a problem. more than 99% of the time things will be fine, but eventually the result will be surprising. here's a more stable approach.
// choose either the unit Up or Forward axis,
// depending on which one has the smaller dot() with A.
// ie, which one is more perpendicular to A.
// one of them is guaranteed to not be parallel (or anti-parallel) with A.
// any two vectors known to be perpendicular to each other will work fine here.
float du = Vector3.Dot(A, Vector3.up);
float df = Vector3.Dot(A, Vector3.forward);
Vector3 v1 = Mathf.Abs(du) < Mathf.Abs(df) ? Vector3.up : Vector3.forward;
// cross v1 with A. the new vector is perpendicular to both v1 and A.
Vector3 v2 = Vector3.Cross(v1, A);
// rotate v2 around A by a random amount
float degrees = Random.Range(0.0f, 360.0f);
v2 *= Quaternion.AngleAxis(degrees, A.normalized);
Answer by Tortuap · Feb 14 at 11:39 AM
You want this :
B = Quaternion.LookRotation ( A ) * UnityEngine.Random.insideUnitCircle;
Answer by jstopyraIGG · Apr 01, 2019 at 10:06 PM
You need to figure out what "perpendicular" means. Is it towards the camera? Is it world up direction? is it a character or vehicle up direction?
You can use this to rotate a vector
https://answers.unity.com/questions/46770/rotate-a-vector3-direction.html
//This will rotate your vector by a random angle around the world up axis.
vector = Quaternion.AngleAxis(Random.Range(0, 360), Vector3.up) * vector;
Perpendicular means that the angle between the second vector and the first vector is 90 degrees. AngleAxis requires a second vector for the upVector so in your method i would have to generate, again, a random vector. This takes you back to the original question.
There is infinite amount of perpendicular vectors to any given vector, so you need to know what direction it needs to be. For example, in your drawing, the perpendicular vector is towards the camera, or maybe Z axis. You need to figure out, or describe in more details how you want to achieve that perpendicular vector, because as I stated before, there are infinite perpendicular vectors to any given vector.
but if you literally want a random perpendicular vector to the one you drew, then use the equation I've posted.
vector = Quaternion.AngleAxis(Random.Range(0, 360), vector) * vector;
Ok, I understand the question now, and here's what I have:
//this is your green vector
Vector3 myVector = transform.forward;
//this is any vector ever(it literally doesnt matter what you put there as long as it's not perpendicular to your vector)
Vector3 anyVector = new Vector3(1, 0.25f, 0);
//This generates a random vector pernendicular to your green vector.
Vector3 vector = Quaternion.AngleAxis(Random.Range(0, 360), myVector) *
Vector3.Cross(myVector, anyVector).normalized;
Answer by dtrevillyan · Apr 01, 2019 at 10:23 PM
If you have two vectors then you can calculate a perpendicular vector, to both of the original vectors, using the cross product of the two vectors. Here is a link explaining the cross product if you are not familiar with it. The Unity cross product is explained here. Since you have one vector then you need to create a second vector that is random. That vector would have its origin at the one end of vector A and the other end defined by some random point around the origin. The second link has an example showing the use of the cross product that will also be applicable to what you are trying to do. All you need to do is define the second vector.
"Since you have one vector then you need to create a second vector that is random" Yes, exactly, you have to generate a second vector that is perpendicular to the first vector. That was the question
Your answer
Follow this Question
Related Questions
How to get a vector3 (postion) 1 unit away from another in the direction of a 3rd vector3? 2 Answers
How can I make this object relative to the players position? 2 Answers
how to Break a vector3 line into half and Quater 2 Answers
How to transform/rotate a vector onto the same plane as another vector 2 Answers
managing floating point rounding 1 Answer