通过3个圆圈的交叉绘制三角形

时间:2015-06-10 16:05:58

标签: javascript canvas draw

我想在3个圆的交点上绘制一个三角形。是否有任何函数或任何方法用JavaScript来解决这个问题?或者我需要执行一些数学计算以获得交点的精确位置并自己绘制三角形。

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 个答案:

答案 0 :(得分:3)

查找所有三个圆周上的交叉点

enter image description here

以下是如何操作:

定义3个圈子:

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

计算3个圆圈相互之间的交点(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);}

测试每个交叉点。保留所有3个圆圈中的任何交叉点。

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

在您的示例代码中,您将留下3个交叉点,这些交叉点也位于所有3个圆圈中。

但是如果圆圈位于其他位置,则可能会得到更少或超过3个交叉点。

使用上下文路径命令在3个已发现的点之间绘制折线。

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

示例代码和演示:

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>

答案 1 :(得分:0)

如果圆的中心位于(x1,y1)且半径为r,那么圆的方程是

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

对于三个圆圈,您将得到三个方程式。现在你必须成对地求解方程并得到坐标。

请注意,任何两个圆圈(如果它们相交)将在两个点相交或在一个点相交。因此,您需要准确定义将使用哪些交点来绘制三角形。

看看这个答案here