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.

Basic Collision Detection

Multiple Type Collision Detection