Archived

This topic is now archived and is closed to further replies.

Gladiator

Need some help with Vectors

Recommended Posts

Gladiator    127
Hi there! I need someone who knows quite a bit about the OOP aspect of C++ and would be kind enough to take a look at my VECTOR class to see if I have implemented it correctly. By now I have been doing mixed C/C++ and I don''t know if what I''ve written in C++ is efficient or not (I know that I need to inline most of my member functions). What I''m looking for is whether or not I have to include the operators overloading in the class or not, also if I have to return a VECTOR& or VECTOR from a function (like the Cross Product), basically that kind of stuff. Anyone willing to help me? What if I say "Pleaaaaasssee?" Okay, I will just post the code here for everyone to see instead of having the hassle to send it to everyone separately! This is what I currently have, but since I wrote it just now, I haven''t changed a few things I want to change. For example I think it would be better if I move the operators'' overloading outside the class. Thank you people! You''re the best!
        
/////////////////// VECTOR.H ///////////////////////

#ifndef __VECTOR_H
#define __VECTOR_H

class VECTOR
{
public:
	VECTOR();
	VECTOR( float _x, float _y, float _z );
	VECTOR( VECTOR &v );
	~VECTOR();

	float	Magnitude();
	float	Dot( VECTOR &v );
	VECTOR	Cross( VECTOR &v );
	void	Normalize();

	void	SetX( float _x );
	void	SetY( float _y );
	void	SetZ( float _z );
	void	SetVector( VECTOR &v );
	void	SetVector( float _x, float _y, float _z );

	float	GetX();
	float	GetY();
	float	GetZ();
	VECTOR	GetVector();

	int	operator == ( VECTOR &v );
	VECTOR operator =  ( VECTOR &v );
	VECTOR operator +  ( VECTOR &v );
	VECTOR operator -  ( VECTOR &v );
	VECTOR operator *  ( VECTOR &v );
	VECTOR operator /  ( VECTOR &v );

protected:
	float x, y, z;
};

#endif
////////////////////////// VECTOR.H END ////////////////////////

////////////////////////////////////////////////////////////////

////////////////////////// VECTOR.CPP //////////////////////////

#include <math.h>

#include "vector.h"

VECTOR::VECTOR()
{
	x = 0.0;
	y = 0.0;
	z = 0.0;
}

VECTOR::VECTOR( float _x, float _y, float _z )
{
	x = _x;
	y = _y;
	z = _z;
}

VECTOR::VECTOR( VECTOR &v )
{
  SetVector(v.x, v.y, v.z);
}

VECTOR::~VECTOR()
{

}

float VECTOR::Magnitude()
{
	return (float) sqrt( x*x + y*y + z*z );
}

float VECTOR::Dot( VECTOR &v )
{
	return (x*x + y*y + z*z);
}

VECTOR VECTOR::Cross( VECTOR &v )
{
	return VECTOR(x*v.z-z*v.y, z*v.x-x*v.z, x*v.y-y*v.x);
}

void VECTOR::Normalize()
{
	float	length = 1/Magnitude();

	x *= length;
	y *= length;
	z *= length;	
}

void VECTOR::SetX( float _x )
{
	x = _x;
}

void VECTOR::SetY( float _y )
{
	y = _y;
}

void VECTOR::SetZ( float _z )
{
	z = _z;
}

void VECTOR::SetVector( VECTOR &v )
{
	SetVector(v.x, v.y, v.z);
}

void VECTOR::SetVector( float _x, float _y, float _z)
{
	x = _x;
	y = _y;
	z = _z;
}

float VECTOR::GetX()
{
	return x;
}

float VECTOR::GetY()
{
	return y;
}

float VECTOR::GetZ()
{
	return z;
}

VECTOR VECTOR::GetVector()
{
	return *this;
}


VECTOR VECTOR::operator =  ( VECTOR &v )
{
	SetVector( v );
	return *this;
}

int VECTOR::operator == ( VECTOR &v )
{
	// FIX: Normalize both vectors first!! SLOW!!!!


	return (x == v.x && y == v.y && z == v.z);
}

VECTOR VECTOR::operator +  ( VECTOR &v )
{
	return VECTOR(x+v.x, y+v.y, z+v.z);
}

