Line Collisions in Typescript for HTML5 Games

The basics of line collision detection is to look at each line and see if the two points that make up the other line are on the same side or the opposite side of the line. In the diagram below, the lines on the left intersect. Look at the blue line, you can see that P1 and P2 are on opposite sides of the blue line, so there is an intersection. In the example on the right, P1 and P2 are both on the same side of the blue line, so there is no intersection.

 

Dot Product

To understand how we can tell if both points are on the same side of the line, we need to understand how the dot product works. The dot product of a unit circle is the cosine of the angle between two vectors. The diagram below shows the values you get for the angle between two unit vectors.

 

Using Dot products and vector normals

So, the fist thing we need to do, is get a vector that represents the direction the first line is going. We then need to rotate that vector by 90 degrees. We then compare that vector with the two vectors between the first point in our line and the two points on the other line. If the angle between two lines is less than 90 degrees, the dot product value is going to be positive. If it is greater than 90 degrees the dot product is negative, so we can tell if those points are on the same or opposite sides of our line, by checking to see if the sign of one of the dot products is positive and the other is negative.

 

The Line class in TypeScript

So far I've shown you some diagrams, but I haven't shown you any code yet. In step 1 we are going to need to define our line class. A line is defined by two points, a starting point and an ending point. All our colliders must have a position attribute, so we'll keep that as our starting point. Here is what the line collider class looks like.

class cLineCollider implements iCollider {
   public position: cVector = new cVector();
   public endPosition: cVector = new cVector(1, 1);
   public colliderType: COLLIDER = COLLIDER.LINE;
}

 

Line Line Collision Code

We also need to add another static function to our Collision class. This function will actually do the work of the collision detection.

public static LineLine(a: cLineCollider, b: cLineCollider): boolean {
 var directionA: cVector = new cVector(a.endPosition.x, a.endPosition.y);
 var directionB: cVector = new cVector(b.endPosition.x, b.endPosition.y);

 directionA.subtract(a.position);

 if (directionA.x == 0 && directionA.y == 0) {
  // THIS IS NOT A LINE, THIS IS A POINT. DON'T BOTHER CHECKING
  return false;
 }

 var distance_point_1: cVector = a.position.duplicate();
 var distance_point_2: cVector = a.position.duplicate();

 distance_point_1.subtract(b.position);
 distance_point_2.subtract(b.endPosition);

 var rotated_direction: cVector = directionA.duplicate();
 rotated_direction.rotate90();

 if (rotated_direction.dot(distance_point_1) * rotated_direction.dot(distance_point_2) > 0) {
  return false;
 }

 directionB.subtract(b.position);

 if (directionA.x == 0 && directionA.y == 0) {
  // THIS IS NOT A LINE, THIS IS A POINT. DON'T BOTHER CHECKING
  return false;
 }

 distance_point_1.copy(b.position);
 distance_point_1.subtract(a.position);

 distance_point_2.copy(b.position);
 distance_point_2.subtract(a.endPosition);

 rotated_direction.copy(directionB);
 rotated_direction.rotate90();

 if (rotated_direction.dot(distance_point_1) * rotated_direction.dot(distance_point_2) > 0) {
  return false;
 }

 return true;
}

Games

 

More Games

Calculation Solitaire
Colorado Solitaire
Cruel Solitaire
Freecell
Classic Solitaire
Scorpion Solitaire
space invaders
asteroids
sudoku
mathjong
mahjong words
reversi
3 Diamond Mahjong
8 bit mahjong
Big Eye Mahjong
Chinese Fan Mahjong
Circle Mahjong
Diamond Mine Mahjong
Sudoku
Candy Sudoku
Halloween Sudoku
Mermaid Sudoku
Christmas Sudoku
Valentine Sudoku
Candy Mahjong
Christmas Mahjong
Fruit Mahjong
Mermaid Mahjong
Office Mahjong
Valentine Mahjong
Multi Lines Mathjong
Plus Mathjong
Pyramid Mathjong
Shell Mathjong
Smiley Mathjong
Starfish Mathjong
To suggest an improvement, or just say hi, please contact me on twitter :-)

Follow @battagline or  Tweet to @battagline

Thanks,
Rick