2016-01-08 38 views
3

再次開始使用我的Agar.io克隆。兩個圓之間的基本碰撞檢測很容易(距離<半徑=碰撞)。但是,瓊脂的碰撞檢測有點複雜。它似乎檢測出圈A有多少圈B,但由於它不是開源的,我無法弄清楚他們是如何做到的。我在GitHub上看到了這個Agar clone,但似乎他們採取了更簡單的路線,並且只是定期進行碰撞檢測。檢查有多少圓與另一個圓碰撞

這就是我現在要做的。

collision: function(circle) { 
    var xx = circle.x - this.x; 
    var yy = circle.y - this.y; 
    var distance = Math.sqrt(xx * xx + yy * yy); 
    return distance < this.radius + circle.radius; 
}, 

我將如何檢查有一個圓圈中有多少是另一個圈子裏面?

+0

通過涵蓋你的意思是多少周或多少面積?無論哪種方式,一些高中水平的數學是你需要的 - http://mathworld.wolfram.com/Circle-CircleIntersection.html –

+0

地區,而不是周長。 – Raiden

+0

這很好,因爲我連接的數學顯示如何做區域 –

回答

4

可以通過添加2個相交圓部分的面積計算出2個圈之間的交叉區域:

enter image description here

  1. 計算2點,其中圓相交。