VECTOR VECTOR::operator -  ( VECTOR &v )
{
	return VECTOR(x-v.x, y-v.y, z-v.z);
}

VECTOR VECTOR::operator *  ( VECTOR &v )
{
	return VECTOR(x*v.x, y*v.y, z*v.z);
}

VECTOR VECTOR::operator /  ( VECTOR &v )
{
	return VECTOR(x/v.x, y/v.y, z/v.z);
}
////////////////////////// VECTOR.CPP END ///////////////////////

        
That''s all of it. If you know how to deal with C++ please help me out here. Thank you! ---------------------------------------------- That's just my 200 bucks' worth!
..-=gLaDiAtOr=-..

Share this post


Link to post
Share on other sites
Guest Anonymous Poster   
Guest Anonymous Poster
Hey Gladiator,

Your vector class looks pretty thorough. There''s a couple things you should changed though. Your == opeator should take an epsilon value so that you can compare values within a certain range. Floats can be trouble to == because they are only equal when they are actuall the same number but 0.1*10^-30 ~= to 0.9*10^31, right? Make a default parameter or something that compares if the values are the same within a certain range.

There is a mistake in your dot method too. You need x*v.x, etc, instead of just squaring the data members.

Looks like a good implementation otherwise. Is GetVector really necessary?

Share this post


Link to post
Share on other sites
Gladiator    127
Wow, someone finally replied to my message!

Thank you very much!

Yes, you''re right about the floating point thingy... I almost forgot I was using floats and not ints (year rriiight )

Oh.. Thanks for spotting the mistake on the Dot Product. I missed it when I went over the whole class implementationg.

GetVector() is not really needed, but I just put it there just for the hell of it

Anyways, I have a question!!

Do you think I should use

VECTOR& VECTOR::Cross(.....)
{
return VECTOR(...);
}

instead of...

VECTOR VECTOR::Cross(.....)
{
return VECTOR(....);
}

which one is better and what''s the different between the two? I''m getting kinda confused now.. I thought I knew this stuff, but hey... haven''t done too much C++ coding so...

----------------------------------------------
That's just my 200 bucks' worth!

..-=gLaDiAtOr=-..

Share this post


Link to post
Share on other sites
Guest Anonymous Poster   
Guest Anonymous Poster
quote:
Original post by Gladiator

Do you think I should use

VECTOR& VECTOR::Cross(.....)
{
return VECTOR(...);
}

instead of...

VECTOR VECTOR::Cross(.....)
{
return VECTOR(....);
}

which one is better and what''s the different between the two? [quote]

hey,

The first one returns a reference to a vector instead of a copy of the vector. This is not what you want because it means the vector youre returning the reference to must continue to exist after the Cross method has finished. You could acheive this by either passing it into the function in the first place or dynamically creating memory for it using the ''new'' operator. The latter is not a good idea but the former is reasonable. I recommend leaving it the way you have it though.

The rest of the class looks good. one thing: are you sure you want to normalise both vectors before you copare for equality? I mean, are two vectors that point in the same direction but have a different magnitude equal?

ro

Share this post


Link to post
Share on other sites
Gladiator    127
Thank you very much everybody! That''s all I wanted to hear. Now I can safely implement what I think would work for me (and most of them fall into this category ). Once again thanks!

----------------------------------------------
That's just my 200 bucks' worth!

..-=gLaDiAtOr=-..

Share this post


Link to post
Share on other sites
JS    122
something else you might wanna do is inline everything. vector ops are used quite a bit and inlining them should cut out a fair ammount of function call overhead.


JS
http://www.thepeel.com/void

Share this post


