# Help With Vector Math

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

## Recommended Posts

I'm writing up a camera class today and I'm having troubles. The mouse handles perfectly fine, but motion is not so good looking. I believe it may have to do with my vector math functions. Is there anything wrong here? SimStructs.h
typedef struct SimVector
{
float x, y, z;

void operator= (SimVector v)
{
x = v.x;
y = v.y;
z = v.z;
}

void operator+= (SimVector v)
{
x += v.x;
y += v.y;
z += v.z;
}

void operator-= (SimVector v)
{
x -= v.x;
y -= v.y;
z -= v.z;
}

void operator*= (float a)
{
x *= a;
y *= a;
z *= a;
}

void operator/= (float a)
{
x /= a;
y /= a;
z /= a;
}

SimVector operator+ (SimVector v)
{
SimVector ret;
ret.x = x + v.x;
ret.y = y + v.y;
ret.z = z + v.z;
return ret;
}

SimVector operator- (SimVector v)
{
SimVector ret;
ret.x = x - v.x;
ret.y = y - v.y;
ret.z = z - v.z;
return ret;
}

SimVector operator* (float a)
{
SimVector ret;
ret.x = x * a;
ret.y = y * a;
ret.z = z * a;
}

SimVector operator/ (float a)
{
SimVector ret;
ret.x = x / a;
ret.y = y / a;
ret.z = z / a;
return ret;
}

float operator[] (int a)
{
if(a == 0)
return x;
if(a == 1)
return y;
if(a == 2)
return z;
}
};

namespace SimStructs
{
float GetMagnitude(SimVector v);
void Normalize(SimVector &v);
float DotProduct(SimVector v1, SimVector v2);
SimVector CrossProduct(SimVector v1, SimVector v2);
}


SimStructs.cpp
float SimStructs::GetMagnitude(SimVector v)
{
return sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
}

void SimStructs::Normalize(SimVector &v)
{
float mag = 1.0f / SimStructs::GetMagnitude(v);

v *= mag;
}

float SimStructs::DotProduct(SimVector v1, SimVector v2)
{
return (v1.x * v2.x + v1.y * v2.y + v1.z * v2.z);
}

SimVector SimStructs::CrossProduct(SimVector v1, SimVector v2)
{
SimVector ret;
ret.x = (v1.y * v2.z - v1.z * v2.y);
ret.y = (v1.z * v2.x - v1.x * v2.z);
ret.z = (v1.x * v2.y - v1.y * v2.x);
return ret;
}


Camera code:
void SimCamera::Move(float speed, float timestep)
{
direction = target - position;
SimStructs::Normalize(direction);

position += (direction * speed * timestep);
target += (direction * speed * timestep);
}

void SimCamera::Strafe(float speed, float timestep)
{
direction = target - position;
SimStructs::Normalize(direction);

strafe = SimStructs::CrossProduct(direction, up);
SimStructs::Normalize(strafe);

position += (strafe * speed * timestep);
target += (strafe * speed * timestep);
}


Usage:
    camera.MouseInput();

if(globalInput.IsKeyDown(SDLK_w))
camera.Move(1, frameInterval);
if(globalInput.IsKeyDown(SDLK_s))
camera.Move(-1, frameInterval);
if(globalInput.IsKeyDown(SDLK_a))
camera.Strafe(-1, frameInterval);
if(globalInput.IsKeyDown(SDLK_d))
camera.Strafe(1, frameInterval);



##### Share on other sites
there's a return missing in your operator*

##### Share on other sites
Thanks :). I feel kinda dumb now.

##### Share on other sites
Haha. Don't! Happend at least a 100 times to me before. Strangly enough, MSVC doesn't complain or even warn about it.

##### Share on other sites
Now that you've got your class working, it's time to clean it up and make it watertight. I'll take a Zahlman approach to this (that's right - it's official).

// "typedef" isn't required in C++. You can leave it out happily.struct SimVector{	float x, y, z;		// A constructor will make your life a trillion easier. That's	// right, a trillion. Note we initialise via the initialisation	// list.	SimVector(float x_, float y_, float z_) : x(x_), y(y_), z(z_)	{	}		// You don't need to write an assignment operator ( operator = ),	// because C++ will generate one for your automatically, with a 	// member-wise copy. That's what you've got, so delete it and watch	// it still work.		// You should pass by reference rather by value. this means that	// instead of making a new SimVector, we get given a reference to	// the original one. It is declared "const" so we can't change it.	//	// You should return a (non-const) reference so people can do things	// like:	//    SimVector v = SimVector(3, 4, 5);	//    if ( (v += 4).x == 7 ) go_crazy();	//	SimVector& operator += (const SimVector& v)	{		x += v.x; y += v.y; z += v.z;		return *this;	}		// ...		// it's good practice to make your addition, subtraction, division and 	// multiplication friend operators, because otherwise this:	//   SimVector r = 3.6f * my_simvector;	// won't work, as you have only define an operator * that -takes- a float,	// not a float that takes a SimVector for multiplication.	inline friend SimVector operator + (const SimVector& lhs, const SimVector& rhs)	{		// thanks, constructor!		return SimVector(lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z);	}		// finally, -I- prefer to have my major functions as friend functions. it gives	// them the same scope as your class, and makes for a logical place to put them.	inline friend float Magnitude(const SimVector& v)	{		return sqrt(v.x * v.x + v.y * v.y + v.z * v.z);	}}

Hope that helps.

1. 1
2. 2
3. 3
Rutin
22
4. 4
JoeJ
16
5. 5

• 14
• 29
• 13
• 11
• 11
• ### Forum Statistics

• Total Topics
631774
• Total Posts
3002286
×