如何在任何给定的空间内使最短的线条触及两个圆圈?

时间:2017-01-16 19:48:54

标签: math d3.js trigonometry

这是我想要实现的目标。

enter image description here

参数是圆半径,x - 中心和y - 中心。制作行的功能是line(x1, y1, x2, y2)

以下是我现在使用JavaScript的内容。

var lineX1 = circleX1 + (circleRadius1 * Math.sin(Math.atan2(circleY2 - circleY1, circleX2 - circleX1)));
var lineY1 = circleY1 + (circleRadius1 * Math.cos(Math.atan2(circleY2 - circleY1, circleX2 - circleX1)));
var lineX2 = circleX2 - (circleRadius2 * Math.sin(Math.atan2(circleY1 - circleY2, circleX1 - circleX2)));
var lineY2 = circleY2 - (circleRadius2 * Math.cos(Math.atan2(circleY1 - circleY2, circleX1 - circleX2)));

line(lineX1, lineY1, lineX2, lineY2);

但它看起来像这样。

enter image description here

2 个答案:

答案 0 :(得分:3)

三角函数不需要。

center difference vector
dx = cx2 - cx1
dy = cy2 - cy1
len = Math.Sqrt(dx*dx + dy*dy)
normalized
udx = dx / len
udy = dy / len

line ends
lx1 = cx1 + udx * r1
ly1 = cy1 + udy * r1
lx2 = cx2 - udx * r2
ly2 = cy2 - udy * r2

答案 1 :(得分:2)

你几乎是对的。正如@welbog指出的那样,你想使用Math.atan2。另外,你用你的cos和sin换了x / y。最后,您只需要计算一次角度。

这是一个示范:



<!DOCTYPE html>
<html>

<head>
  <script data-require="d3@4.0.0" data-semver="4.0.0" src="https://d3js.org/d3.v4.min.js"></script>
</head>

<body>
  <script>
    var svg = d3.select('body')
      .append('svg')
      .attr('width', 500)
      .attr('height', 500);
      
    draw();

    function draw() {
      
      svg.selectAll("*").remove();

      var circleRadius1 = Math.random() * 100,
        circleRadius2 = Math.random() * 100,
        circleX1 = Math.random() * 500,
        circleY1 = Math.random() * 500,
        circleX2 = Math.random() * 500,
        circleY2 = Math.random() * 500;
        
      svg.append('circle')
        .attr('r', circleRadius1)
        .attr('cx', circleX1)
        .attr('cy', circleY1)
        .style('fill', 'none')
        .style('stroke', 'steelblue');
        
      svg.append('circle')
        .attr('r', circleRadius2)
        .attr('cx', circleX2)
        .attr('cy', circleY2)
        .style('fill', 'none')
        .style('stroke', 'orange');
        
      var angle = Math.atan2(circleY2 - circleY1, circleX2 - circleX1),
          lineX1 = circleX1 + (circleRadius1 * Math.cos(angle)),
          lineY1 = circleY1 + (circleRadius1 * Math.sin(angle)),
          lineX2 = circleX2 - (circleRadius2 * Math.cos(angle)),
          lineY2 = circleY2 - (circleRadius2 * Math.sin(angle));
          
      svg.append('line')
        .attr('x1', lineX1)
        .attr('y1', lineY1)
        .attr('x2', lineX2)
        .attr('y2', lineY2)
        .style('stroke','black')
        
      setTimeout(draw, 1000);

    }
  </script>
</body>

</html>
&#13;
&#13;
&#13;