# Vector Projection with zero length

This topic is 2153 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Currently I'm doing this

        public static Vector2 Project(this Vector2 A, Vector2 B)
{
if (A.X != 0f || A.Y != 0)
return Vector2.Multiply(A, Vector2.Dot(A, B) / Vector2.Dot(A, A));
else
return A;
//return B; ???
}


Without the zero length check in there every thing blows up because this method returns an effectively infinite length vector.  What is the best thing to return when the length of A is zero?

##### Share on other sites

If A is a zero-vector, then the result is undefined and anything you return is technically wrong. Which, among all incorrect, options is the better one depends on what it is you do with the result. But I would suggest that, in general, the best thing to do is avoid division by zero, or in this case having a zero-length A, in the first place.

##### Share on other sites

Return the zero vector.

You are trying to scale A (which is the zero vector) by an indeterminate dot(A, B) / dot(A, A). dot(A, B) == 0, dot(A, A) == 0, so you are trying to calculate A * (0/0), but A is zero anyway => return A (which is the zero vector).

To see this (non-rigorous argument) is correct, consider the limit when length(A) tends to zero. (EDIT: If you halve the length of A, the length of the projected vector is halved too, so it is easy to see that the limit when length(A) -> 0 is the zero vector).

EDIT: Considering the limit is the way to do it, but it doesn't apply in all cases e.g. normalisation of a vector, which has no limit as the length tends to zero. You have to consider each function separately.

##### Share on other sites

To see this (non-rigorous argument) is correct, consider the limit when length(A) tends to zero. (EDIT: If you halve the length of A, the length of the projected vector is halved too, so it is easy to see that the limit when length(A) -> 0 is the zero vector).

I'm not sure what you mean considering the result should be the same for all lengths of A with the sole exception 0.

##### Share on other sites

Whoops, my mistake then.

You can't return anything meaningful in that case. Either return the zero vector anyway or throw an exception.

EDIT: I confused myself from looking at this picture in wikipedia from the vector projection page

which suggested to me that if a was twice as long then the length a1 would be also. EDIT2: I was confused ;) More coffee required.

##### Share on other sites

Currently I'm doing this

        public static Vector2 Project(this Vector2 A, Vector2 B)
{
if (A.X != 0f || A.Y != 0)
return Vector2.Multiply(A, Vector2.Dot(A, B) / Vector2.Dot(A, A));
else
return A;
//return B; ???
}


Without the zero length check in there every thing blows up because this method returns an effectively infinite length vector.  What is the best thing to return when the length of A is zero?

What you are trying to do here is figure out how much of B is pointing in the A direction. This assumes that A is a direction vector. A direction vector is usually required to have a length of 1. Any vector that can be normalized can be a direction vector. However, a zero-length vector cannot be normalized and thus has no direction. If A was correctly normalized your project function simply return Vector2.Dot(A,B). If you should not be projecting zero-length vectors, it seems that there is a problem upstream of this function. Personally, I would get rid of this function and make sure that my direction vector was normalized and use the dot product directly.

-Josh

##### Share on other sites

Whoops, my mistake then.

You can't return anything meaningful in that case. Either return the zero vector anyway or throw an exception.

EDIT: I confused myself from looking at this picture in wikipedia from the vector projection page

which suggested to me that if a was twice as long then the length a1 would be also. EDIT2: I was confused ;) More coffee required.

Also I'm projecting B onto A, as where this example projects A onto B.

##### Share on other sites

Currently I'm doing this

        public static Vector2 Project(this Vector2 A, Vector2 B)
{
if (A.X != 0f || A.Y != 0)
return Vector2.Multiply(A, Vector2.Dot(A, B) / Vector2.Dot(A, A));
else
return A;
//return B; ???
}


Without the zero length check in there every thing blows up because this method returns an effectively infinite length vector.  What is the best thing to return when the length of A is zero?

What you are trying to do here is figure out how much of B is pointing in the A direction. This assumes that A is a direction vector. A direction vector is usually required to have a length of 1. Any vector that can be normalized can be a direction vector. However, a zero-length vector cannot be normalized and thus has no direction. If A was correctly normalized your project function simply return Vector2.Dot(A,B). If you should not be projecting zero-length vectors, it seems that there is a problem upstream of this function. Personally, I would get rid of this function and make sure that my direction vector was normalized and use the dot product directly.

-Josh

Normalizing requires a square root call which I'd like to avoid as much as possible, and seeing as I can project just fine while avoiding that I see no benefit in doing so. Also zero vectors are perfectly valid in some cases(a velocity vector for example).

##### Share on other sites
I want to point out that the code in the OP is not very robust: If the input is the vector (0, epsilon) --where epsilon is a number so small that its square is 0--, the code will still divide by zero.

##### Share on other sites

I want to point out that the code in the OP is not very robust: If the input is the vector (0, epsilon) --where epsilon is a number so small that its square is 0--, the code will still divide by zero.

        public static Vector2 Project(this Vector2 A, Vector2 B)
{
float DotOverDot = Vector2.Dot(A, B) / Vector2.Dot(A, A);
if (float.IsNaN(DotOverDot) || float.IsInfinity(DotOverDot))
return Vector2.Zero;
else
return Vector2.Multiply(A, DotOverDot);
}
Edited by Grain

• 21
• 11
• 9
• 17
• 13