0

Is it possible to calculate the length of a vector by rotating it to, and along an axis, and then use that axis to measure the length of the vector? If so, is it less expensive than calculating length by Pythagoras/square-root? i am working in unity (C#)

Example:

Vector3 myVector(x, y, z);
Vector3 myVectorRealigned = Quaternion.FromToRotation(myVector, Vector3.up) * myVector;

float myVectorLength1 = sqrt(myVector.x^2 + myVector.y^2 + myVector.z^2);
float myVectorLength2 = myVectorRealigned.y;

when i tried this it seemed to work! however which of these methods is the best to use/is the least expensive?

Marx
  • 3
  • 1
  • 1
    If you're using visual studio, it has a built-in profiler. It will let you measure the performance of the two. – byxor Jan 03 '17 at 08:37
  • I suggest what @BrandonIbbotson said, but I can imagine that the norm will be faster, as Quaternion calculation requires sqrt as well and the rotation involves a lot more multiplications than the norm. – nyro_0 Jan 03 '17 at 08:46
  • 1
    for the sake of performance, sometimes it's better not to sqrt the sum of squares. like when you wanna compare distances. – Bizhan Jan 03 '17 at 09:11
  • Computing a vector length by rotation is a completely bad idea, as you are computing three components, two of which will be zero. Not counting the fact that to obtain the rotation you need the norm and more. –  Jan 03 '17 at 13:49

1 Answers1

3

I am no mathematician, so please correct me if I am wrong.

As you have tested, both approaches should work, but I guess that the Quaternion approach is more costly.

The norm approach requires 3 multiplications, 2 additions and 1 sqrt.

In contrast, the first step in the quaternion approach (Quaternion.FromToRotation) alone requires is more costly than calculating the norm. A way of calculating the quaternion describing the rotation from one vector to another is this:

Quaternion q;
vector a = crossproduct(v1, v2)
q.xyz = a;
q.w = sqrt((v1.Length ^ 2) * (v2.Length ^ 2)) + dotproduct(v1, v2)

As you see, this alone is more costly than norm = sqrt(myVector.x^2 + myVector.y^2 + myVector.z^2).

Additionally you use that quaternion to rotate your vector again involves dot products, cross products and several multiplications and additions.

E.g.: rotatedVec = 2 * dot(q.xyz, v) * q.xyz + (q.w^2 - dot(q.xyz, q.xyz)) * v + 2 * q.w * cross(q.xyz, v).

References: from-to-quaternion, rotate vector by quaternion

Side Note: If you are concerned with performance and you don't need the exact length of the vector (e.g. for determining the closest object to position x), you can use Vector3.sqrMagnitude (squared norm) as well.

Community
  • 1
  • 1
nyro_0
  • 1,135
  • 1
  • 7
  • 9