2017-01-16 4 views
0

これは私が達成したいものです。どのようなスペースで2つの円に触れる最短の線を作るには?

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

+1

Math.atan()(つまり1つのパラメータのメソッド)を呼び出していますが、Math.atan2()(つまり2つのパラメータのメソッド)を呼び出そうとしていますか? – Welbog

+0

それはタイプミスで、私は 'Math.atan2()'も使用しました。ごめんなさい! – notalentgeek

答えて

2

あなたは、ほぼ正しいです。 @welbogが指摘したように、Math.atan2を使いたいとします。また、あなたはcosとsinをx/yに入れ替えました。最後に、角度を一度計算するだけで済みます。

ここでデモンストレーションです:

<!DOCTYPE html> 
 
<html> 
 

 
<head> 
 
    <script data-require="[email protected]" 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>

+0

申し訳ありませんが、問題は実際に私がcosとsinを反転させたためです。 'Math.atan()'も同様に 'Math.atan()'を使っていたので、 'Math.atan()'は型です。すべてあなたの答えをありがとう! – notalentgeek

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 
+0

Upvotedですが、JavaScriptには 'Math.Sqrt()'はありません。それは 'math.sqrt()'です。 –

+0

私はそのようなJavaScriptの特殊性を知らないので、一種の擬似コードを与えました。 – MBo

関連する問題