Collision Detection

[ your browser does not support the canvas tag ]

LINE/LINE

With this example, you'll be able to build a super-sweet sword fighting game! (Or reboot one that never got finished?)

To check if two lines are touching, we have to calculate the distance to the point of intersection:

float uA = ((x4-x3)*(y1-y3) - (y4-y3)*(x1-x3)) / ((y4-y3)*(x2-x1) - (x4-x3)*(y2-y1));

float uB = ((x2-x1)*(y1-y3) - (y2-y1)*(x1-x3)) / ((y4-y3)*(x2-x1) - (x4-x3)*(y2-y1));

If there is a collision, uA and uB should both be in the range of 0-1. We test for that like this:

if (uA >= 0 && uA <= 1 && uB >= 0 && uB <= 1) {
    return true;
}
return false;

That's it! We can add one more feature, if desired, that will tell us the intersection point of the two lines. This might be useful if, for example, you're making a sword-fighting game and want sparks to fly where the two blades hit.

float intersectionX = x1 + (uA * (x2-x1));
float intersectionY = y1 + (uA * (y2-y1));

Here's the full example:

float x1 = 0;    // line controlled by mouse
float y1 = 0;
float x2 = 10;   // fixed end
float y2 = 10;

float x3 = 100;  // static line
float y3 = 300;
float x4 = 500;
float y4 = 100;


void setup() {
  size(600,400);

  strokeWeight(5);  // make lines easier to see
}


void draw() {
  background(255);

  // set line's end to mouse coordinates
  x1 = mouseX;
  y1 = mouseY;

  // check for collision
  // if hit, change color of line
  boolean hit = lineLine(x1,y1,x2,y2, x3,y3,x4,y4);
  if (hit) stroke(255,150,0, 150);
  else stroke(0,150,255, 150);
  line(x3,y3, x4,y4);

  // draw user-controlled line
  stroke(0, 150);
  line(x1,y1, x2,y2);
}


// LINE/LINE
boolean lineLine(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4) {

  // calculate the distance to intersection point
  float uA = ((x4-x3)*(y1-y3) - (y4-y3)*(x1-x3)) / ((y4-y3)*(x2-x1) - (x4-x3)*(y2-y1));
  float uB = ((x2-x1)*(y1-y3) - (y2-y1)*(x1-x3)) / ((y4-y3)*(x2-x1) - (x4-x3)*(y2-y1));

  // if uA and uB are between 0-1, lines are colliding
  if (uA >= 0 && uA <= 1 && uB >= 0 && uB <= 1) {

    // optionally, draw a circle where the lines meet
    float intersectionX = x1 + (uA * (x2-x1));
    float intersectionY = y1 + (uA * (y2-y1));
    fill(255,0,0);
    noStroke();
    ellipse(intersectionX,intersectionY, 20,20);

    return true;
  }
  return false;
}

Based on a tutorial by Paul Bourke, who includes code to test if the lines are parallel and coincident. Also based on this post by Ibackstrom and help from Reddit.

NEXT: Line/Rectangle