More Collision Detection

On this page we're going to cover Rectangle / Line, Rectangle / Rotated Rectangle, and Rotated Rectangle / Line collision detection.

Rectangle Line Collision Detection

Detecting if a line collides with a rectangle is pretty easy. The first thing to look for is if either end point of your line is contained within the rectangle. Basically if you have a range on the x and y axis, you can check to see if the point falls between both the ranges on the axis. If not, you still need to check to see if the line collides with any of the edge lines on the rectangle. If it does, then we have a collision. If not we don't.



The code is actually pretty simple because it reuses a lot of code we've already written.

public static RectangleLine(r: cRectangleCollider, l: cLineCollider): boolean {
   var x_range: cRange = new cRange();
   var y_range: cRange = new cRange();
   x_range.min = r.position.x;
   x_range.max = r.position.x + r.dimension.x;
   y_range.min = r.position.y;
   y_range.max = r.position.y + r.dimension.y;

   if (x_range.min <= l.position.x && l.position.x <= x_range.max &&
   y_range.min <= l.position.y && l.position.y <= y_range.max) {
      return true;
   }
   if (x_range.min <= l.endPosition.x && l.endPosition.x <= x_range.max &&
      y_range.min <= l.endPosition.y && l.endPosition.y <= y_range.max) {
      return true;
   }

   var line_2: cLineCollider = new cLineCollider();
   line_2.position.copy(r.position);
   line_2.endPosition.copy(r.position);
   line_2.endPosition.x += r.dimension.x;

   if (Collision.LineLine(l, line_2)) {
      return true;
   }

   line_2.position.copy(r.position);
   line_2.endPosition.copy(r.position);
   line_2.endPosition.y += r.dimension.y;

   if (Collision.LineLine(l, line_2)) {
      return true;
   }

   line_2 = new cLineCollider();
   line_2.position.copy(r.position);
   line_2.position.add(r.dimension);
   line_2.endPosition.copy(r.position);
   line_2.endPosition.x += r.dimension.x;

   if (Collision.LineLine(l, line_2)) {
      return true;
   }

   line_2.position.copy(r.position);
   line_2.position.add(r.dimension);
   line_2.endPosition.copy(r.position);
   line_2.endPosition.y += r.dimension.y;

   if (Collision.LineLine(l, line_2)) {
      return true;
   }

   return false;
}

 

Rectangle, Rotated Rectangle Collision

It's pretty easy to detect a collision between a Rectangle and a Rotated Rectangle. All you have to do, is change your Rectangle into a Rotated Rectangle with an rotation of 0. Then you can just perform collision detection between two Rotated Rectangles.

public static RectangleRotRectangle(r: cRectangleCollider, rr: cRotRectangleCollider): boolean {
   var rr2: cRotRectangleCollider = new cRotRectangleCollider();
   rr2.position.copy(r.position);
   rr2.position.x += r.dimension.x / 2;
   rr2.position.y += r.dimension.y / 2;
   rr2.halfDimension.copy(r.dimension);
   rr2.halfDimension.multiply(0.5);
   rr2.rotation = 0;
   return Collision.RotRectangleRotRectangle(rr, rr2);
}

 

Rotated Rectangle, Line Collision

Detecting if a rotated rectangle collides with a line is very similar to detecting if a rectangle collides with a line. Basically you look to see if one of the end point falls within the rotated rectangle, if not, you have to do a line line collision detection between all 4 edges of the rotated rectangle and the line. We're going to cheat a bit and reuse our rotated rectangle / circle collider with a circle radius of 0 to detect collisions between our endpoints and the rotated rectangle. This will be a tad less effecient than if we coded specifically to a point, but it shouldn't make that big a difference so I'm going with it.

public static RotRectangleLine(rr: cRotRectangleCollider, l: cLineCollider): boolean {
   var edge: cLineCollider = rr.GetEdge(0);

   if (edge.hitTest(l)) {
      return true;
   }

   edge = rr.GetEdge(1);
   if (edge.hitTest(l)) {
      return true;
   }

   edge = rr.GetEdge(2);
   if (edge.hitTest(l)) {
      return true;
   }

   edge = rr.GetEdge(3);
   if (edge.hitTest(l)) {
      return true;
   }

   var point_test: cCircleCollider = new cCircleCollider();
   point_test.position.copy(l.position);
   point_test.radius = 0;

   return Collision.CircleRotRectangle(point_test, rr);
}

Check out the full collision detection typescript code here. If you want to play around with the different colliders you will need to change the gameLoop code some.

Games

 

More Games

Calculation Solitaire
Colorado Solitaire
Cruel Solitaire
Freecell
Classic Solitaire
Scorpion Solitaire
space invaders
asteroids
sudoku
mathjong
mahjong words
reversi
House Mahjong
Infinity Mahjong
Lines Mahjong
Little Pyramids Mahjong
Multiline Mahjong
Plus Mahjong
Sudoku
Candy Sudoku
Halloween Sudoku
Mermaid Sudoku
Christmas Sudoku
Valentine Sudoku
Coffee Mahjong
Halloween Mahjong
Fruit Mahjong
Mermaid Mahjong
Office Mahjong
Valentine Mahjong
Hour Glass Mathjong
House Mathjong
Classic Mathjong
Infinity Mathjong
Lines Mathjong
Little Pyramids Mathjong
To suggest an improvement, or just say hi, please contact me on twitter :-)

Follow @battagline or  Tweet to @battagline

Thanks,
Rick