• 14
• 12
• 9
• 10
• 13

# SAT - Minimum translation vector

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

## Recommended Posts

I have this situation where obj2box collides with the obj1box one on its top side. (both axis alligned)

Check overlap over obj1 axes
[0]Overlap :229.68519862516825 axis:Vector3D(-1, 0, 0)
[1]Overlap :-2.221934558031876 axis:Vector3D(0, -1, 0)
[2]Overlap :-229.68519862516825 axis:Vector3D(1, 0, 0)
[3]Overlap :2.221934558031876 axis:Vector3D(0, 1, 0)

Check overlap over obj2 axes
[0]Overlap :229.68519862516825 axis:Vector3D(-1, 0, 0)
[1]Overlap :-2.221934558031876 axis:Vector3D(0, -1, 0)
[2]Overlap :-229.68519862516825 axis:Vector3D(1, 0, 0)
[3]Overlap :2.221934558031876 axis:Vector3D(0, 1, 0)

If I select the smallest one, the -229.68519862516825 is selected...but it is wrong since the vector should push obj2 up.

this is my overlap check function(AS3):

public function testOverlap(prj1:SAT_projection,prj2:SAT_projection):Number
{
var d0:Number = prj1.max_ - prj2.min_;
var d1:Number = prj2.max_ - prj1.min_;
if(d0 < 0 || d1 < 0) return 0;
if (d0 < d1){return -d0}else{return d1}
}

this is my project function(AS3):

public function Project ax:SAT_axis):SAT_projection
{ var p:Number;
var prj:SAT_projection=new SAT_projection()
for (var i=0; i<sides; i++)
{
p = ax.dotProduct(vertexArr);
if (p < prj.min_)
{
prj.min_ = p;
}
if (p > prj.max_)
{
prj.max_ = p;
}
}
return prj
}

1)Something wrong with those scalars or I have to abs them?
2)The scalars of the second check are the same as the first, is it OK?
3)How to calculate the Mtv direction ? As you can see If I get ABS value, I have the two scalars of the same size that point to opposite direction..

After that I want the obj2 bounce over obj1:
How to use MTV for that?Maybe I have to apply MTV first and the bounce?

public function doBounce(planeVector:SAT_axis)
{

var dir:Vector3D=new Vector3D(this.vx,this.vy)
var dp:Number=dir.dotProduct(planeVector)
var mag:Number=dir.length*planeVector.length
var sine:Number = dp/mag + Math.PI/2;
var cosine:Number = dp/mag;

this.vx = planeVector.x * sine - planeVector.y * cosine *2;
this.vy = planeVector.x * cosine + planeVector.y * sine *2;
}

##### Share on other sites
1) You have to abs them to determine which one you should move along(it's shortest vector not lowest number), but you'll still want to note the sign when you do the actual moving.

2) There are are only really 2 axes of interest in an AABB check, so there will really only be two meaningful results. It looks like that's what you've got, so it should work, but you could make it more efficient by one checking twice instead of 8 times. Well, unless you're writing a general SAT and just happen to be using AABBs for testing, then the optimizations are less trivial.

3)The sign that you need will be based on which object you're applying the movement to positively and which one negatively. It's arbitrary which of the directions you want, but it'll be consistent. Try them both and stick with whichever works.

		public function Project(ax:SAT_axis):SAT_projection		{	var p:Number;			var prj:SAT_projection=new SAT_projection()			for (var i=0; i<sides; i++)				{				p = Math.abs(ax.dotProduct(vertexArr));				if (p < prj.min_)					{					prj.min_ = p;				}				if (p > prj.max_)				{					prj.max_ = p;				}			}			return prj		}public function testOverlap(prj1:SAT_projection,prj2:SAT_projection):Number		{	        var d0:Number = prj1.max_ - prj2.min_;		var d1:Number = prj2.max_ - prj1.min_;		if(d0 < 0 || d1 < 0) return 0;		if (d0 < d1){return -d0}else{return d1}		}