Jump to content
  • Advertisement
Sign in to follow this  
walle

My new vector class

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

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello. I've made a vector class to represent a 2 dimensional vector...but I don't know much about vectors, therefore made this class to use in games, to learn vectors. I would apprishiate if someone would take a look at it and maybe come with suggestions for improvment... The vectorclass is a template...only have need for inegers now...but soon I'll need floating point values...and the user(me) can only use rectangular coordinates with the class...but can get the magnitud and angle of the vector(not able to set it)...well thats about what I can say about it...
#ifndef VECTOR2D_H
#define VECTOR2D_H

#include <cmath>

template <typename T>
class vec2
{
    public:
        vec2();
        vec2(T x, T y);
        ~vec2();
        
        // Memberfunctions
        T x() const { return m_x; }       // Get the values in the variables
        T y() const { return m_y; }
        T mag();
        T ang();
        
        void x(T x);      // Set the value in the variables
        void y(T y);
        void set(T x, T y);

        
        // Operator overloading
        vec2 operator+(const vec2 &b) const;
        vec2 operator-(const vec2 &b) const;
        vec2 operator+=(const vec2 &b);
        vec2 operator-=(const vec2 &b);
        vec2 operator-() const;
        vec2 operator*(T n) const;
    private:
        // Varables
        T m_x;
        T m_y;
        T m_mag;
        T m_ang;
};

template <typename T>
vec2<T>::vec2()
{
    m_x = m_y = m_mag = m_ang = 0;
}

template <typename T>
vec2<T>::vec2(T x, T y)
{
    m_x = x;
    m_y = y;
}

template <typename T>
vec2<T>::~vec2()
{
    // No allocated memory with new
}

// Memberfunctions
template <typename T>
T vec2<T>::mag()
{
    m_mag = sqrt(m_x*m_x+m_y*m_y);    // Convert from rectangular coordinates to polar coordinates
    return m_mag;
}

template <typename T>
T vec2<T>::ang()
{
    if(m_x == 0 && m_y == 0) { m_ang = 0; }// Convert from rectangular coordinates to polar coordinates
    else { m_ang = atan2(m_y, m_x); }
    return m_ang;
}

template <typename T>
void vec2<T>::x(T x)
{
    m_x = x;
}

template <typename T>
void vec2<T>::y(T y)
{
    m_y = y;
}

template <typename T>
void vec2<T>::set(T x, T y)
{
    m_x = x;
    m_y = y;
}

// Operator overloading
template <typename T>
vec2<T> vec2<T>::operator+(const vec2 &b) const
{
    return vec2(m_x + b.m_x, m_y + b.m_y);
}

template <typename T>
vec2<T> vec2<T>::operator-(const vec2 &b) const
{
    return vec2(m_x - b.m_x, m_y - b.m_y);
}

template <typename T>
vec2<T> vec2<T>::operator+=(const vec2 &b) 
{
    return vec2(m_x += b.m_x, m_y += b.m_y);
}

template <typename T>
vec2<T> vec2<T>::operator-=(const vec2 &b) 
{
    return vec2(m_x -= b.m_x, m_y -= b.m_y);
}

template <typename T>
vec2<T> vec2<T>::operator-() const
{
    return vec2(-m_x, -m_y);
}

template <typename T>
vec2<T> vec2<T>::operator*(T n) const
{
    return vec2(n * m_x, n * m_y);
}

#endif


Thanks.

Share this post


Link to post
Share on other sites
Advertisement
A couple of comments:

1. Getters and setters are usually overkill for what is, essentially, a struct. You may as well just make x and y public variables, unless you're trying to do something special. And making a void x(float) and float x(void) is cute, but may make code that uses this class look confusing.

2. Your polar coordinates implementation is a little incomplete. You compute and cache the magnitude and angle, but you never use the cached magnitude and angle. There's no reason to have them as member variables if you aren't doing caching, and doing caching here is probably overkill.

Share this post


Link to post
Share on other sites
Ok...don't follow you here...chache the magnitus and angle...but don't use them? I only want to be able to get them computed for me when I want them...is'nt that what I'm doing? And I find it easy to use void x(float) and float x() but do other people find it confusing I'll change it =)

Share this post


Link to post
Share on other sites
A tip:


typedef Vec2<T> VECT;

// faster
VECT(const VECT& v):x(v.x),y(v.y){}

// more standard :)
VECT& operator += (const VECT& v) {
return *this = *this + v; // using your code
}