Link to post
Share on other sites
Serge K    154
Here is my Vector3D class.
(I hope you'll find something useful in it)

            
#pragma once

#include <math.h>

class Vector3D
{
public:

union
{
struct { float x, y, z; };
float c[3];
};

Vector3D () {};
Vector3D (float s) { x=y=z=s; };
Vector3D (const Vector3D& v) { x=v.x; y=v.y; z=v.z; };
Vector3D (float vx, float vy, float vz) { x=vx; y=vy; z=vz; };
Vector3D& operator = (const Vector3D& v) { x=v.x; y=v.y; z=v.z; return *this; };
Vector3D& operator = (float s) { x=y=z=s; return *this; };

Vector3D operator - () const { return Vector3D(-x, -y, -z); };
Vector3D& operator += (const Vector3D&);
Vector3D& operator -= (const Vector3D&);
Vector3D& operator *= (const Vector3D&);
Vector3D& operator *= (float s);
Vector3D& operator /= (float s);

float& operator [] (int n) { return c[n]; };
float operator ! () const { return (float)sqrt(x*x + y*y + z*z); }; // lenght

int operator < (float s) const { return x<s && y<s && z<s; };
int operator > (float s) const { return x>s && y>s && z>s; };

friend Vector3D operator + (const Vector3D&, const Vector3D&);
friend Vector3D operator - (const Vector3D&, const Vector3D&);
friend Vector3D operator * (const Vector3D&, const Vector3D&);
friend Vector3D operator * (float s, const Vector3D&);
friend Vector3D operator * (const Vector3D&, float s);
friend Vector3D operator / (const Vector3D&, float s);
friend Vector3D operator / (const Vector3D&, const Vector3D&);
friend float operator & (const Vector3D&, const Vector3D&); // dot pr.

friend Vector3D operator ^ (const Vector3D&, const Vector3D&); // Cross pr.

void Normalize();
};

//==============================================================================


inline Vector3D operator + (const Vector3D& u, const Vector3D& v)
{
return Vector3D(u.x+v.x, u.y+v.y, u.z+v.z);
}

inline Vector3D operator - (const Vector3D& u, const Vector3D& v)
{
return Vector3D(u.x-v.x, u.y-v.y, u.z-v.z);
}

inline Vector3D operator * (const Vector3D& u, const Vector3D& v)
{
return Vector3D(u.x*v.x, u.y*v.y, u.z*v.z);
}

inline Vector3D operator * (const Vector3D& v, float s)
{
return Vector3D(v.x*s, v.y*s, v.z*s);
}

inline Vector3D operator * (float s, const Vector3D& v)
{
return Vector3D(s*v.x, s*v.y, s*v.z);
}

inline Vector3D operator / (const Vector3D& v, float s)
{
float r = 1.f / s;
return Vector3D(v.x*r, v.y*r, v.z*r);
}

inline Vector3D operator / (const Vector3D& u, const Vector3D& v)
{
return Vector3D(u.x/v.x, u.y/v.y, u.z/v.z);
}

inline float operator & (const Vector3D &u, const Vector3D &v)
{
return u.x*v.x + u.y*v.y + u.z*v.z;
}

inline Vector3D operator ^ (const Vector3D& u, const Vector3D& v)
{
return Vector3D(u.y*v.z - u.z*v.y, u.z*v.x - u.x*v.z, u.x*v.y - u.y*v.x);
}

inline Vector3D& Vector3D::operator += (const Vector3D& v)
{
x += v.x;
y += v.y;
z += v.z;
return *this;
}

inline Vector3D& Vector3D::operator -= (const Vector3D& v)
{
x -= v.x;
y -= v.y;
z -= v.z;
return *this;
}

inline Vector3D& Vector3D::operator *= (float s)
{
x *= s;
y *= s;
z *= s;
return *this;
}

inline Vector3D& Vector3D::operator *= (const Vector3D& v)
{
x *= v.x;
y *= v.y;
z *= v.z;
return *this;
}

inline Vector3D& Vector3D::operator /= (float s)
{
float r = 1.f / s;
x *= r;
y *= r;
z *= r;
return *this;
}

inline void Vector3D::Normalize(void)
{
float r = (float)sqrt(x*x + y*y + z*z);
if(*(int*)&r >= 0x01000000)
{
r = 1.f / r;
x *= r;
y *= r;
z *= r;
}
else x=y=z=0.f;
}



Edited by - Serge K on July 24, 2000 10:03:17 AM

Share this post


Link to post
Share on other sites
Serge K    154
Hey, I just did small bug fixing.
Actually, I made union in this class just before posting the message (before it was just "float x,y,z"), and because I was on my way to sleep (or shut down) I forgot to make a struct from (x,y,z)...

Share this post


Link to post
Share on other sites