Closed. This question needs to be more focused。它当前不接受答案。
                            
                        
                    
                
            
                    
                
                        
                            
                        
                    
                        
                            想改善这个问题吗?更新问题,使其仅通过editing this post专注于一个问题。
                        
                        3年前关闭。
                    
                
        

我有一些代码在其中绘制一个三角形并返回其中带有x1, y1, x2, y2, x3, y3的对象。我也有一个返回x, y, w, h的矩形绘制函数和一个返回x1, y1, x2, y2, x3, y3, x4, y4, x5, y5的五边形绘制函数。如何制作碰撞检测功能,以检测矩形和五边形或三角形和五边形是否发生碰撞?

最佳答案

测试三角形的任意边(线段)是否与矩形的任意边相交

如果任何一侧相交,则三角形和矩形碰撞。


将三角形的第1面相对于矩形的每一面进行测试,
在矩形的每一侧上测试三角形的第二侧,
将三角形的第3面相对于矩形的每一面进行测试,
如果在测试时发现拦截,则可以停止,因为形状确实在碰撞。


有关“是否截取两个线段?”的详细信息,请参见下文。

对其他任何多边形进行相同的侧面拦截测试,以查看它们是否发生碰撞。

这里复制了两行拦截的测试:

// point object: {x:, y:}
// p0 & p1 form one segment, p2 & p3 form the second segment
// Returns true if lines segments are intercepting
var lineSegmentsIntercept = (function(){ // function as singleton so that closure can be used

    var v1, v2, v3, cross, u1, u2;  // working variable are closed over so they do not need creation
                               // each time the function is called. This gives a significant performance boost.
    v1 = {x : null, y : null}; // line p0, p1 as vector
    v2 = {x : null, y : null}; // line p2, p3 as vector
    v3 = {x : null, y : null}; // the line from p0 to p2 as vector

    function lineSegmentsIntercept (p0, p1, p2, p3) {
        v1.x = p1.x - p0.x; // line p0, p1 as vector
        v1.y = p1.y - p0.y;
        v2.x = p3.x - p2.x; // line p2, p3 as vector
        v2.y = p3.y - p2.y;
        if((cross = v1.x * v2.y - v1.y * v2.x) === 0){  // cross prod 0 if lines parallel
            return false; // no intercept
        }
        v3 = {x : p0.x - p2.x, y : p0.y - p2.y};  // the line from p0 to p2 as vector
        u2 = (v1.x * v3.y - v1.y * v3.x) / cross; // get unit distance along line p2 p3
        // code point B
        if (u2 >= 0 && u2 <= 1){                   // is intercept on line p2, p3
            u1 = (v2.x * v3.y - v2.y * v3.x) / cross; // get unit distance on line p0, p1;
            // code point A
            return (u1 >= 0 && u1 <= 1);           // return true if on line else false.
            // code point A end
        }
        return false; // no intercept;
        // code point B end
    }
    return lineSegmentsIntercept;  // return function with closure for optimisation.
})();






两个线段是否相互拦截?


  (归因于user blindman67,以协助以下示例)


如果两个线段相交,则此示例中的函数返回true,否则返回false

该示例旨在提高性能,并使用闭包来保存工作变量

Java脚本
    //点对象:{x :, y:}
    // p0和p1构成一个分段,p2&p3构成第二个分段
    //如果线段正在拦截,则返回true
    var lineSegmentsIntercept =(function(){//作为单例函数,因此可以使用闭包

    var v1, v2, v3, cross, u1, u2;  // working variable are closed over so they do not need creation
                               // each time the function is called. This gives a significant performance boost.
    v1 = {x : null, y : null}; // line p0, p1 as vector
    v2 = {x : null, y : null}; // line p2, p3 as vector
    v3 = {x : null, y : null}; // the line from p0 to p2 as vector

    function lineSegmentsIntercept (p0, p1, p2, p3) {
        v1.x = p1.x - p0.x; // line p0, p1 as vector
        v1.y = p1.y - p0.y;
        v2.x = p3.x - p2.x; // line p2, p3 as vector
        v2.y = p3.y - p2.y;
        if((cross = v1.x * v2.y - v1.y * v2.x) === 0){  // cross prod 0 if lines parallel
            return false; // no intercept
        }
        v3 = {x : p0.x - p2.x, y : p0.y - p2.y};  // the line from p0 to p2 as vector
        u2 = (v1.x * v3.y - v1.y * v3.x) / cross; // get unit distance along line p2 p3
        // code point B
        if (u2 >= 0 && u2 <= 1){                   // is intercept on line p2, p3
            u1 = (v2.x * v3.y - v2.y * v3.x) / cross; // get unit distance on line p0, p1;
            // code point A
            return (u1 >= 0 && u1 <= 1);           // return true if on line else false.
            // code point A end
        }
        return false; // no intercept;
        // code point B end
    }
    return lineSegmentsIntercept;  // return function with closure for optimisation.
})();


```

使用范例

var p1 = {x: 100, y: 0};   // line 1
var p2 = {x: 120, y: 200};
var p3 = {x: 0,   y: 100}; // line 2
var p4 = {x: 100, y: 120};
var areIntersepting = lineSegmentsIntercept (p1, p2, p3, p4); // true


该示例很容易修改以返回拦截点。将code point AA end之间的代码替换为

if(u1 >= 0 && u1 <= 1){
    return {
        x : p0.x + v1.x * u1,
        y : p0.y + v1.y * u1,
    };
}


或者,如果要获取直线上的截点,则忽略线段的起点和终点,将code point BB end之间的代码替换为

return {
    x : p2.x + v2.x * u2,
    y : p2.y + v2.y * u2,
};


如果没有拦截,则两种修改都将返回false或将拦截点返回为{x : xCoord, y : yCoord}

09-16 10:20