I would like to extend a method found in C# XNA which will set the length of a vector.

I thought I should go with extensions as that seemed like the only option. It appears that this isn't going to work as intended as my original vector value isn't updated when using this extension method.

public static Vector2 SetLength(this Vector2 v, float length)
        {
            v.Normalize();
            return v *= length;
        }

If I have the line

Vector3 vec = new Vector3(0, 3, 0);

then set the new length using

vec.SetLength(10);

the vec variable does not get updated. Why is this, and what are my alternatives?

Recommended Answers

All 6 Replies

Your extension method is returning a new Vector2. So for your code to work, you would need to update the last part to this

vec = vec.SetLength(10);

With that in mind, you may want to update the method name to something more descriptive of what is happening since you are not merely setting the length. You're normalizing the vector (whatever that entails), and then multiplying it by an input.

With that in mind, you may want to update the method name to something more descriptive of what is happening since you are not merely setting the length. You're normalizing the vector (whatever that entails), and then multiplying it by an input.

I was certain you had to normalize a vector to set its length? How else could it be set. I must be in the range of [-1,1] and then multiplied by the new length?

If I decide to copy and add to the base Vector2 OR Vector3 class

namespace Microsoft.Xna.Framework
{
    [Serializable]
    [StructLayout(LayoutKind.Sequential)]
    public struct Vector3 : IEquatable<Vector3>
    {

then the namespace will conflict. How can I override the orginal namespace without getting the following warnings?

The type 'Microsoft.Xna.Framework.Vector3' in 'C:\' conflicts with the imported type '..\x86\Microsoft.Xna.Framework.dll'. Using the type defined in 'C:\'

@DaveTran: When you normalise a vector you set its length to 1. This is a Unit Vector and of course, multiplying it by a number will set it accordingly. So yes, his method is aptly named for what it does.

@OP: I think you may want to consider why you'd need to do this. A vector ought to be manipulated via its dimensional components. E.g. Your original Vector (a) is x = 3, y = 1, z = 2

So now we get the length of this vector length = sqrt((ax * ax) + (ay * ay) + (az * az)); or; length = sqrt(9 + 1 + 4); Now your length is 3.742 (also notated as |a| where 'a' is the name of your vector).

You normalise your vector:

x = ax/|a|
y = ay/|a|
z = az/|a|

or in numerics:

x = 3.0 / 3.742 = 0.802
y = 1.0 / 3.742 = 0.267
z = 2.0 / 3.742 = 0.534

(Obviously I have precision errors, but if you calculate the length of your new vector it is equal (or near as damn) to 1)

So if you want a length of 5, you multiply each component by 5...

x = x * 5
y = y * 5
z = z * 5

numerics;

x = 0.802 * 5 = 4.01
y = 0.267 * 5 = 1.335
z = 0.534 * 5 = 2.67

So what was the point in setting the length of the vector if all you've done is scaled it? Scaling is computationally must more efficient than what you asked. (ax * scale, ay * scale, az * scale)

Also XNA has a built in scale function ^^

But even still it is a *new* vector. It is only similar to the old vector in orientation. If you are obtaining magnitude information, it will be incorrect (if it is relation to the old vector) If you are changing velocity you should do a vector addition.

If you're doing anything else you should use dot and cross products to get your values.

@DaveTran: When you normalise a vector you set its length to 1. This is a Unit Vector and of course, multiplying it by a number will set it accordingly. So yes, his method is aptly named for what it does.

@OP: I think you may want to consider why you'd need to do this. A vector ought to be manipulated via its dimensional components. E.g. Your original Vector (a) is x = 3, y = 1, z = 2

We are one and the same person :)

If I understand your post correctly would this suffice?

public static void SetLength(ref Vector2 v, float length)
        {
            v.Normalize();
            v *= length;
        }

I would still like to write my own Vector3 class though and not have it conflict with the XNA Framework.

Sorry I wrote the wrong poster name ^^

To write your own Vector class you will have to call it something different or put it in your own namespace and call it direct through the namespace.

MyFramework::Vector3 as opposed to XNAFramework::Vector3 etc...

If you want a set length method, then you write a set length method, but you should multiply each component individually as I don't know the predicted outcome of multiplying the vector by a scalar. (I don't use XNA)

Personally I've never found a reason to set the magnitude of a vector manually.

Personally I've never found a reason to set the magnitude of a vector manually.

Resolving velocity along a contact normal. Velocity length needs to be reduced by a small epsilon value in order to move away from colliding point.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.