enter image description here

  • 計算由所述相交的楔形成的中心角。中心角是通過將一個交點連接到圓心點到另一個交點而形成的。
  • enter image description here

  • 計算圓截面的面積。您可以首先計算楔形區域的面積,然後減去楔形非弧形三角形的面積,從而計算出圓形區域的面積。
  • enter image description here減去enter image description here等於enter image description here

  • 用於兩個圓重複和同時添加部區域以獲得2米的圓的交叉點的總面積。
  • enter image description here

    示例代碼和演示

    var canvas=document.getElementById("canvas"); 
     
    var ctx=canvas.getContext("2d"); 
     
    var cw=canvas.width; 
     
    var ch=canvas.height; 
     
    function reOffset(){ 
     
        var BB=canvas.getBoundingClientRect(); 
     
        offsetX=BB.left; 
     
        offsetY=BB.top;   
     
    } 
     
    var offsetX,offsetY; 
     
    reOffset(); 
     
    window.onscroll=function(e){ reOffset(); } 
     
    
     
    
     
    // define 2 circles 
     
    var c1={x:100,y:100,r:100}; 
     
    var c2={x:200,y:200,r:150}; 
     
    
     
    // get points where 2 circles' perimeters intersect 
     
    var pts=intersection(c1.x,c1.y,c1.r,c2.x,c2.y,c2.r); 
     
    
     
    // get the angle formed by one intersection point 
     
    // and the circle's centerpoint 
     
    // and the other intersection point 
     
    var centralAngle1=centralAngle({x:pts.x1,y:pts.y1},{x:c1.x,y:c1.y},{x:pts.x2,y:pts.y2}); 
     
    var centralAngle2=centralAngle({x:pts.x1,y:pts.y1},{x:c2.x,y:c2.y},{x:pts.x2,y:pts.y2}); 
     
    
     
    // calculate the area of the two circle sectors 
     
    var sector1area=parseInt(sectorArea(c1.r,centralAngle1)); 
     
    var sector2area=parseInt(sectorArea(c2.r,centralAngle2)); 
     
    
     
    draw(); 
     
    
     
    
     
    function draw(){ 
     
        // stroke circles 
     
        ctx.beginPath(); 
     
        ctx.arc(c1.x,c1.y,c1.r,0,Math.PI*2); 
     
        ctx.closePath(); 
     
        ctx.stroke(); 
     
        ctx.beginPath(); 
     
        ctx.arc(c2.x,c2.y,c2.r,0,Math.PI*2); 
     
        ctx.closePath(); 
     
        ctx.stroke(); 
     
        // intersecting chord 
     
        ctx.beginPath(); 
     
        ctx.moveTo(pts.x1,pts.y1); 
     
        ctx.lineTo(pts.x2,pts.y2); 
     
        ctx.stroke(); 
     
        // intersection points 
     
        ctx.fillStyle='red'; 
     
        ctx.beginPath(); 
     
        ctx.arc(pts.x1,pts.y1,5,0,Math.PI*2); 
     
        ctx.closePath(); 
     
        ctx.fill(); 
     
        ctx.beginPath(); 
     
        ctx.arc(pts.x2,pts.y2,5,0,Math.PI*2); 
     
        ctx.closePath(); 
     
        ctx.fill(); 
     
        ctx.fillStyle='black'; 
     
        // sector labels 
     
        ctx.fillText('sector2',100,100); 
     
        ctx.fillText('sector1',135,135); 
     
        // report sector areas 
     
        ctx.fillText(sector2area,100,112); 
     
        ctx.fillText(sector1area+'px',135,147); 
     
        ctx.fillText('px',100,124); 
     
        // 
     
        ctx.fillText('circle#1',c1.x-35,c1.y-35); 
     
        ctx.fillText('circle#2',c2.x,c2.y); 
     
    } 
     
    
     
    // calc area of circle section 
     
    function sectorArea(radius,radianSweep){ 
     
        var PI=Math.PI; 
     
        var PI2=PI*2; 
     
        // area of wedge with specified sweep angle 
     
        var wedgeArea=(PI*radius*radius)*radianSweep/PI2; 
     
        // area of triangle formed by 2 radii & radianSweep 
     
        // == side angle side method 
     
        var triangleArea=0.50*radius*radius*Math.sin(radianSweep); 
     
        // subtract triangle area from wedge area 
     
        // leaving the sector area 
     
        return(wedgeArea-triangleArea); 
     
    } 
     
    
     
    // return angle between 3 points 
     
    function centralAngle(p0,p1,p2) { 
     
        var dx1=p1.x-p0.x; 
     
        var dy1=p1.y-p0.y; 
     
        var dx2=p1.x-p2.x; 
     
        var dy2=p1.y-p2.y; 
     
        var dx3=p2.x-p0.x; 
     
        var dy3=p2.y-p0.y; 
     
        var a=dx1*dx1+dy1*dy1; 
     
        var b=dx2*dx2+dy2*dy2; 
     
        var c=dx3*dx3+dy3*dy3; 
     
        return(Math.acos((a+b-c)/Math.sqrt(4*a*b))); 
     
    } 
     
    
     
    
     
    function centralAngleX(x1,y1,x2,y2){ 
     
        var dx=x2-x1; 
     
        var dy=y2-y1; 
     
        return(Math.abs(Math.atan2(dy,dx))); 
     
    } 
     
    
     
    function intersection(x0, y0, r0, x1, y1, r1) { 
     
        var a, dx, dy, d, h, rx, ry; 
     
        var x2, y2; 
     
        /* dx and dy are the vertical and horizontal distances between 
     
        * the circle centers. 
     
        */ 
     
        dx = x1 - x0; 
     
        dy = y1 - y0; 
     
        /* Determine the straight-line distance between the centers. */ 
     
        d = Math.sqrt((dy*dy) + (dx*dx)); 
     
        /* Check for solvability. */ 
     
        if (d > (r0 + r1)) { 
     
        /* no solution. circles do not intersect. */ 
     
        return false; 
     
        } 
     
        if (d < Math.abs(r0 - r1)) { 
     
        /* no solution. one circle is contained in the other */ 
     
        return false; 
     
        } 
     
        /* 'point 2' is the point where the line through the circle 
     
        * intersection points crosses the line between the circle 
     
        * centers. 
     
        */ 
     
        /* Determine the distance from point 0 to point 2. */ 
     
        a = ((r0*r0) - (r1*r1) + (d*d))/(2.0 * d) ; 
     
        /* Determine the coordinates of point 2. */ 
     
        x2 = x0 + (dx * a/d); 
     
        y2 = y0 + (dy * a/d); 
     
        /* Determine the distance from point 2 to either of the 
     
        * intersection points. 
     
        */ 
     
        h = Math.sqrt((r0*r0) - (a*a)); 
     
        /* Now determine the offsets of the intersection points from 
     
        * point 2. 
     
        */ 
     
        rx = -dy * (h/d); 
     
        ry = dx * (h/d); 
     
        /* Determine the absolute intersection points. */ 
     
        var xi = x2 + rx; 
     
        var xi_prime = x2 - rx; 
     
        var yi = y2 + ry; 
     
        var yi_prime = y2 - ry; 
     
        return({x1:xi, y1:yi, x2:xi_prime, y2:yi_prime}); 
     
    }
    <canvas id="canvas" width=350 height=350></canvas>

    +0

    嗯。爲什麼這些價值如此之大? – Raiden

    +0

    @Raiden值顯示正確。交叉點的區域包含許多像素。 – markE

    +0

    是的,但我如何將這些價值觀融入到我的工作中? – Raiden