Draw triangle by the intersect of 3 circles

816 Views Asked by At

I want to draw a triangle base on the intersection points of 3 circles. Is there any function or any method with JavaScript to solve this? Or I need to perform some math calculation to get exact position of the intersection point and draw the triangle myself.

enter image description here

function drawMap(){
    var ctx = $('#map')[0].getContext("2d");

    // Draw the map of my room 400cm * 300cm
    ctx.fillStyle = "#ecf0f1"
    ctx.beginPath();
    ctx.rect(0, 0, 300, 400);
    ctx.closePath();
    ctx.fill();

    //Draw the first circle (blue one)
    ctx.fillStyle = "rgba(52, 152, 219,0.5)";
    ctx.beginPath();
    ctx.arc(0, 0, 200, 0, Math.PI*2, true);
    ctx.closePath();
    ctx.fill();

    //Draw the second circle(green one)
    ctx.fillStyle = "rgba(46, 204, 113,0.5)";
    ctx.beginPath();
    ctx.arc(0, 400, 250, 0, Math.PI*2, true);
    ctx.closePath();
    ctx.fill();

    // Draw the third circle (yellow one)
    ctx.fillStyle = "rgba(241, 196, 15,0.5)";
    ctx.beginPath();
    ctx.arc(300, 200, 280, 0, Math.PI*2, true);
    ctx.closePath();
    ctx.fill();
}
2

There are 2 best solutions below

5
On BEST ANSWER

Finding the intersection points which are on the circumference of all three circles

enter image description here

Here's how to do it:

Define 3 circles:

var A={x:0,y:0,r:200,color:"rgba(52, 152, 219,0.5)"};
var B={x:0,y:400,r:250,color:"rgba(46, 204, 113,0.5)"};
var C={x:300,y:200,r:280,color:"rgba(241, 196, 15,0.5)"};

Calculate the intersection points of the 3 circles vs each other (AB,BC,CA):

var intersections=[];
var AB=circleIntersections(A,B); // see example code below for circleIntersections()
var BC=circleIntersections(B,C);
var CA=circleIntersections(C,A);
if(AB){intersections.push(AB);}
if(BC){intersections.push(BC);}
if(CA){intersections.push(CA);}

Test each intersection point. Keep any intersection points that are in all 3 circles.

var triangle=[];
for(var i=0;i<intersections.length;i++){
    var pt=intersections[i];
    if(ptIsInCircle(pt,A) && ptIsInCircle(pt,B) && ptIsInCircle(pt,C)){
        triangle.push(pt);
    }
}

In your example code you are left with 3 intersection points that are also in all 3 circles.

But with circles positioned elsewhere you might get fewer or more than 3 intersection points.

Use context path commands to draw a polyline between the 3 discovered points.

if(triangle.length==3){
    ctx.beginPath();
    ctx.moveTo(triangle[0].x,triangle[0].y);
    ctx.lineTo(triangle[1].x,triangle[1].y);
    ctx.lineTo(triangle[2].x,triangle[2].y);
    ctx.closePath();
    ctx.stroke();
}

Example code and a Demo:

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(); }




var A={x:0,y:0,r:200,color:"rgba(52, 152, 219,0.5)"};
var B={x:0,y:400,r:250,color:"rgba(46, 204, 113,0.5)"};
var C={x:300,y:200,r:280,color:"rgba(241, 196, 15,0.5)"};

var intersections=[];
var AB=circleIntersections(A,B);
var BC=circleIntersections(B,C);
var CA=circleIntersections(C,A);
if(AB){intersections=intersections.concat(AB);}
if(BC){intersections=intersections.concat(BC);}
if(CA){intersections=intersections.concat(CA);}

var triangle=[];
for(var i=0;i<intersections.length;i++){
  var pt=intersections[i];
  if(ptIsInCircle(pt,A) && ptIsInCircle(pt,B) && ptIsInCircle(pt,C)){
    triangle.push(pt);
  }
}

drawMap();

if(triangle.length==3){
  ctx.beginPath();
  ctx.moveTo(triangle[0].x,triangle[0].y);
  ctx.lineTo(triangle[1].x,triangle[1].y);
  ctx.lineTo(triangle[2].x,triangle[2].y);
  ctx.closePath();
  ctx.stroke();
}

function drawMap(){

  // Draw the map of my room 400cm * 300cm
  ctx.fillStyle = "#ecf0f1"
  ctx.beginPath();
  ctx.rect(0, 0, 300, 400);
  ctx.closePath();
  ctx.fill();

  drawCircle(A);
  drawCircle(B);
  drawCircle(C);

}

function drawCircle(c){
  ctx.fillStyle = c.color;
  ctx.beginPath();
  ctx.arc(c.x,c.y,c.r, 0, Math.PI*2, true);
  ctx.closePath();
  ctx.fill();
}

// intersection points of 2 circles
function circleIntersections(c0,c1) {
  var x0=c0.x;
  var y0=c0.y;
  var r0=c0.r;
  var x1=c1.x;
  var y1=c1.y;
  var r1=c1.r;

  // calc circles' proximity
  var dx = x1 - x0;
  var dy = y1 - y0;
  var d = Math.sqrt((dy*dy) + (dx*dx));

  // return if circles do not intersect. 
  if (d > (r0 + r1)) { return; }
  // return if one circle is contained in the other 
  if (d < Math.abs(r0 - r1)) { return; }

  // calc the 2 intersection points
  var a = ((r0*r0) - (r1*r1) + (d*d)) / (2.0 * d) ;
  var x2 = x0 + (dx * a/d);
  var y2 = y0 + (dy * a/d);
  var h = Math.sqrt((r0*r0) - (a*a));
  var rx = -dy * (h/d);
  var ry = dx * (h/d);
  var xi = x2 + rx;
  var xi_prime = x2 - rx;
  var yi = y2 + ry;
  var yi_prime = y2 - ry;

  return([ {x:xi,y:yi}, {x:xi_prime,y:yi_prime} ]);
}

function ptIsInCircle(pt,circle){
  var dx=pt.x-circle.x;
  var dy=pt.y-circle.y;
  var r=circle.r+1; // allow circle 1px expansion for rounding
  return(dx*dx+dy*dy<=r*r);
}
#canvas{border:1px solid red; margin:0 auto; }
<canvas id="canvas" width=300 height=300></canvas>

0
On

If the centre of the circle is at (x1, y1) and radius is r then the equation of the circle is

(x - x1)^2 + (y - y1)^2 = r^2 (where ^ denotes exponentiation)

For three circles, you will get three equations. Now you have to solve pairwise the equations and get the coordinates.

Note that any two circle, if they intersect, will intersect at two points or meet at a single point. So you will need to define exactly which points of intersection will be used to draw the triangle.

Look at this answer here.