Jump to content
  • Advertisement
Sign in to follow this  
lack the hack

what parameters for bounding sphere?

This topic is 4811 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 everyone i've been having some misunderstandings about bounding sphere parameters in the functions. this is the code i'm using (from OpenGL Game Programming, Dave Astle and Kevin Hawkins)(i added the CVector class because it's used in FindBoundingSphereRadius):
typedef float scalar_t;
class CVector
{
public:
	scalar_t x;
	scalar_t y;
	scalar_t z;
public:
	CVector(scalar_t a = 0,scalar_t b = 0, scalar_t c = 0)
	{
		x = a;
		y = b;
		z = c;
	}
	
	const bool operator==(const CVector &vec) const
	{
		return ((x == vec.x) && (y == vec.y) && (z == vec.z));
	}
	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);
	}
	const CVector operator+() const
	{
		return CVector(*this);
	}
	const CVector& operator+=(const CVector& vec)
	{
		x += vec.x;
		y += vec.y;
		z += vec.z;

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

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

		return *this;
	}
	const CVector &operator/=(const scalar_t &s)
	{
		const float recip = 1/s;

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

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

		return CVector(s*x,y*s,s*z);
	}
	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);
	}
	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);
	}
	const scalar_t DotProduct(const CVector &vec) const
	{
		return x*vec.x + y*vec.x + z*vec.z;
	}
	const scalar_t operator%(const CVector &vec) const
	{
		return x*vec.x + y*vec.x + z*vec.z;
	}
	const scalar_t Length() const
	{
		return (scalar_t)sqrt((double)(x*x + y*y + z*z));
	}
	const CVector UnitVector() const
	{
		return (*this) / Length();
	}
	void Normalize()
	{
		(*this) /= Length();
	}
	const scalar_t operator!() const
	{
		return sqrtf(x*x + y*y + z*z);
	}
	const CVector operator | (const scalar_t length) const
	{
		return *this * (length / !(*this));
	}
	const CVector& operator |= (const float length)
	{
		return *this = *this | length;
	}
	const float inline Angle(const CVector& normal) const
	{
		return acosf(*this % normal);
	}
	const CVector inline Reflection(const CVector& normal) const
	{
		const CVector vec(*this | 1);
		return (vec - normal * 2.0 * (vec % normal )) * !*this;
	}
};
float FindBoundingSphereRadius(CVector *points, CVector center, int numPoints)
{
	float currDist = 0.0f;
	float maxDist  = 0.0f;
	if (points == NULL)
		return -1.0;
	for (int idx = 0; idx < numPoints; idx++)
	{
		currDist = ((points[idx].x - center.x)*(points[idx].x - center.x)) + ((points[idx].y - center.y)*(points[idx].y - center.y))+((points[idx].z - center.z)*(points[idx].z - center.z));
		if (currDist > maxDist)
			maxDist = currDist;
	}
	return sqrt(maxDist);
}

now in the FindBoundingSphereRadius parameters, what should *points, center, and numPoints be? i'm guessing numPoints should just be the number of points, so if you had a quad it would be 4. but what is *points and center? and where should i call this function? thanks a bunch:-)

Share this post


Link to post
Share on other sites
Advertisement
well the *points would be your vertices, and numPoints is the number of vertices that you have in your object. center would simply be the center that your sphere is calculated from.

someone correct me if im wrong.
//fredrik

Share this post


Link to post
Share on other sites
Quote:
Original post by lack the hack
i'm sorry but i don't know what numbers or variables the parameters should be. could you give me some sample code to look at?

thanks a bunch


frecco2k is correct, but I'll explain some more.

float FindBoundingSphereRadius(CVector *points, CVector center, int numPoints)

Let's say you have a simple box, each side has length two. The definition of it would look like this (taken from NeHe)

glBegin(GL_QUADS);
// Front Face
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // Bottom Left Of The Texture and Quad
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); // Bottom Right Of The Texture and Quad
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); // Top Right Of The Texture and Quad
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // Top Left Of The Texture and Quad
// Back Face
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); // Bottom Right Of The Texture and Quad
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); // Top Right Of The Texture and Quad
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); // Top Left Of The Texture and Quad
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); // Bottom Left Of The Texture and Quad
// Top Face
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); // Top Left Of The Texture and Quad
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // Bottom Left Of The Texture and Quad
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f); // Bottom Right Of The Texture and Quad
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); // Top Right Of The Texture and Quad
// Bottom Face
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f); // Top Right Of The Texture and Quad
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f); // Top Left Of The Texture and Quad
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); // Bottom Left Of The Texture and Quad
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // Bottom Right Of The Texture and Quad
// Right face
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); // Bottom Right Of The Texture and Quad
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); // Top Right Of The Texture and Quad
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); // Top Left Of The Texture and Quad
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); // Bottom Left Of The Texture and Quad
// Left Face
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); // Bottom Left Of The Texture and Quad
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // Bottom Right Of The Texture and Quad
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // Top Right Of The Texture and Quad
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); // Top Left Of The Texture and Quad
glEnd();



