POLYGON/LINE
Checking if a line is hitting a polygon is very much like the Rectangle/Line example. We go through each side of the polygon and do a Line/Line check.
In this example, we make a nice regular polygon with 16 sides (a hexadecagon). The points are stored in an array of PVectors again:
var vertices = ; // generate a nice, even polygonvar angle = TWO_PI / verticeslength;for var i=0; i<verticeslength; i++ var a = angle * i; var x = 300 + * 100; var y = 200 + * 100; verticesi = ;
We do the same for loop that walks through the vertices and gets the current point, as well as the point one step ahead in the array.
var next = 0;for var current=0; current<verticeslength; current++ // get next vertex in list // if we've hit the end, wrap around to 0 next = current+1; if next == verticeslength next = 0;
Now we can get the X/Y coordinates of those two points, which form a line:
var x3 = verticescurrentx;var y3 = verticescurrenty;var x4 = verticesnextx;var y4 = verticesnexty;
And we can pass that to a Line/Line collision. If any of the lines hit, we can immediately send back true
. This saves processing, since we can skip computing the remaining sides. If we get to the end and haven't had a hit, we return false
.
var hit = ;if hit return true;
Here's a full example:
var x1 = 0; // line position (set by mouse)var y1 = 0;var x2 = 20; // fixed endvar y2 = 20; // array of PVectors, one for each vertex in the polygonvar vertices = Array16; { var canvas = ; ; ; // make the line easier to see // set position of the vertices - a regular polygon! // based on this example: // https://processing.org/examples/regularpolygon.html var angle = TWO_PI / verticeslength; for var i=0; i<verticeslength; i++ var a = angle * i; var x = 300 + * 100; var y = 200 + * 100; verticesi = ; } { ; // update line to mouse coordinates x1 = mouseX; y1 = mouseY; // check for collision // if hit, change fill color var hit = ; if hit ; else ; // draw the polygon using beginShape() ; ; for var i=0; i<verticeslength; i++ var v = verticesi; ; ; // draw line ; ;} // POLYGON/LINE { // go through each of the vertices, plus the next // vertex in the list var next = 0; for var current=0; current<verticeslength; current++ // get next vertex in list // if we've hit the end, wrap around to 0 next = current+1; if next == verticeslength next = 0; // get the PVectors at our current position // extract X/Y coordinates from each var x3 = verticescurrentx; var y3 = verticescurrenty; var x4 = verticesnextx; var y4 = verticesnexty; // do a Line/Line comparison // if true, return 'true' immediately and // stop testing (faster) var hit = ; if hit return true; // never got a hit return false;} // LINE/LINE { // calculate the direction of the lines var uA = x4-x3*y1-y3 - y4-y3*x1-x3 / y4-y3*x2-x1 - x4-x3*y2-y1; var 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 return true; return false;}