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;
}
- Next -> Part 4 - Oriented rectangle collision detection
- Part 5 - Polygon collision detection
- Part 1 - Circle circle collision detection
- Part 2 - Rectangle collision detection
- Part 3 - Line line collision detection