Ignore the glTexCoord2f stuff, but do you see each of the glVertex3f? Well those are your verticies of the box. You would have a total of 4 verticies per side * 6 sides = 24, even though there is repeation. So to use that function with that object, you'd call:


CVector center = CVector( 0,0,0 );
CVector points[] = { CVector(-1.0f, -1.0f, 1.0f), ..., CVector(-1.0f, 1.0f, -1.0f) };
// Basically you put all 24 verticies into an array of CVectors

float radius = FindBoundingSphereRadius( points, center, 24 );


That should return roughly 1 since the radius for a box with length 2 is 1. The center is where the object is centered at.

So for anything else, all you need to is first make an array of CVectors that contain the verticies of your object, then the point where your object is centered at, then finally the total number of verticies you have in that object (total array elements).

Share this post


Link to post
Share on other sites
ok if you have a single quad, this would give you a sphere radius of: 1.414214f

CVector *points;
void setup( void ) {
points = new CVector[ 4 ];
points[ 0 ] = CVector(-1.0f, 1.0f, 0.0f);
points[ 1 ] = CVector( 1.0f, 1.0f, 0.0f);
points[ 2 ] = CVector( 1.0f,-1.0f, 0.0f);
points[ 3 ] = CVector(-1.0f,-1.0f, 0.0f);
}


void someinitfunction( void ) {
setup();
float radius = FindBoundingSphereRadius( points, CVector( 0.0f, 0.0f, 0.0f ), 4 ) );
}






so the center is the center of the quad ex( 0.0, 0.0, 0.0 ), numpoints is the number of your vertices wich in this case would be 4.

hope that helps.

*edit o sorry Drew_Benton you beat me to it.

Share this post


Link to post
Share on other sites
thanks a bunch you guys, the code finally works now. i just have one more problem:-(. when i do the collision detection by using this code:
 if(maxDist + maxDist2 <= maxDist2 + maxDist)
{
glTranslatef(0.0f,0.0f,0.0f);
bullet(0.0f,0.0f,0.0f);
}


it doesn't translate my bullet back to it's original position. what's a matter with it? i made 2 bounding sphere functions, so i have 2 currdist and maxdist variables. any clue as to why it isn't working?

thanks a bunch again:)

Share this post


Link to post
Share on other sites
Hmm, that code is not looking as it should:

First:
if(maxDist + maxDist2 <= maxDist2 + maxDist) will always evaluate to true, since maxDist + maxDist2 == maxDist2 + maxDist. So you will need to check your math there again and fix what you are trying to do.

Second:
glTranslatef(0.0f,0.0f,0.0f); will not move your object at all. It's telling it to simply traslate 0 units in all directions. If you want your object to be at the orgin, set it's internal position to (0,0,0) or just do something like this:

glPushMatrix();
glLoadIdentity();
bullet(0.0f,0.0f,0.0f);
glPopMatrix();


That will put the object at the orgin. However, if you want to put the object back into it's old position, you will need to simply store those values, then use the math to go back:

// Save old values
float OldX;
float OldY;
float OldZ;
...
// Move object and do detection
...
// Store new values
float NewX;
float NewY;
float NewZ;

// Now go back if the collision is true
glTranslatef( -NewX + OldX, -NewY + OldY, -NewZ + OldZ;



Share this post


Link to post
Share on other sites
sorry to bring back an old topic, but this is the last time i will annoy you guys. sorry about this:(

i can't figure out how to calculate the distance between the two objects. i know if the distance between the 2 objects is <= the distance between them, they are colliding. i just can't figure out how to put the distance part of this equation into the code. could anyone give me some sample code or something? i'm guessing you would have two variables adding or subtracting from vertexes to check the distance. i just can't figure it out on my own though. thanks a bunch you guys, you've been a great help

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!