My new vector class

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

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);

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;
}

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 on other sites

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 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 on other sites
A tip:

typedef Vec2<T> VECT;// fasterVECT(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 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}// Memberfunctionstemplate <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 overloadingtemplate <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 on other sites
Quote:
 Original post by walleOk...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 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 on other sites
Quote:
 Original post by walleYes...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 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 on other sites
Quote:
 Original post by walleOk...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.

• What is your GameDev Story?

In 2019 we are celebrating 20 years of GameDev.net! Share your GameDev Story with us.

• 15
• 9
• 11
• 9
• 9
• Forum Statistics

• Total Topics
634136
• Total Posts
3015757
×