2010-11-22 2 views
13

Даны две окружности:Область пересечения между двумя окружностями

  • C1 в (x1, y1) с radius1
  • C2 в (x2, y2) с radius2

Как рассчитать область их пересечения? Все стандартные математические функции (sin, cos и т. Д.) Доступны, конечно.

+0

http://mathworld.wolfram.com/Circle-CircleIntersection.html – 2010-11-22 16:50:57

+0

Спасибо. Я действительно знал ссылку перед публикацией. Я фактически искал конкретное уравнение, используя перечисленные переменные. – 2010-11-22 19:24:01

ответ

24

Хорошо, используя ссылку Вольфрама и реплику некорректной, чтобы посмотреть на уравнении 14, я вывел следующее решение Java с использованием переменного я, перечисленными и расстояния между центрами (которые тривиальное могут быть выведены из них):

Double r = radius1; 
Double R = radius2; 
Double d = distance; 
if(R < r){ 
    // swap 
    r = radius2; 
    R = radius1; 
} 
Double part1 = r*r*Math.acos((d*d + r*r - R*R)/(2*d*r)); 
Double part2 = R*R*Math.acos((d*d + R*R - r*r)/(2*d*R)); 
Double part3 = 0.5*Math.sqrt((-d+r+R)*(d+r-R)*(d-r+R)*(d+r+R)); 

Double intersectionArea = part1 + part2 - part3; 
10

Возможно, вы захотите проверить это analytical solution и применить формулу с вашими входными значениями.

Еще одна формулы дается here -

Area = r^2*(q - sin(q)) where q = 2*acos(c/2r), 
where c = distance between centers and r is the common radius. 
+0

+1 Первая ссылка имеет полный вывод формулы. Второй полезен, если радиусы окружностей одинаковы. – eaj 2010-11-22 17:09:20

+0

Спасибо за ссылки. Существует ли более общая формула, которая может быть получена, используя, в частности, переменные, которые я дал (например, не предполагая общий радиус)? – 2010-11-22 17:43:59

18

Вот функция JavaScript, которая делает именно то, что Крис после:

function areaOfIntersection(x0, y0, r0, x1, y1, r1) 
{ 
    var rr0 = r0 * r0; 
    var rr1 = r1 * r1; 
    var d = Math.sqrt((x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0)); 
    var phi = (Math.acos((rr0 + (d * d) - rr1)/(2 * r0 * d))) * 2; 
    var theta = (Math.acos((rr1 + (d * d) - rr0)/(2 * r1 * d))) * 2; 
    var area1 = 0.5 * theta * rr1 - 0.5 * rr1 * Math.sin(theta); 
    var area2 = 0.5 * phi * rr0 - 0.5 * rr0 * Math.sin(phi); 
    return area1 + area2; 
} 

Однако этот метод вернет NaN, если один круг полностью находится внутри другого, или они вообще не касаются друг друга. Немного другая версия, которая не подведет в этих условиях заключается в следующем:

function areaOfIntersection(x0, y0, r0, x1, y1, r1) 
{ 
    var rr0 = r0 * r0; 
    var rr1 = r1 * r1; 
    var d = Math.sqrt((x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0)); 

    // Circles do not overlap 
    if (d > r1 + r0) 
    { 
    return 0; 
    } 

    // Circle1 is completely inside circle0 
    else if (d <= Math.abs(r0 - r1) && r0 >= r1) 
    { 
    // Return area of circle1 
    return Math.PI * rr1; 
    } 

    // Circle0 is completely inside circle1 
    else if (d <= Math.abs(r0 - r1) && r0 < r1) 
    { 
    // Return area of circle0 
    return Math.PI * rr0; 
    } 

    // Circles partially overlap 
    else 
    { 
    var phi = (Math.acos((rr0 + (d * d) - rr1)/(2 * r0 * d))) * 2; 
    var theta = (Math.acos((rr1 + (d * d) - rr0)/(2 * r1 * d))) * 2; 
    var area1 = 0.5 * theta * rr1 - 0.5 * rr1 * Math.sin(theta); 
    var area2 = 0.5 * phi * rr0 - 0.5 * rr0 * Math.sin(phi); 

    // Return area of intersection 
    return area1 + area2; 
    } 
} 

Я написал эту функцию, прочитав информацию, найденную на Math Forum. Я нашел это более ясным, чем объяснение Wolfram MathWorld.

Смежные вопросы