javascript - 通过 3 个圆的交点绘制三 Angular 形

标签 javascript canvas draw

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

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

最佳答案

找到所有三个圆圆周上的交点

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>

关于javascript - 通过 3 个圆的交点绘制三 Angular 形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30761641/

相关文章:

javascript - jQuery 播放音频。音频重复每个正确或错误的答案

javascript - 如何使用Jquery更新网站信息而不刷新

javascript - 在js Canvas 中返回精确的矢量分量

javafx canvas draw 与 java.awt.graphics2d draw 的比较

iphone - Objective C 在图像顶部绘制自由形状

java - 如何在java中为设计着色?

使用 Seaborn 在散点图上绘制线条

javascript - 将类作为泛型参数传递给 Typescript

javascript - MongoDB 对象类型/嵌套架构

javascript - 如何找到 Canvas 上两个向量之间的 Angular ?