代码之家  ›  专栏  ›  技术社区  ›  brent

Kineticjs发现一条线是否与矩形发生冲突

  •  0
  • brent  · 技术社区  · 10 年前

    我正在尝试编写一个函数来检测一条直线是否与矩形相交。 我有一个检测图像是否与矩形相交的函数,但线型没有我需要的所有财产,如宽度和高度等。

    function checkCollision(obj1, obj2){ //checks for collision
    var status = false;
    var obj1Top = obj1.getAttr('y');
    var obj1Bottom = obj1.getAttr('y') + obj1.getAttr('height');
    var obj1Left = obj1.getAttr('x');
    var obj1Right = obj1.getAttr('x') + obj1.getAttr('width');
    
    var obj2Top = obj2.getAttr('y');
    var obj2Bottom = obj2.getAttr('y') + obj2.getAttr('height');
    var obj2Left = obj2.getAttr('x');
    var obj2Right = obj2.getAttr('x') + obj2.getAttr('width');
    
    if (!(obj1Bottom < obj2Top || obj1Top > obj2Bottom || obj1Left > obj2Right || obj1Right < obj2Left))
    
    status = true;
    
    return status;
    }
    

    有什么想法吗?

    1 回复  |  直到 10 年前
        1
  •  2
  •   markE    10 年前

    演示: http://jsfiddle.net/m1erickson/eZHu7/

    线-矩形碰撞异常复杂!

    此函数用于测试线段是否与矩形的4条边中的任何一条相交:

    // test line vs the 4 rectangle lines
    function lineRectIntersects(line,rect){
    
        // p=line startpoint, p2=line endpoint
        var p={x:line.x1,y:line.y1};
        var p2={x:line.x2,y:line.y2};
    
        // top rect line
        var q={x:rect.x,y:rect.y};
        var q2={x:rect.x+rect.width,y:rect.y};
        if(doLineSegmentsIntersect(p,p2,q,q2)){ return true; }
    
        // right rect line
        var q=q2;
        var q2={x:rect.x+rect.width,y:rect.y+rect.height};
        if(doLineSegmentsIntersect(p,p2,q,q2)){ return true; }
    
        // bottom rect line
        var q=q2;
        var q2={x:rect.x,y:rect.y+rect.height};
        if(doLineSegmentsIntersect(p,p2,q,q2)){ return true; }
    
        // left rect line
        var q=q2;
        var q2={x:rect.x,y:rect.y};
        if(doLineSegmentsIntersect(p,p2,q,q2)){ return true; }
    
        // If not intersecting with the 4 rect sides, then not intersecting
        return(false);
    }
    

    该函数使用Peter Kelley的直线相交算法:

    https://github.com/pgkelley4/line-segments-intersect/blob/master/js/line-segments-intersect.js

    Peter的代码在此处复制,以防链接腐烂:

    /**
     * @author Peter Kelley
     * @author pgkelley4@gmail.com
     */
    
    
    /**
     * See if two line segments intersect. This uses the 
     * vector cross product approach described below:
     * http://stackoverflow.com/a/565282/786339
     * 
     * @param {Object} p point object with x and y coordinates
     *  representing the start of the 1st line.
     * @param {Object} p2 point object with x and y coordinates
     *  representing the end of the 1st line.
     * @param {Object} q point object with x and y coordinates
     *  representing the start of the 2nd line.
     * @param {Object} q2 point object with x and y coordinates
     *  representing the end of the 2nd line.
     */
    function doLineSegmentsIntersect(p, p2, q, q2) {
      var r = subtractPoints(p2, p);
      var s = subtractPoints(q2, q);
    
    
      var uNumerator = crossProduct(subtractPoints(q, p), r);
      var denominator = crossProduct(r, s);
    
    
      if (uNumerator == 0 && denominator == 0) {
        // colinear, so do they overlap?
        return ((q.x - p.x < 0) != (q.x - p2.x < 0) != (q2.x - p.x < 0) != (q2.x - p2.x < 0)) || 
          ((q.y - p.y < 0) != (q.y - p2.y < 0) != (q2.y - p.y < 0) != (q2.y - p2.y < 0));
      }
    
    
      if (denominator == 0) {
        // lines are paralell
        return false;
      }
    
    
      var u = uNumerator / denominator;
      var t = crossProduct(subtractPoints(q, p), s) / denominator;
    
    
      return (t >= 0) && (t <= 1) && (u >= 0) && (u <= 1);
    }
    
    
    /**
     * Calculate the cross product of the two points.
     * 
     * @param {Object} point1 point object with x and y coordinates
     * @param {Object} point2 point object with x and y coordinates
     * 
     * @return the cross product result as a float
     */
    function crossProduct(point1, point2) {
      return point1.x * point2.y - point1.y * point2.x;
    }
    
    
    /**
     * Subtract the second point from the first.
     * 
     * @param {Object} point1 point object with x and y coordinates
     * @param {Object} point2 point object with x and y coordinates
     * 
     * @return the subtraction result as a point object.
     */ 
    function subtractPoints(point1, point2) {
      var result = {};
      result.x = point1.x - point2.x;
      result.y = point1.y - point2.y;
      return result;
    }