#### Archived

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

# My vector class isn't working! Stack overflow!

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

## Recommended Posts

Ok, here is how thinks are right now... I'm writing this game, a cover on Pong, SuperPong, and it MUST be ready on wednesday, and my program is almost ready. But one thing remains: the collision detection! I'm using a plane class and a vector class from the book "OpenGL Game Developing". And it should work, because it works in a hockey demo demonstrated in the same book. So, the problem is this: One of my balls(no not those balls) in SuperPong is not bouncing correct. I have set one of my gamefield walls at x=50(it's a vertical one). And the ball doesn't even bounce back there, it just continues in the same direction. The mystic part is that it eventually bounces back, but the plane seems to be at x=80 or something. And then on the way back from the mystic wall the program crashes when the ball reaches origo. The debugger says it's a Stack Overflow error, and complains about the vector class. I know it is a hard issue, but please guys I need your help with this one! Really! Here is the vector class:
#ifndef __VECTOR_H
#define __VECTOR_H

#include <math.h>

/*
VECTOR.H

scalar_t
CVector class

OpenGL Game Programming
by Kevin Hawkins and Dave Astle

Some operators of the CVector class based on
operators of the CVector class by Bas Kuenen.
*/

typedef float scalar_t;

class CVector
{
public:
scalar_t x;
scalar_t y;
scalar_t z;    // x,y,z coordinates

public:
CVector(scalar_t a = 0, scalar_t b = 0, scalar_t c = 0) : x(a), y(b), z(c) {}
CVector(const CVector &vec) : x(vec.x), y(vec.y), z(vec.z) {}

// vector assignment

const CVector &operator=(const CVector &vec)
{
x = vec.x;
y = vec.y;
z = vec.z;

return *this;
}

// vecector equality

const bool operator==(const CVector &vec) const
{
return ((x == vec.x) && (y == vec.y) && (z == vec.z));
}

// vecector inequality

const bool operator!=(const CVector &vec) const
{
return !(*this == vec);
}

const CVector operator+(const CVector &vec) const
{
return CVector(x + vec.x, y + vec.y, z + vec.z);
}

// vector add (opposite of negation)

const CVector operator+() const
{
return CVector(*this);
}

// vector increment

const CVector& operator+=(const CVector& vec)
{    x += vec.x;
y += vec.y;
z += vec.z;
return *this;
}

// vector subtraction

const CVector operator-(const CVector& vec) const
{
return CVector(x - vec.x, y - vec.y, z - vec.z);
}

// vector negation

const CVector operator-() const
{
return CVector(-x, -y, -z);
}

// vector decrement

const CVector &operator-=(const CVector& vec)
{
x -= vec.x;
y -= vec.y;
z -= vec.z;

return *this;
}

// scalar self-multiply

const CVector &operator*=(const scalar_t &s)
{
x *= s;
y *= s;
z *= s;

return *this;
}

// scalar self-divecide

const CVector &operator/=(const scalar_t &s)
{
const float recip = 1/s; // for speed, one divecision

x *= recip;
y *= recip;
z *= recip;

return *this;
}

// post multiply by scalar

const CVector operator*(const scalar_t &s) const
{
return CVector(x*s, y*s, z*s);
}

// pre multiply by scalar

friend inline const CVector operator*(const scalar_t &s, const CVector &vec)
{
return vec*s;
}

/*   friend inline const CVector operator*(const CVector &vec, const scalar_t &s)
{
return CVector(vec.x*s, vec.y*s, vec.z*s);
}

*/   // divecide by scalar

const CVector operator/(scalar_t s) const
{
s = 1/s;

return CVector(s*x, s*y, s*z);
}

// cross product

const CVector CrossProduct(const CVector &vec) const
{
return CVector(y*vec.z - z*vec.y, z*vec.x - x*vec.z, x*vec.y - y*vec.x);
}

// cross product

const CVector operator^(const CVector &vec) const
{
return CVector(y*vec.z - z*vec.y, z*vec.x - x*vec.z, x*vec.y - y*vec.x);
}

// dot product

const scalar_t DotProduct(const CVector &vec) const
{
return x*vec.x + y*vec.x + z*vec.z;
}

// dot product

const scalar_t operator%(const CVector &vec) const
{
return x*vec.x + y*vec.x + z*vec.z;
}

// length of vector

const scalar_t Length() const
{
return (scalar_t)sqrt((double)(x*x + y*y + z*z));
}

// return the unit vector

const CVector UnitVector() const
{
return (*this) / Length();
}

// normalize this vector

void Normalize()
{
(*this) /= Length();
}

const double operator!() const
{
return sqrtf((x*x) + (y*y)+ (z*z));
}

// return vector with specified length

const CVector operator | (const double length) const
{
return (*this) * (length / !(*this));
}

// set length of vector equal to length

const CVector& operator |= (const float length)
{
return *this = *this | length;
}

// return angle between two vectors

const float inline Angle(const CVector& normal) const
{
return acosf(*this % normal);
}

// reflect this vector off surface with normal vector

const CVector inline Reflection(const CVector& normal) const
{
const CVector vec(*this | 1);     // normalize this vector

return (vec - normal * 2.0 * (vec % normal)) * !*this;
}

};

#endif

And here is the collision code...
void CMainBall::Move(float deltaTime, CField *field)
{
if (deltaTime <= 0) return;

double fastestTime = deltaTime;
CPlane *planeCollision = NULL;
for (int idx = 0; idx < 4; idx++)
{
CPlane *plane = &field->fieldWalls[idx];
double collisionTime;
double aa, b, c;

// dot product

aa = plane->N % (a * 0.5);
b = plane->N % v;
c = plane->N % pos + plane->D - Radius;

if (aa == 0)         // first degree

{
if (b != 0 && c != 0)    // must have velocity

{
collisionTime = -c/b;
if (collisionTime >= 0 && collisionTime < fastestTime)
{
fastestTime = collisionTime;
planeCollision = plane;
}
}
}
else
{    //   Second degree equation

double D = b*b - 4*aa*c;       //   Calc determinant

if (D >= 0)
{
//   Calc solution (cannot be negative, so the negative solution is dropped)

collisionTime = (- b - sqrt(D)) / (2*aa);
if (collisionTime >= 0 && collisionTime < fastestTime)
{
fastestTime = collisionTime;
planeCollision = plane;
}
}
}
}

// apply friction (coefficient = 0.2)

if (v.Length() > 0.0)
a = -v * 0.2;

//   Move to collision point & set velocity there

pos += v * fastestTime + a * (fastestTime*fastestTime*0.5);
v += a * fastestTime;

// only allow velocity to max out at 800

if (v.Length() > 800.0)
v |= 800.0;       // set velocity equal to 800

if (planeCollision)
{    //   Bounce - invert height direction

v = v.Reflection(planeCollision->N);
}

//   Recursive call

Move(deltaTime - fastestTime, field);

}

[edited by - AfroMogli on March 27, 2004 4:35:10 AM]

##### Share on other sites
Have you tried increasing the stack size? I know in VC++ you can use the /STACK option to set the stack size to a larger value.

----------------------------------------
"Before criticizing someone, walk a mile in their shoes.
Then, when you do criticize them, you will be a mile away and have their shoes." -- Deep Thoughts
"If you have any trouble sounding condescending, find a Unix user to show you how it''s done." - Scott Adams
FaceHat Software -- Wear the hat.

##### Share on other sites
Your Move() function is a recursive function with no terminating condition. You''re just calling the function infinitely. This is a bad thing.

##### Share on other sites
One thing I did notice is that your equality operation won''t work. You''re using == on floats. Test the difference against eplison instead.

You have to remember that you''re unique, just like everybody else.

##### Share on other sites
Ok, I fixed the Stack Overflow-error by removing the the iterating part.
Now I have another BIG problem. The ball, when it has bounced of a wall(this is happening with all walls) it "gets stuck" when it reaches the opppsoite axis.
Ok, I know sounds crazy but it''s in that way. Here is a step by step explanation of the problem:

1. The ball:s velocity is set to (10, 0, 0).
2. The ball is heading in the positive X direction as it should do.
3. It reaches the vertical wall which is at x=50.
4. It bounces of the wall, and is now heading in the negative X direction.
5. When it reaches the border between the positive x-axis and the negative x-axis it just stops!

My guess is that it is something wrong at the Move(). But I cannot fix the problem because of my limited collision and physics knowledge.

##### Share on other sites
Pseudo code:

...
ball.pos=(0,0)
ball.vel=(2,4)

while !exit
t=time()
dt=time()-t

ball.pos.x+=dt*ball.vel.x
ball.pos.y+=dt*ball.vel.y

resolveCollision()

endwhile
...

func resolveCollision()

//right
dx=50-r-ball.pos.x
if dx<0 //out of field
ball.pos.x+=2*dx
ball.vel.x=-ball.vel.x
endif
//left
dx=-50+r-ball.pos.x
if dx>0 //out of field
ball.pos.x+=2*dx
ball.vel.x=-ball.vel.x
endif
//top
dy=50-r-ball.pos.y
if dy<0 //out of field
ball.pos.y+=2*dy
ball.vel.y=-ball.vel.y
endif
//bottom
dy=-50+r-ball.pos.y
if dy>0 //out of field
ball.pos.y+=2*dy
ball.vel.y=-ball.vel.y
endif

endfunc

I think this works well, did not try it. If the ball has not got very very much velocity and dt is small enough, it should work well.

1. 1
Rutin
40
2. 2
3. 3
4. 4
5. 5

• 9
• 24
• 20
• 14
• 14
• ### Forum Statistics

• Total Topics
633384
• Total Posts
3011592
• ### Who's Online (See full list)

There are no registered users currently online

×