/* Repo: https://github.com/bmoren/p5.collide2D/ Created by http://benmoren.com Some functions and code modified version from http://www.jeffreythompson.org/collision-detection Version v0.7.3 | June 22, 2020 CC BY-NC-SA 4.0 File edited to fit my needs and project */ import p5 from 'p5' // const collideRectRect = function (x, y, w, h, x2, y2, w2, h2) { // //2d // //add in a thing to detect rectMode CENTER // if (x + w >= x2 && // r1 right edge past r2 left // x <= x2 + w2 && // r1 left edge past r2 right // y + h >= y2 && // r1 top edge past r2 bottom // y <= y2 + h2) { // r1 bottom edge past r2 top // return true; // } // return false; // }; // // p5.vector version of collideRectRect // p5.prototype.collideRectRectVector = function(p1, sz, p2, sz2){ // return p5.prototype.collideRectRect(p1.x, p1.y, sz.x, sz.y, p2.x, p2.y, sz2.x,sz2.y) // } const collideRectCircle = function (p5: p5, rx: number, ry: number, rw: number, rh: number, cx: number, cy: number, diameter: number) { //2d // temporary variables to set edges for testing var testX = cx; var testY = cy; // which edge is closest? if (cx < rx){ testX = rx // left edge }else if (cx > rx+rw){ testX = rx+rw } // right edge if (cy < ry){ testY = ry // top edge }else if (cy > ry+rh){ testY = ry+rh } // bottom edge // // get distance from closest edges var distance = p5.dist(cx,cy,testX,testY) // if the distance is less than the radius, collision! if (distance <= diameter/2) { return true; } return false; }; // // p5.vector version of collideRectCircle // p5.prototype.collideRectCircleVector = function(r, sz, c, diameter){ // return p5.prototype.collideRectCircle(r.x,r.y, sz.x,sz.y, c.x,c.y, diameter) // } const collideCircleCircle = function (p5: p5, x: number, y: number, d: number, x2: number, y2: number, d2: number) { //2d if( p5.dist(x,y,x2,y2) <= (d/2)+(d2/2) ){ return true; } return false; }; // p5.vector version of collideCircleCircle // p5.prototype.collideCircleCircleVector = function(p1,d, p2, d2){ // return p5.prototype.collideCircleCircle(p1.x,p1.y, d, p2.x,p2.y, d2) // } // p5.prototype.collidePointCircle = function (x, y, cx, cy, d) { // //2d // if( this.dist(x,y,cx,cy) <= d/2 ){ // return true; // } // return false; // }; // // p5.vector version of collidePointCircle // p5.prototype.collidePointCircleVector = function(p, c, d){ // return p5.prototype.collidePointCircle(p.x,p.y,c.x,c.y, d) // } // p5.prototype.collidePointEllipse = function (x, y, cx, cy, dx, dy) { // //2d // var rx = dx/2, ry = dy/2; // // Discarding the points outside the bounding box // if (x > cx + rx || x < cx - rx ||y > cy + ry || y < cy - ry) { // return false; // } // // Compare the point to its equivalent on the ellipse // var xx = x - cx, yy = y - cy; // var eyy = ry * this.sqrt(this.abs(rx * rx - xx * xx)) / rx; // return yy <= eyy && yy >= -eyy; // }; // // p5.vector version of collidePointEllipse // p5.prototype.collidePointEllipseVector = function(p, c, d){ // return p5.prototype.collidePointEllipse(p.x,p.y,c.x,c.y,d.x,d.y); // } // p5.prototype.collidePointRect = function (pointX, pointY, x, y, xW, yW) { // //2d // if (pointX >= x && // right of the left edge AND // pointX <= x + xW && // left of the right edge AND // pointY >= y && // below the top AND // pointY <= y + yW) { // above the bottom // return true; // } // return false; // }; // // p5.vector version of collidePointRect // p5.prototype.collidePointRectVector = function(point, p1, sz){ // return p5.prototype.collidePointRect(point.x, point.y, p1.x, p1.y, sz.x, sz.y); // } // p5.prototype.collidePointLine = function(px,py,x1,y1,x2,y2, buffer){ // // get distance from the point to the two ends of the line // var d1 = this.dist(px,py, x1,y1); // var d2 = this.dist(px,py, x2,y2); // // get the length of the line // var lineLen = this.dist(x1,y1, x2,y2); // // since floats are so minutely accurate, add a little buffer zone that will give collision // if (buffer === undefined){ buffer = 0.1; } // higher # = less accurate // // if the two distances are equal to the line's length, the point is on the line! // // note we use the buffer here to give a range, rather than one # // if (d1+d2 >= lineLen-buffer && d1+d2 <= lineLen+buffer) { // return true; // } // return false; // } // // p5.vector version of collidePointLine // p5.prototype.collidePointLineVector = function(point,p1,p2, buffer){ // return p5.prototype.collidePointLine(point.x,point.y, p1.x,p1.y, p2.x,p2.y, buffer); // } // p5.prototype.collideLineCircle = function( x1, y1, x2, y2, cx, cy, diameter) { // // is either end INSIDE the circle? // // if so, return true immediately // var inside1 = this.collidePointCircle(x1,y1, cx,cy,diameter); // var inside2 = this.collidePointCircle(x2,y2, cx,cy,diameter); // if (inside1 || inside2) return true; // // get length of the line // var distX = x1 - x2; // var distY = y1 - y2; // var len = this.sqrt( (distX*distX) + (distY*distY) ); // // get dot product of the line and circle // var dot = ( ((cx-x1)*(x2-x1)) + ((cy-y1)*(y2-y1)) ) / this.pow(len,2); // // find the closest point on the line // var closestX = x1 + (dot * (x2-x1)); // var closestY = y1 + (dot * (y2-y1)); // // is this point actually on the line segment? // // if so keep going, but if not, return false // var onSegment = this.collidePointLine(closestX,closestY,x1,y1,x2,y2); // if (!onSegment) return false; // // draw a debug circle at the closest point on the line // if(this._collideDebug){ // this.ellipse(closestX, closestY,10,10); // } // // get distance to closest point // distX = closestX - cx; // distY = closestY - cy; // var distance = this.sqrt( (distX*distX) + (distY*distY) ); // if (distance <= diameter/2) { // return true; // } // return false; // } // // p5.vector version of collideLineCircle // p5.prototype.collideLineCircleVector = function( p1, p2, c, diameter){ // return p5.prototype.collideLineCircle( p1.x, p1.y, p2.x, p2.y, c.x, c.y, diameter); // } // p5.prototype.collideLineLine = function(x1, y1, x2, y2, x3, y3, x4, y4,calcIntersection) { // var intersection; // // calculate the distance to intersection point // 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) { // if(this._collideDebug || calcIntersection){ // // calc the point where the lines meet // var intersectionX = x1 + (uA * (x2-x1)); // var intersectionY = y1 + (uA * (y2-y1)); // } // if(this._collideDebug){ // this.ellipse(intersectionX,intersectionY,10,10); // } // if(calcIntersection){ // intersection = { // "x":intersectionX, // "y":intersectionY // } // return intersection; // }else{ // return true; // } // } // if(calcIntersection){ // intersection = { // "x":false, // "y":false // } // return intersection; // } // return false; // } // // p5.vector version of collideLineLine // p5.prototype.collideLineLineVector = function(p1, p2, p3, p4, calcIntersection){ // return p5.prototype.collideLineLine(p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y, calcIntersection); // } // p5.prototype.collideLineRect = function(x1, y1, x2, y2, rx, ry, rw, rh, calcIntersection) { // // check if the line has hit any of the rectangle's sides. uses the collideLineLine function above // var left, right, top, bottom, intersection; // if(calcIntersection){ // left = this.collideLineLine(x1,y1,x2,y2, rx,ry,rx, ry+rh,true); // right = this.collideLineLine(x1,y1,x2,y2, rx+rw,ry, rx+rw,ry+rh,true); // top = this.collideLineLine(x1,y1,x2,y2, rx,ry, rx+rw,ry,true); // bottom = this.collideLineLine(x1,y1,x2,y2, rx,ry+rh, rx+rw,ry+rh,true); // intersection = { // "left" : left, // "right" : right, // "top" : top, // "bottom" : bottom // } // }else{ // //return booleans // left = this.collideLineLine(x1,y1,x2,y2, rx,ry,rx, ry+rh); // right = this.collideLineLine(x1,y1,x2,y2, rx+rw,ry, rx+rw,ry+rh); // top = this.collideLineLine(x1,y1,x2,y2, rx,ry, rx+rw,ry); // bottom = this.collideLineLine(x1,y1,x2,y2, rx,ry+rh, rx+rw,ry+rh); // } // // if ANY of the above are true, the line has hit the rectangle // if (left || right || top || bottom) { // if(calcIntersection){ // return intersection; // } // return true; // } // return false; // } // // p5.vector version of collideLineRect // p5.prototype.collideLineRectVector = function(p1, p2, r, rsz, calcIntersection){ // return p5.prototype.collideLineRect(p1.x, p1.y, p2.x, p2.y, r.x, r.y, rsz.x, rsz.y, calcIntersection); // } // p5.prototype.collidePointPoly = function(px, py, vertices) { // var collision = false; // // go through each of the vertices, plus the next vertex in the list // var next = 0; // for (var current=0; current= py && vn.y < py) || (vc.y < py && vn.y >= py)) && // (px < (vn.x-vc.x)*(py-vc.y) / (vn.y-vc.y)+vc.x)) { // collision = !collision; // } // } // return collision; // } // // p5.vector version of collidePointPoly // p5.prototype.collidePointPolyVector = function(p1, vertices){ // return p5.prototype.collidePointPoly(p1.x, p1.y, vertices); // } // // POLYGON/CIRCLE // p5.prototype.collideCirclePoly = function(cx, cy, diameter, vertices, interior) { // if (interior === undefined){ // interior = false; // } // // go through each of the vertices, plus the next vertex in the list // var next = 0; // for (var current=0; current 0 && angle <= arcAngle / 2 && angle >= -arcAngle / 2) { // return true; // } // } // return false; // } // // p5.vector version of collidePointArc // p5.prototype.collidePointArcVector = function(p1, a, arcRadius, arcHeading, arcAngle, buffer){ // return p5.prototype.collidePointArc(p1.x, p1.y, a.x, a.y, arcRadius, arcHeading, arcAngle, buffer); // } export { collideCircleCircle, collideRectCircle }