Skip to content
Advertisement

Intersection between 2 circles javascript

Iā€™m trying to do a function to detect intersections between two circles. If yes it scores true, otherwise it scores false, but I think I got lost so it does not display what I want. If anyone can help me please . Thank you Surely I have incorrectly coded in javascript if there is a person who knows the answer I am all ears

function AreCirclesIntersecting(c0,c1) {

    x0 = c0['center']['x'];
    y0 = c0['center']['y'];
    r0 = c0['center']['r'];
    x1 = c1['center']['x'];
    y1 = c1['center']['y'];
    r1 = c1['center']['r'];


    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 [xi, xi_prime, yi, yi_prime];

}

const circles = [
    {center: {x: 10.0, y: 10.0}, radius: 5.0},
    {center: {x: 20.0, y: 20.0}, radius: 15.0},
    {center: {x: 20.0, y: 10.0}, radius: 5.0},
    {center: {x: 20.0, y: 25.0}, radius: 7.5},
];

const q7_result1 = AreCirclesIntersecting(circles[0], circles[1]);
console.log(q7_result1); // Expected output: true

const q7_result2 = AreCirclesIntersecting(circles[0], circles[2]);
console.log(q7_result2); // Expected output: true

const q7_result3 = AreCirclesIntersecting(circles[1], circles[3]);
console.log(q7_result3); // Expected output: false

const q7_result4 = AreCirclesIntersecting(circles[2], circles[3]);
console.log(q7_result4); // Expected output: false

Advertisement

Answer

Javascript natively offers a hypothenus function,
useful here to calculate the distance between 2 points on a 2 D system

const circles = 
  [ { center: { x: 10.0, y: 10.0 } , radius:  5.0 }  
  , { center: { x: 20.0, y: 20.0 } , radius: 15.0 }  
  , { center: { x: 20.0, y: 10.0 } , radius:  5.0 } 
  , { center: { x: 20.0, y: 25.0 } , radius:  7.5 } 
  ] 

function AreCirclesIntersecting(c0,c1)
  {
  let delta_x  = Math.abs(c0.center.x - c1.center.x)
    , delta_y  = Math.abs(c0.center.y - c1.center.y)
    , dist     = Math.hypot(delta_x, delta_y)
    , out      = (dist > (c0.radius + c1.radius) )
    , c0_in_c1 = !out && ( c1.radius > (c0.radius + dist )) 
    , c1_in_c0 = !out && ( c0.radius > (c1.radius + dist )) 
    ;
  return !(out || c0_in_c1 || c1_in_c0)
  }

function testing (name, expected, indx_a, indx_b )
  {
  let test    = AreCirclesIntersecting(circles[indx_a], circles[indx_b])
    , divTest = document.createElement('div')
    , c0      = circles[indx_a]
    , c1      = circles[indx_b]
    ;
  divTest.className = 'test'
  divTest.innerHTML = `
  <p> 
    <strong>${name}</strong> <br>
    ${JSON.stringify(circles[indx_a]) } green <br>
    ${JSON.stringify(circles[indx_b]) } red <br><br>
    expected: ${expected}<br>result:<strong>${test}</strong><br>sucess: ${(expected===test)? 'āœ…':'āŒ'}
  </p>
  <svg viewBox="0 0 50 40" xmlns="http://www.w3.org/2000/svg" width="200" heigth="160">
    <circle cx="${c0.center.x}" cy="${c0.center.y}" r="${c0.radius}" fill="none" stroke="green"/>
    <circle cx="${c1.center.x}" cy="${c1.center.y}" r="${c1.radius}" fill="none" stroke="red"/>
  </svg>`
  document.body.appendChild(divTest)
}  

testing('q7_result1',true, 0,1)
testing('q7_result2',true, 0,2)
testing('q7_result3',false,1,3)
testing('q7_result4',false,2,3)
body {
  font-family: Arial, Helvetica, sans-serif;
  font-size: 14px;
}
div.test {
  display : inline-block;
  margin  : .5em;
  border  : 1px solid grey;
  padding : 1em;
  width   : 400px;
}
div.test p { margin: .3em; }
User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement