Collision detection between a line and a circle in JavaScript

前端 未结 4 1572
故里飘歌
故里飘歌 2020-12-06 18:57

I\'m looking for a definitive answer, maybe a function cos I\'m slow, that will determine if a line segment and circle have collided, in javascript (working with canvas)

相关标签:
4条回答
  • 2020-12-06 19:32
    function pointCircleCollide(point, circle, r) {
        if (r===0) return false
        var dx = circle[0] - point[0]
        var dy = circle[1] - point[1]
        return dx * dx + dy * dy <= r * r
    }
    
    var tmp = [0, 0]
    
    function lineCircleCollide(a, b, circle, radius, nearest) {
        //check to see if start or end points lie within circle
        if (pointCircleCollide(a, circle, radius)) {
            if (nearest) {
                nearest[0] = a[0]
                nearest[1] = a[1]
            }
            return true
        } if (pointCircleCollide(b, circle, radius)) {
            if (nearest) {
                nearest[0] = b[0]
                nearest[1] = b[1]
            }
            return true
        }
    
        var x1 = a[0],
            y1 = a[1],
            x2 = b[0],
            y2 = b[1],
            cx = circle[0],
            cy = circle[1]
    
        //vector d
        var dx = x2 - x1
        var dy = y2 - y1
    
        //vector lc
        var lcx = cx - x1
        var lcy = cy - y1
    
        //project lc onto d, resulting in vector p
        var dLen2 = dx * dx + dy * dy //len2 of d
        var px = dx
        var py = dy
        if (dLen2 > 0) {
            var dp = (lcx * dx + lcy * dy) / dLen2
            px *= dp
            py *= dp
        }
    
        if (!nearest)
            nearest = tmp
        nearest[0] = x1 + px
        nearest[1] = y1 + py
    
        //len2 of p
        var pLen2 = px * px + py * py
    
        //check collision
        return pointCircleCollide(nearest, circle, radius)
                && pLen2 <= dLen2 && (px * dx + py * dy) >= 0
    }
    
    var circle = [5, 5],
        radius = 25,
        a = [5, 6],
        b = [10, 10]
    
    var hit = lineCircleCollide(a, b, circle, radius)
    
    
    0 讨论(0)
  • 2020-12-06 19:33

    I Spent about a day and a half to make it perfect.. Hope this helps.

    function collisionCircleLine(circle,line){ // Both are objects
    
        var side1 = Math.sqrt(Math.pow(circle.x - line.p1.x,2) + Math.pow(circle.y - line.p1.y,2)); // Thats the pythagoras theoram If I can spell it right
    
        var side2 = Math.sqrt(Math.pow(circle.x - line.p2.x,2) + Math.pow(circle.y - line.p2.y,2));
    
        var base = Math.sqrt(Math.pow(line.p2.x - line.p1.x,2) + Math.pow(line.p2.y - line.p1.y,2));
    
        if(circle.radius > side1 || circle.radius > side2)
            return true;
    
        var angle1 = Math.atan2( line.p2.x - line.p1.x, line.p2.y - line.p1.y ) - Math.atan2( circle.x - line.p1.x, circle.y - line.p1.y ); // Some complicated Math
    
        var angle2 = Math.atan2( line.p1.x - line.p2.x, line.p1.y - line.p2.y ) - Math.atan2( circle.x - line.p2.x, circle.y - line.p2.y ); // Some complicated Math again
    
        if(angle1 > Math.PI / 2 || angle2 > Math.PI / 2) // Making sure if any angle is an obtuse one and Math.PI / 2 = 90 deg
            return false;
    
    
            // Now if none are true then
    
            var semiperimeter = (side1 + side2 + base) / 2;
    
            var areaOfTriangle = Math.sqrt( semiperimeter * (semiperimeter - side1) * (semiperimeter - side2) * (semiperimeter - base) ); // Heron's formula for the area
    
            var height = 2*areaOfTriangle/base;
    
            if( height < circle.radius )
                return true;
            else
                return false;
    
    }
    

    And that is how you do it..

    0 讨论(0)
  • 2020-12-06 19:37

    Here you will need some Math:

    enter image description here This is the basic concept if you don't know how to solve equations in general. I will leave the rest of the thinking to you. ;) Figuring out CD's length isn't that hard.

    If you are asking how, that's how: enter image description here Finding collisions in JavaScript is kind of complicated.

    0 讨论(0)
  • 2020-12-06 19:42

    Matt DesLauriers published a Javascript library for this problem at https://www.npmjs.com/package/line-circle-collision. The API is straightforward:

    var circle = [5, 5],
        radius = 25,
        a = [5, 6],
        b = [10, 10]
    
    var hit = collide(a, b, circle, radius)
    
    0 讨论(0)
提交回复
热议问题