You could also implement this (as I've done)


template <int N, class T>
class PointNT{
...
};



So you have points of every type and every dimension! In this case you cannot use inline ctor and use short loops to cycle for the unknown dimension N

Share this post


Link to post
Share on other sites
Thanks for the replies...why would I want to remove the reminder of that the class is a template...<T> (with the typedef) Yes...what is it called that thing...when you initilase varables outside the constructor (sortof) initialising list or something? And well I'll use this for 2d...then I'll write a new for 3d I think =)

edit:
I get an error...in the new constructor...
error: class `vec2<T>' does not have any field named `x'
error: class `vec2<T>' does not have any field named `y'
Well her's the new code...


#ifndef VECTOR2D_H
#define VECTOR2D_H

#include <cmath>

template <typename T>
class vec2
{
public:
vec2();
vec2(const vec2 &b):x(b.m_x),y(b.m_y){}
~vec2();

// Memberfunctions
T x() const { return m_x; } // Get the values in the variables
T y() const { return m_y; }
T mag();
T ang();

void x(T x); // Set the value in the variables
void y(T y);
void set(T x, T y);


// Operator overloading
vec2 operator+(const vec2 &b) const;
vec2 operator-(const vec2 &b) const;
vec2 operator+=(const vec2 &b);
vec2 operator-=(const vec2 &b);
vec2 operator-() const;
vec2 operator*(T n) const;
private:
// Varables
T m_x;
T m_y;
T m_mag;
T m_ang;
};

template <typename T>
vec2<T>::vec2()
{
m_x = m_y = m_mag = m_ang = 0;
}

template <typename T>
vec2<T>::~vec2()
{
// No allocated memory with new
}

// Memberfunctions
template <typename T>
T vec2<T>::mag()
{
m_mag = sqrt(m_x*m_x+m_y*m_y); // Convert from rectangular coordinates to polar coordinates
return m_mag;
}

template <typename T>
T vec2<T>::ang()
{
if(m_x == 0 && m_y == 0) { m_ang = 0; }// Convert from rectangular coordinates to polar coordinates
else { m_ang = atan2(m_y, m_x); }
return m_ang;
}

template <typename T>
void vec2<T>::x(T x)
{
m_x = x;
}

template <typename T>
void vec2<T>::y(T y)
{
m_y = y;
}

template <typename T>
void vec2<T>::set(T x, T y)
{
m_x = x;
m_y = y;
}

// Operator overloading
template <typename T>
vec2<T> vec2<T>::operator+(const vec2 &b) const
{
return vec2(*this + b);
}

template <typename T>
vec2<T> vec2<T>::operator-(const vec2 &b) const
{
return vec2(*this - b);
}

template <typename T>
vec2<T> vec2<T>::operator+=(const vec2 &b)
{
return vec2(*this = *this + b);
}

template <typename T>
vec2<T> vec2<T>::operator-=(const vec2 &b)
{
return vec2(*this = *this - b);
}

template <typename T>
vec2<T> vec2<T>::operator-() const
{
return vec2(-m_x, -m_y);
}

template <typename T>
vec2<T> vec2<T>::operator*(T n) const
{
return vec2(n * m_x, n * m_y);
}

#endif


Share this post


Link to post
Share on other sites
Quote:
Original post by walle
Ok...don't follow you here...chache the magnitus and angle...but don't use them?

Look what you're doing. Every single time someone calls mag(), you compute the magnitude. Why do you bother storing the value you computed? You never use the stored value. You recompute it each time.

Share this post


Link to post
Share on other sites
Yes...but how do I know when I should re calculate it then...unless I always calculate thet when I get new x, y values...I thought about doing that...but I figure that I'll assign new values alot more than I'll get the magitud, angle...if at all...

Share this post


Link to post
Share on other sites
Quote:
Original post by walle
Yes...but how do I know when I should re calculate it then...unless I always calculate thet when I get new x, y values...I thought about doing that...but I figure that I'll assign new values alot more than I'll get the magitud, angle...if at all...

The point was, you really don't need to store it at all - you'd be better off saving space.

If you wanted to cache the value, you'd have a boolean flag to determine if the current value is accurate. Whenever you change the x or y values of the vector, the magnitute changes. Which means you'd set the flag to 'recalculate'. When you calculate, switch it back to 'yay'. Only recalculte if the flag tells you that you need to.

And if you do use a flag, you cannot expose the members x and y to direct interaction - you'd have to use an accessor function to make sure the 'must recalc' flag gets set correctly.

Share this post


Link to post
Share on other sites
Ok...but I still don't understand why the constructor don't recognice x and y as metods...it doesn't work...

Share this post


Link to post
Share on other sites
Quote:
Original post by walle
Ok...but I still don't understand why the constructor don't recognice x and y as metods...it doesn't work...

Try declaring the constructor after you declare those functions. That should do the trick.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!