Reputation: 4022
Lets say I have an arbitrary vector A. What is the most efficient way to reducing that vectors magnitude by arbitrary amount?
My current method is as follows:
Vector shortenLength(Vector A, float reductionLength) {
Vector B = A;
B.normalize();
B *= reductionLength;
return A - B;
}
Is there a more efficent way to do this? Possibly removing the square root required to normalize B...
Upvotes: 11
Views: 14017
Reputation: 19731
So if I understand you correctly, you have a vector A
, and want another vector which points in the same direction as A
, but is shorter by reductionLength
, right?
Does the Vector
interface have something like a "length" member function (returning the length of the vector)? Then I think the following should be more efficient:
Vector shortenLength(Vector A, float reductionLength)
{
Vector B = A;
B *= (1 - reductionLength/A.length());
return B;
}
Upvotes: 13
Reputation: 308988
If you're going to scale a vector by multiplying it by a scalar value, you should not normalize. Not for efficiency reasons; because the outcome isn't what you probably want.
Let's say you have a vector that looks like this:
v = (3, 4)
Its magnitude is sqrt(3^2 + 4^2) = 5
. So let's normalize it:
n = (0.6, 0.8)
This vector has magnitude 1; it's a unit vector.
So if you "shorten" each one by a factor of 0.5, what do you get?
shortened v = (3, 4) * 0.5 = (1.5, 2.0)
Now let's normalize it by its magnitude sqrt(6.25):
normalized(shortened v) = (1.5/2.5, 2/2.5) = (0.6, 0.8)
If we do the same thing to the unit vector:
shortened(normalized v) = (0.6, 0.8) * 0.5 = (0.3, 0.4)
These are not the same thing at all. Your method does two things, and they aren't commutative.
Upvotes: 7