如何计算与任意两个圆 SVG 边缘的最小距离



我知道你通常会使用勾股定理来获得点之间的距离,但圆没有x1和x2。下面是一个示例。没有这些值,我怎么能计算距离?

circle {
fill: orange;
}
<svg transform="translate(0, 22)">
<circle class="point" cx="121.78235294117647" cy="13.200000000000001" r="3.1058823529411765" stroke="rgb(0, 0, 0)" stroke-width="1" data-values="[0.047]"></circle>
<circle class="point" cx="125.2764705882353" cy="30.28235294117647" r="3.1058823529411765" stroke="rgb(0, 0, 0)" stroke-width="1" data-values="[0.042]"></circle>
<circle class="point" cx="112.8529411764706" cy="30.67058823529412" r="3.1058823529411765" stroke="rgb(0, 0, 0)" stroke-width="1" data-values="[0.037]"></circle>
<circle class="point" cx="103.53529411764706" cy="32.22352941176471" r="3.1058823529411765" stroke="rgb(0, 0, 0)" stroke-width="1" data-values="[0.047]">
</svg>

两个圆之间的距离等于它们的中心距离减去它们的半径之和。

function distanceOfPoints(p0, p1) {
let dx = p0.x - p1.x;
let dy = p0.y - p1.y;
return Math.sqrt(dx*dx + dy*dy);
}
function distanceOfCircles(cen0, rad0, cen1, rad1) {
// if the circles intersect, our distance might be negative
return Math.max(0, distanceOfPoints(cen0, cen1) - rad0 - rad1);
}

在SVG中,cxcy是圆的中心(cen0cen1(,r是它们的半径(rad0rad1(。

要获得所有圆之间的最小距离,您可以遍历所有圆对,并在找到较低的圆时更新结果距离。

要计算两个圆之间的最小距离,首先取一个连接两个圆中心的向量并计算其长度。然后,减去两个圆的半径,因为两个圆的最近点必须远离圆心,正好在每个半径的距离内。

编辑:水平和垂直距离值不必为正数,因为它们无论如何都会在下一步中平方(感谢@Jan Schultke的建议(。

const circle1 = {
x: 13,      // horizontal center coordinate
y: 4,       // vertical center coordinate
radius: 5
};
const circle2 = {
x: 9,      // horizontal center coordinate
y: 24,       // vertical center coordinate
radius: 3
};
function minimumDistance(circle1, circle2) {
const horizontalDistance = circle1.x - circle2.x;
const verticalDistance = circle1.y - circle2.y;
const distanceBetweenCenter = Math.sqrt(horizontalDistance**2 + verticalDistance**2);  // pythagoras
return distanceBetweenCenter - circle1.radius - circle2.radius;
}
console.log(minimumDistance(circle1, circle2));

我昨天发现这个问题很有趣。

我的回答更像是基于@Spark Fountain和@Jan Schultke伟大答案的问题。这些概念是他们的。

下面的javascript基于每个svg圈都有自己的唯一ID。

// find our distance between two svg circles by id
function distance(circle1,circle2) {
// get our specified circles by id
let c1 = document.getElementById(circle1);
let c2 = document.getElementById(circle2);

// circle one attributes
c1 = {
x: c1.getAttribute("cx"),
y: c1.getAttribute("cy"),
r: c1.getAttribute("r")
};
		
// circle two attributes
c2 = {
x: c2.getAttribute("cx"),   
y: c2.getAttribute("cy"),
r: c2.getAttribute("r")
};

// lets work out each x and y axis distance
// not too worry about negative values
let x = c1.x - c2.x;
let y = c1.y - c2.y;

// lets work out the hypotenuse between x and y using pythagoras
// negative x or y values become absolute when squared
let distance = Math.sqrt(x**2 + y**2);

// now minus the radius of both circles from our distance
// to equal the distance from the edge of the circles
// math.max largest of zero or more incase circles overlap
distance = Math.max(0, distance - c1.r - c2.r);

console.log('distance between circle ' + circle1 + ' and ' + circle2 + ' is ' + distance);

// return the distance
return distance;

}
// check your console for distance
distance('4','3');
distance('1','2');
distance('3','1');
distance('2','3');
<svg transform="translate(0, 22)">
<circle id="1" class="point" cx="121.78235294117647" cy="13.200000000000001" r="3.1058823529411765" stroke="rgb(0, 0, 0)" stroke-width="1" data-values="[0.047]"></circle>
<circle id="2" class="point" cx="125.2764705882353" cy="30.28235294117647" r="3.1058823529411765" stroke="rgb(0, 0, 0)" stroke-width="1" data-values="[0.042]"></circle>
<circle id="3" class="point" cx="112.8529411764706" cy="30.67058823529412" r="3.1058823529411765" stroke="rgb(0, 0, 0)" stroke-width="1" data-values="[0.037]"></circle>
<circle id="4" class="point" cx="103.53529411764706" cy="32.22352941176471" r="3.1058823529411765" stroke="rgb(0, 0, 0)" stroke-width="1" data-values="[0.047]"></circle>
</svg>

最新更新