Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Efficient way to reduce a vectors magnitude by a specific length?

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...

like image 903
kbirk Avatar asked Jan 08 '12 22:01

kbirk


2 Answers

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;
}
like image 129
celtschk Avatar answered Oct 03 '22 17:10

celtschk


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.

like image 30
duffymo Avatar answered Oct 03 '22 16:10

duffymo