• Advertisement
Sign in to follow this  

Scaling a bounding box

This topic is 4321 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

Hey guys. I'm using a bounding structure for a bounding box that's defined by a min and max point in 3D space. I have a function to scale the box, which gets called when the associated object is scaled, that looks like this:
void ABounds::setScale(const D3DXVECTOR3& s)
{
        box.min.x *= s.x;
	box.min.y *= s.y;
	box.min.z *= s.z;

	box.max.x *= s.x;
	box.max.y *= s.y;
	box.max.z *= s.z;
}
This doesn't work. It does make the bounding box bigger, but it also translates it. I'm not sure why. I think its because its not scaling relative to the center of the object. I tried to fix it by calculating a translation vector for the min and max points. I got the vector from the center of the object to the min/max, scaled that vector by the scale factor, then translated the min/max along that vector. That didn't seem to work correclty either. This is what that code looked like:
void ABounds::setScale(const D3DXVECTOR3& s)
{
        // to scale the bounding box min and max points *relative to the center*
	// we need to get a translation vector from the center to the current 
	// min/max, scale that translation vector by the scale factor, then translate 
	// the min/max along their respective translation vectors

	// get vector from center of bounding box to the min and max pointx
	D3DXVECTOR3 minTranslation = box.min - getPosition();
	D3DXVECTOR3 maxTranslation = box.max - getPosition();

	// scale the translation vectors by the scaling factor
	minTranslation.x *= (s.x / 2.0f);
	minTranslation.y *= (s.y / 2.0f);
	minTranslation.z *= (s.z / 2.0f);

	maxTranslation.x *= (s.x / 2.0f);
	maxTranslation.y *= (s.y / 2.0f);
	maxTranslation.z *= (s.z / 2.0f);

        // move the min and max points along the translation vectors
	box.min += minTranslation;
	box.max += maxTranslation;
}
Any help would be greatly appreciated. =)

Share this post


Link to post
Share on other sites
Advertisement
Quote:


void ABounds::setScale(const D3DXVECTOR3& s)
{
// to scale the bounding box min and max points *relative to the center*
// we need to get a translation vector from the center to the current
// min/max, scale that translation vector by the scale factor, then translate
// the min/max along their respective translation vectors

// get vector from center of bounding box to the min and max pointx
D3DXVECTOR3 minTranslation = box.min - getPosition();
D3DXVECTOR3 maxTranslation = box.max - getPosition();

// scale the translation vectors by the scaling factor
minTranslation.x *= (s.x / 2.0f);
minTranslation.y *= (s.y / 2.0f);
minTranslation.z *= (s.z / 2.0f);

maxTranslation.x *= (s.x / 2.0f);
maxTranslation.y *= (s.y / 2.0f);
maxTranslation.z *= (s.z / 2.0f);

// move the min and max points along the translation vectors
box.min += minTranslation;
box.max += maxTranslation;
}


Any help would be greatly appreciated. =)


Does getPosition return center of the box? If not, then the vector you need is "c = (min + max) / 2"

Then multiply by s (not s/2).


c = (box.min + box.max) / 2

minTranslation = box.min - c;
maxTranslation = box.max - c;

minTranslation *= s;
maxTranslation *= s;

box.min = minTranslation + c;
box.max = maxTranslation + c;

Share this post


Link to post
Share on other sites
You will not scale things if you multiply the coordinates of the point. If you do that, you will move it.


. min

. max
----|--------|----> x
3 5


Multiplying it by a number k will do this:


. min

. max
--------|----------------|----> x
3*k 5*k


It will increase the size of the box (before, diff was 2, now it is 2*k, so properly scaled), but will also move it.

You need to scale the vectors only.

Share this post


Link to post
Share on other sites
Quote:
Original post by Antheus

Does getPosition return center of the box? If not, then the vector you need is "c = (min + max) / 2"

Then multiply by s (not s/2).


c = (box.min + box.max) / 2

minTranslation = box.min - c;
maxTranslation = box.max - c;

minTranslation *= s;
maxTranslation *= s;

box.min = minTranslation + c;
box.max = maxTranslation + c;



Yes sorry I forgot to say... getPosition() returns the center of the bounding box. I tried your method, even calculating the center instead of calling getPosition() just to be sure, but it doesn't seem to be working.

I have the object scaling on input (up/down keys) and the actual model is scaling correctly so I'm fairly certain that valid values are being passed along. And the bounding box starts out correct, it just scales up orders of magnitude faster than the model (using your method).

Using the first method (just scaling the vector values) it scales correctly, but also translates. Which is due to what Kalazart said.

Share this post


Link to post
Share on other sites
Here's another variation of the above suggestions that you might try:
vector3 center = (max + min) * 0.5f;
vector3 extents = (max - min) * 0.5f;
extents *= scale;
min = center - extents;
max = center + extents;
That should scale the AABB without changing its position.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement