Math 在任何给定的空间里,如何使两个圆接触的最短线?

Math 在任何给定的空间里,如何使两个圆接触的最短线?,math,d3.js,trigonometry,Math,D3.js,Trigonometry,这就是我想要实现的目标 参数包括圆半径、x中心和y中心。生成行的函数是行(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 -

这就是我想要实现的目标

参数包括圆半径、x中心和y中心。生成行的函数是
行(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);
但看起来是这样的


你几乎是对的。正如@welbog所指出的,您希望使用。还有,你用你的罪和因换了x/y。最后,只需计算一次角度

下面是一个演示:


var svg=d3.select('body')
.append('svg')
.attr('width',500)
.attr('height',500);
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;
append('circle')
.attr('r',circleRadius1)
.attr('cx',circleX1)
.attr('cy',圆圈1)
.style('填充','无')
.style('stroke','steelblue');
append('circle')
.attr('r',circleRadius2)
.attr('cx',circleX2)
.attr('cy',圆圈2)
.style('填充','无')
.style('stroke','orange');
变量角度=数学atan2(circleY2-circleY1,circleX2-circleX1),
lineX1=circleX1+(circleRadius1*数学cos(角度)),
lineY1=circleY1+(circleRadius1*数学sin(角度)),
lineX2=circleX2-(circleRadius2*数学cos(角度)),
lineY2=circleY2-(circleRadius2*数学sin(角度));
append('行')
.attr('x1',lineX1)
.attr('y1',第y1行)
.attr('x2',lineX2)
.attr('y2',第2行)
.style('stroke','black')
设置超时(绘图,1000);
}

你几乎是对的。正如@welbog所指出的,您希望使用。还有,你用你的罪和因换了x/y。最后,只需计算一次角度

下面是一个演示:


var svg=d3.select('body')
.append('svg')
.attr('width',500)
.attr('height',500);
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;
append('circle')
.attr('r',circleRadius1)
.attr('cx',circleX1)
.attr('cy',圆圈1)
.style('填充','无')
.style('stroke','steelblue');
append('circle')
.attr('r',circleRadius2)
.attr('cx',circleX2)
.attr('cy',圆圈2)
.style('填充','无')
.style('stroke','orange');
变量角度=数学atan2(circleY2-circleY1,circleX2-circleX1),
lineX1=circleX1+(circleRadius1*数学cos(角度)),
lineY1=circleY1+(circleRadius1*数学sin(角度)),
lineX2=circleX2-(circleRadius2*数学cos(角度)),
lineY2=circleY2-(circleRadius2*数学sin(角度));
append('行')
.attr('x1',lineX1)
.attr('y1',第y1行)
.attr('x2',lineX2)
.attr('y2',第2行)
.style('stroke','black')
设置超时(绘图,1000);
}

不需要三角函数

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

不需要三角函数

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

您是否正在调用
Math.atan()
(即单参数方法)但打算调用
Math.atan2()
(即双参数方法)?这是一个输入错误,我也使用了
Math.atan2()
。很抱歉您是否正在调用
Math.atan()
(即单参数方法)但打算调用
Math.atan2()
(即双参数方法)?这是一个输入错误,我也使用了
Math.atan2()
。很抱歉哦。好吧,问题其实是因为我翻转了cos和sin。
Math.atan()
是一种类型,因为我也使用了
Math.atan2()
。总之,谢谢你的回答!哦。好吧,问题其实是因为我翻转了cos和sin。
Math.atan()
是一种类型,因为我也使用了
Math.atan2()
。总之,谢谢你的回答!向上投票,但JavaScript中没有
Math.Sqrt()
。这是
math.sqrt()
。我不知道JavaScript的这种特性,所以给出了一种伪代码。经过投票,但JavaScript中没有
math.sqrt()
。这是
math.sqrt()
。我不知道这种JavaScript特性,所以给出了一种伪代码。