Basic AABB collision using projection vector

I've been searching around for the past few days, and researching about Vectors, but still can't quite get my head around the math..

I have two AABB's. On collision I want my method to return a Vector that I can then add to the position Vector to bring my object back into bounds.

Here's my current code:

(The position Vector is the center of the AABB)

public Vector2f collide(Sprite other) { if(!collideBoolean(other)) return null; //no collision float xAxis = Math.abs(this.position.x - other.getX()); //distance between centers on x axis float yAxis = Math.abs(this.position.y - other.getY()); //distance between centers on y axis //these combined values show the minimum distance apart the objects need to be to not collide int cw = this.getHalfWidth() + other.getHalfWidth(); //combined width int ch = this.getHalfHeight() + other.getHalfHeight(); //combined height float ox = Math.abs(xAxis - cw); //overlap on x float oy = Math.abs(yAxis - ch); //overlap on y //direction Vector2f dir = new Vector2f(this.position); dir.sub(other.getPosition()); //subtract other.position from this.position dir.normalise(); return new Vector2f(dir.x * ox, dir.y * oy); }

(self explanatory but here is also the code for collideBoolean(Sprite other) )

public boolean collideBoolean(Sprite other) { //code using halfwidths and centers if(Math.abs(this.position.x - other.getX()) > (this.getHalfWidth() + other.getHalfWidth())) return false; if(Math.abs(this.position.y - other.getY()) > (this.getHalfHeight() + other.getHalfHeight())) return false; return true; }

My current code more or less works.. But the (this) object that is colliding against 'other' gets pushed out AND sides towards the closest corner of 'other'.

I think I'm really close. Surely it'll be something blindingly obvious to a different set of eyes, but I can't quite work it out. Any help would be greatly appreciated!



Adding this into the end of the collide(Sprite other) method works, except isn't as tidy as I'd like. Also when moving into the 'other' body along only one axis it works fine, but if you push into the body at an angle you get inside the shape and it throws you out randomly.

This is probably just because I'm moving too many pixels per step, and I should sweep test my collisions though

(this code looks at the projection vector to see which component is bigger, then 0's out the biggest component. This means that I'm only projecting out of the shape along the shortest path)

.... //direction .... Vector2f projection = new Vector2f(dir.x * (ox+1), dir.y * (oy+1)); if(Math.abs(projection.x) > Math.abs(projection.y)) projection.x = 0; else if(Math.abs(projection.y) > Math.abs(projection.x)) projection.y = 0; return projection; }


With the implementation of Ishtar's answer things were looking good. But I've found if I'm colliding a small object with a wide object, it accurately fixes the collision near the centers, but as you get out near the corners you sink into the shape.

Like this:

_ _______l_l_________ | | |______OK___________| _--________________ | -- | |_____SINKS IN______|


Current collision code:

public class Collision { /** fix collision based on mass */ public static void collide(Sprite s1, Sprite s2) { float xAxis = Math.abs(s1.getX() - s2.getX()); //distance between centers float yAxis = Math.abs(s1.getY() - s2.getY()); //distance between centers int cw = s1.getHalfWidth() + s2.getHalfWidth(); //combined width int ch = s1.getHalfHeight() + s2.getHalfHeight(); //combined height //early exit if(xAxis > cw) return; if(yAxis > ch) return; float ox = Math.abs(xAxis - cw); //overlap on x float oy = Math.abs(yAxis - ch); //overlap on y if(s1.getMass() <= s2.getMass()) fixCollision(s1, s2, ox+1, oy+1); //the +1's make you get out of the shape instead of else //if(s1.getMass() > s2.getMass()) //correcting you onto the edge where you'll be in constant collision fixCollision(s2, s1, ox+1, oy+1); } /** * Fixes the collision * @param s1 : this gets pushed out (should be lower mass) * @param s2 : this stays where it is * @param ox : the overlap along the x axis * @param oy : the overlap along the y axis */ private static void fixCollision(Sprite s1, Sprite s2, float ox, float oy) { //direction Vector2f dir = new Vector2f(s1.getPosition()); dir.sub(s2.getPosition()); dir.normalise(); Vector2f projection = new Vector2f(dir.x * (ox), dir.y * (oy)); if(Math.abs(projection.x) > Math.abs(projection.y)) projection.x = 0; else if(Math.abs(projection.y) > Math.abs(projection.x)) projection.y = 0; if(ox > oy) s1.getPosition().add( new Vector2f(0, dir.y * oy) ); //overlap is bigger on x so project on y else if(ox < oy) s1.getPosition().add( new Vector2f(dir.x * ox, 0)); //overlap is bigger on x so project on x else s1.getPosition().add( new Vector2f(dir.x * ox, dir.y * oy)); //corner to corner }

-------------Problems Reply------------

float ox = Math.abs(xAxis - cw); //overlap on x
float oy = Math.abs(yAxis - ch); //overlap on y

Vector2f dir = new Vector2f(this.position);
dir.sub(other.getPosition()); //subtract other.position from this.position

return new Vector2f(dir.x * ox, dir.y * oy);

The returned translation vector will make both ox (overlap in x) and oy (overlap in y) zero. But that's not what you need. If ox is 0, there is no overlap in the x direction, thus no overlap at all. If oy is 0, idem. So, you need to find the vector that will make only ox or oy zero.

if (ox > oy )
return new Vector3f(0,dir.y*oy);//top-bottom collision
else if (ox < oy )
return new Vector3f(dir.x*ox,0);//left-right collision
else //if(ox == oy)
return new Vector3f(dir.x*ox,dir.y*oy); //corner-corner collision,
//unlikely with float's.

To solve the "sliding problem" do this: (C# XNA code however)

Vector2 direction = (this.Center - other.Center);

direction.X = (int)Math.Round(direction.X);
direction.Y = (int)Math.Round(direction.Y);

First you get a unit vector with the direction you should exit from. But using that as it is, will be unreliable when you're near the corners. the rounding makes the strongest value to be 1, and the other 0.

Explanation why the rounding is necessary:

For example say the two objects centers on the Y axis are equal and we are exiting left. The direction unit vector is (-1, 0) giving us a reliable number to multiply the overlap with. but as you get closer and closer to the corner of the shape the number turns more into (-0.88, *) that non-whole number, when multiplied leads to losing pixels and you sink into the shape.

I hope the explanation made since, not too great at these things.

By the way, I am the OP ^_^ ..thanks for the help everyone

Category:java Views:0 Time:2011-12-15

Related post

  • Computing AABB collision 2011-12-07

    I'm making a game in OpenGL. The game consists on a plane flying free on a 3D world, wich has to go through some especific areas, like if it was going through windows. Right now, I'm trying to compute the collision of the plane with that mentioned "w

  • How do I refine and build on a basic scaffolding Dynamic Data project? 2009-09-12

    Once you create a basic, generated dynamic data project with scaffolding, there are so many more things you can do to customise and improve the project, evolving toward a finely crafted custom application that benefits from reliable infrastructure. Y

  • Basic 2d collision detection 2010-10-03

    Where can I go to read more about basic 2d collision detection for games or just applications that have some interactivity? Edit: How about javascript for Canvas games? --------------Solutions-------------

  • 2D Platformer AABB collision problems 2011-07-04

    I have a problem with AABB collision resolution. I resolve AABB intersection by resolving the X axis first, then the Y axis. This is done to prevent this bug: The current method works fine when an object moves into the player and the player has to be

  • Basic 3D collision detection issue 2013-06-24

    I am trying to implement basic collision detection for a voxel-based 3D Java game I am working on. I am trying to implement the algorithm from this site:, but I can't seem to

  • Setting different c-basic-offs for different projects 2009-12-01

    I usually use 4 white spaces to indent C programs, but in order to keep in consistent with some open source projects, I have to change to 2-white-space indenting sometimes. Currently my indenting style is assigned in my .emacs file with (setq c-basic

  • Zend Framework: Looking For a Basic "stub" for a project 2010-08-01

    We've got a lot of ZF experience. Current project needs a basic user "control panel" and a staff "control panel" backend. We could roll this from scratch, but it seems like a waste of time. What we'd like: User Management (registration, forgot passwo

  • Pseudocode for Swept AABB Collision 2010-08-02

    I think swept means determining if objects will collide at some point, not just whether they are currently colliding, but if I'm wrong tell me. I have objects with bounded boxes that are aligned on an axis. The boxes of objects can be different sizes

  • Help needed while setting up basic multiplatform cmake-enabled project 2010-11-03

    tl;dr the questions are at the bottom. I am a developer trying something new - my last poison is c++. As I am spending half of my time on my linux laptop and the other half on Win XP PC, I tried to find a way to create basic, barebone project, using

  • Platform jumping problems with AABB collisions 2011-06-20

    When my AABB physics engine resolves an intersection, it does so by finding the axis where the penetration is smaller, then "push out" the entity on that axis. Considering the "jumping moving left" example: If velocityX is bigger than velocityY, AABB

  • Efficient way to project vectors onto unit box 2011-07-05

    I am reimplementing a Matlab function in C for performance reasons. Now, I am looking for the most efficient way to compute the projection of a vector onto the unit-box. In C terms, I want to compute double i = somevalue; i = (i > 1.) ? 1. : i; i

  • Simple 2D collision detection with vectors 2012-04-13

    I am trying to create collision algorithm and implement him in my Win32 2D GUI app. The task is that i got one vector that determinate mid-bottom of .bmp image and four more vectors in position of rhombus. I wanted to make it work so algorithm know i

  • How to create a basic User Permissions per project association? 2009-06-22

    I have public and private projects in my app. I want to assign user to private projects for viewing and posting. What's the right way to do this? I tried with a permissionlist model and associated it to a project. but i got so confused that i couldn'

  • Basic question about polymorphism. Vector of base class, want the derived class. How? 2009-11-08

    I think I messed up somehow in my design because I want to keep a vector of various object types. These types all share a common base class. Example: Class Buick: AmericanCar { } Class Ford: AmericanCar { } then I did: vector<AmericanCar*> cars

  • Memory counter - Collision Detection Project 2011-05-08

    I thought I would ask the experts - see if you can help me :o) My son has written C++ code for Collision Detection using Brute Force and Octree algorithms. He has used Debug etc - and to collect stats on mem usage he has used windows & task manag

  • Help understanding code snippet (AABB collision) 2011-08-29

    I've snatched this piece of tile collision code from another game, but in the spirit of understanding and not just stealing, I'd like to get some help understanding what exactly it does. Specifically what the function of x1, y1, x2, y2 are and why it

  • Looking for Basic Training for Microsoft Project 2007 2014-03-30

    Anyone know where in Microsoft land I can find 101 training for Microsoft Project 2007? --------------Solutions------------- Where are you looking for training? There are some on-line videos about Project that may get you started in the correct direc

  • Calculating AABB (axis aligned bounding box) collision 2010-11-16

    I'm supposed to check for AABB collision between two pyramids. I looked up AABB, simple enough to check. I was given the vertices for both pyramids, as well as 4 world positions. I am supposed to calculate the AABB collision box, which I've done, and

  • How to explore set of nonnegative vectors consistent with a set of projections? 2011-11-09

    I am trying to infer an unknown vector x in a high-dimensional space (thousands of dimensions), and have good measurements of its projections onto a few (15) directions -- i.e. if the columns of v[i,j] form a basis for the space, I know v[,j]*x = v[1

Copyright (C), All Rights Reserved.

processed in 0.083 (s). 11 q(s)