겹치는 원의 결합 영역


107

나는 최근에 4 개의 원 (중간 점과 반지름)이 있고이 원들의 결합 면적을 계산해야하는 문제를 발견했습니다.

예시 이미지 :

두 개의 원의 경우 매우 쉽습니다.

삼각형 안에 있지 않은 각 원 영역의 비율을 계산 한 다음 삼각형의 영역을 계산할 수 있습니다.

그러나 두 개 이상의 원이있을 때 사용할 수있는 영리한 알고리즘이 있습니까?


15
이것은 정말 흥미로운 문제입니다. 고등학교 기하학 수업에서 이것을 본 기억이 있지만 해결책을 찾지 못했습니다. 여기에서 답을 찾을 수없는 경우 mathoverflow.net에 게시 하고 수학자에게 크랙을 제공하십시오. P
Charles Ma

25
때때로 실제 프로그래머는 실제 수학을 필요로합니다
fa.

1
이 질문에 대한 답을 찾아 보면 어떨까요? "우리는이 4 개 지역에 영업 담당자가 거주하고 있으며, 각 지역은이 4 개 반경의 지역에 서비스를 제공합니다. 우리가 담당하는 국가는 어느 정도입니까?" 영업 담당자 데이터베이스를 변경했다면 이것은 프로그래밍 질문이됩니다!
Chris Roberts

5
실제로 이것은 실제 프로그래머가 생각하고 싶어하는 종류의 문제입니다.
MAK

2
@zvolkov : 회로 기판은 정사각형과 원을 아래로 내리고 선택적으로 드래그하는 언어로 설명됩니다. "구리 면적 계산". (이는 에칭 시간을 계산하고 청소 아트 워크를 추가할지 여부를 알기 위해 필요할 수 있습니다.)
DigitalRoss

답변:


97

바깥 둘레의 모든 원 교차점을 찾으십시오 (예 : 다음 다이어그램의 B, D, F, H). 해당 원의 중심과 함께 연결하여 다각형을 형성하십시오. 원의 결합 영역은 다각형 영역 + 연속 교차점과 그 사이의 원 중심으로 정의 된 원 슬라이스 영역입니다. 또한 모든 구멍을 고려해야합니다.

원 겹침


17
중앙에 구멍이 생기면 어떻게 되나요?
John Gietzen 2009

3
전체에서 구멍에 대한 중앙 연결 다각형을 빼고 해당 다각형에 대한 원 슬라이스를 합계에 추가해야합니다.
Ants Aasma 2009

3
좋지만 모든 특수한 경우를 처리하기 위해 많은 구현 세부 사항이 필요하다고 생각합니다 (다른 하나의 내부 원, 교차점 없음, 구멍, 한 점 접촉 ...)
fa.

1
특별한 경우는 매우 쉽습니다. 다른 원 안에있는 원은 경계 교차점이 없기 때문에 버려집니다. 하나의 점 접촉은 사실상 거리가 0 인 두 교차점입니다. 연결이 끊긴 모양은 중심의 거리가 반지름의 합보다 작 으면 두 개의 원이 연결된 그래프에서 연결된 구성 요소 알고리즘을 통해 찾을 수 있습니다. 구멍은 면적이 가장 큰 것을 제외한 모든 다각형입니다. 경계 교차점은 엄격하게 원 안에 있지 않은 모든 교차점입니다.
Ants Aasma 2009

4
예, 그러나 구멍의 경계도 (작은) 호입니다. 여전히 잘 작동하려면 많은 코드가 필요하다고 생각합니다.
fa.

32

나는 영리한 알고리즘이 있다고 확신하지만, 그것을 찾아야하는 것을 저장하는 멍청한 알고리즘이있다.

  • 원 주위에 경계 상자를 두십시오.
  • 경계 상자 내에서 임의의 점을 생성합니다.
  • 임의의 점이 원 중 하나 안에 있는지 알아 내십시오.
  • 간단한 덧셈과 나눗셈으로 면적을 계산합니다 (proportion_of_points_inside * area_of_bounding_box).

물론 멍청하지만 :

  • 원하는만큼 정확한 답을 얻을 수 있으며 더 많은 점수를 생성 할 수 있습니다.
  • 내부 / 외부 구분을 계산할 수있는 모든 모양에 대해 작동합니다.
  • 모든 코어를 사용할 수 있도록 아름답게 병렬화됩니다.

2
이것은 작동하지만, 단순히 균일 한 샘플링을 기반으로하는 이와 같은 몬테카를로 방법은 일반적으로 최상의 수렴 률을 갖지 않습니다.
ShreevatsaR

2
죄송합니다. 귀하의 노력에 감사하고 귀하의 솔루션이 "실제적으로 사용 가능"하다고 생각하지만 귀하의 접근 방식이 매우 잘못되었다고 생각합니다. 이것은 무차별 대입이 아닌 수학으로 해결할 수있는 문제이며 해결해야합니다. 이와 같은 문제에 에너지와 핵심을 낭비하는 것은 낭비적이고 호화로운 일입니다.
mafu

5
당신 말이 맞아요, 저는 부끄럽지만 12,000 개의 코어를 가진 클러스터를 가지고 있습니다. 그리고 그 수 많은 프로세서로 확장 가능한 우아한 수학적 솔루션을 만드는 방법을 알 수 없습니다.
High Performance Mark

8
몬테카를로 (또는 임의의 임의) 접근 방식이 필요한 정확도를 제공하고 적절한 시간 내에 수행한다면 본질적으로 잘못된 것은 없습니다.
MAK

@mafutrct, 당신이 확실히 옳습니다. 그러나 수학에서 약간의 실수를하는 것은 쉽습니다. 이 솔루션은 정확성을 테스트하는 간단한 방법을 제공합니다.
리처드

18

Ants Aasma의 답변은 기본 아이디어를 제공했지만 좀 더 구체적으로 만들고 싶었습니다. 아래에있는 5 개의 원과 분해 된 방식을 살펴보세요.

예

  • 파란색 점은 원 중심입니다.
  • 빨간색 점은 원 경계 교차점입니다.
  • 내부흰색 인 빨간색 점 다른 원에 포함되지 않은 원 경계 교차점입니다 .

이 세 가지 유형의 점을 식별하는 것은 쉽습니다. 이제 노드가 파란색 점이고 내부가 흰색 인 빨간색 점인 그래프 데이터 구조를 구성하십시오. 모든 원에 대해 경계의 원 가운데 (파란색 점)와 교차점 (내부 흰색이 흰색 인 빨간색 점) 사이에 가장자리를 배치합니다.

이렇게하면 원 결합이 쌍으로 분리되고 원래 결합 (즉, 파티션)을 덮는 다각형 (파란색 음영)과 원형 원형 조각 (녹색 음영) 집합으로 분해됩니다. 여기의 각 조각은 면적을 계산하기 쉬운 것이기 때문에 조각의 면적을 합산하여 합집합 면적을 계산할 수 있습니다.


빨간색 / 흰색 점 집합을 상당히 쉽게 계산할 수 있다고 생각하지만 그래프 이론은 너무 크지 않습니다. 알고리즘 적으로 노드 + 가장자리 목록에서 계산 된 영역으로 어떻게 가져 오나요?
user999305

1
알고리즘은 다각형 대신 겹치지 않는 삼각형 세트를 사용하여 단순화 할 수 있습니다. 호 (녹색 영역)는 하나의 원에만 포함 된 영역입니다. 더 많은 원을 추가할수록 다각형의 크기를 확장합니다. (결국 다각형에 대해 이야기하고 있다는 것을 잊을 수 있습니다). 부울 속성을 만들고 영역도 계산하기가 더 쉽습니다. 속이 빈 빨간 점이 단색의 빨간 점이됨에 따라 세트에 삼각형을 더 추가하고 점점 더 교차하는 원에 의해 "먹이는"호를 조정합니다.
Steve

16

이전 솔루션과 다른 솔루션의 경우 쿼드 트리를 사용하여 임의 정밀도로 추정을 생성 할 수 있습니다.

사각형이 내부 또는 외부에 있는지 또는 모양과 교차하는지 알 수있는 경우 모든 모양 결합에도 적용됩니다.

각 셀에는 비어 있음, 전체, 부분 상태 중 하나가 있습니다.

알고리즘은 낮은 해상도 (예를 들어 비어있는 것으로 표시된 4 개의 셀)로 시작하는 쿼드 트리의 원을 "그리는"것으로 구성됩니다. 각 셀은 다음 중 하나입니다.

  • 하나 이상의 원 안에있는 셀을 가득 찬 것으로 표시하고
  • 모든 원 밖에서 셀을 비워두고
  • 그렇지 않으면 셀을 부분적으로 표시하십시오.

완료되면 면적 추정치를 계산할 수 있습니다. 전체 셀은 하한, 빈 셀은 상한, 부분 셀은 최대 면적 오류를 제공합니다.

오류가 너무 크면 정확한 정밀도를 얻을 때까지 부분 셀을 다듬습니다.

많은 특수한 경우를 처리해야하는 기하학적 방법보다 구현하기가 더 쉬울 것이라고 생각합니다.


3
생각 엔 이것은 몬테카를로 내부 / 외부 포인트 알고리즘보다 더 빠르게 수렴 할 것입니다.
Frank Krueger

이것은 구현하기가 훨씬 쉬워 보입니다. 확실히 최고의 무차별 대입 방법이 제안되었습니다. 감사!
Anton Hansson

여기서 brute force는 squeeze theorem
fa

이것이 구간 산술에서 사용하는 알고리즘의 종류입니다. en.wikipedia.org/wiki/Interval_arithmetic
rjmunro 2009

13

나는 두 개의 교차하는 원의 경우에 대한 접근 방식을 좋아합니다. 여기 더 복잡한 예제에 대해 동일한 접근 방식의 약간의 변형을 사용하는 방법이 있습니다.

더 많은 수의 반 겹치는 원에 대한 알고리즘을 일반화하는 데 더 나은 통찰력을 줄 수 있습니다.

여기서 차이점은 중심을 연결하는 것으로 시작한다는 것입니다 (원이 교차하는 곳이 아닌 원의 중심 사이에 정점이 있음). 이것이 더 잘 일반화되도록 해준다고 생각합니다.

(실제로 monte-carlo 방법이 가치가있을 수 있습니다)

대체 텍스트
(출처 : secretGeek.net )


1
이미지에서 제안한 다각형 분할을 수행하는 것이 아마도 매우 좋은 접근 방법이라고 생각합니다. 그것을 코딩하기 위해 해결해야 할 많은 세부 사항이 있습니다. 각각 체인의 마지막과 다음과 만 겹치는 20 개의 원 체인을 어떻게 처리할까요? 손으로 쉽게 알아낼 수 있지만 알고리즘은 무엇입니까?
PeterAllenWebb 2009

4

연속적인 답이 아닌 불연속적인 답을 원한다면 픽셀 페인팅 알고리즘과 비슷한 것을 할 수 있습니다.

그리드에 원을 그린 다음 대부분이 원 안에 포함 된 경우 그리드의 각 셀에 색상을 지정합니다 (즉, 영역의 50 % 이상이 원 중 하나 안에 있음). 전체 그리드 (그리드가 원으로 덮인 모든 영역에 걸쳐 있음)에 대해이 작업을 수행 한 다음 그리드에서 색상이 지정된 셀 수를 계산합니다.


3

흠, 매우 흥미로운 문제입니다. 내 접근 방식은 아마도 다음과 같은 것입니다.

  • 임의의 수의 원 사이의 교차 영역이 무엇인지 알아내는 방법을 찾으세요. 즉, 3 개의 원이 있다면 그 원 사이의 교차점이 무엇인지 알아낼 수 있어야합니다. "Monte-Carlo"방법은이를 근사화하는 좋은 방법입니다 ( http://local.wasp.uwa.edu.au/~pbourke/geometry/circlearea/ ).
  • 다른 더 큰 원에 완전히 포함 된 모든 원을 제거합니다 (두 원의 중심 사이의 반경과 거리 계수를보십시오). 필수라고 생각하지 않습니다.
  • 2 개의 원을 선택하고 (A와 B라고 부름) 다음 공식을 사용하여 총 면적을 계산합니다.

(이것은 원형이든 아니든 모든 모양에 해당됩니다)

area(A∪B) = area(A) + area(B) - area(A∩B)

Where A ∪ B는 A 유니온 B를 A ∩ B의미하고 A는 B와 교차 함을 의미합니다 (첫 번째 단계에서이 문제를 해결할 수 있습니다.

  • 이제 계속해서 원을 추가하고 원의 영역과 원 사이의 교차 영역의 합계 / 빼기로 추가 된 영역을 계속 계산합니다. 예를 들어 3 개의 원 (추가 원 C라고 부름)의 경우 다음 공식을 사용하여 면적을 계산합니다.

(위에서 A로 대체 된 것과 동일 A∪B)

area((A∪B)∪C) = area(A∪B) + area(C) - area((A∪B)∩C)

어디 area(A∪B)우리는 그냥 일을하고 area((A∪B)∩C)찾을 수 있습니다 :

area((A∪B)nC) = area((A∩C)∪(B∩C)) = area(A∩C) + area(A∩B) - area((A∩C)∩(B∩C)) = area(A∩C) + area(A∩B) - area(A∩B∩C)

위에서 다시 지역 (A∩B∩C)을 찾을 수 있습니다.

까다로운 부분은 마지막 단계입니다. 더 많은 원이 추가 될수록 더 복잡해집니다. 유한 합집합을 사용하여 교차 영역을 작업하는 데 확장이 있다고 믿습니다. 그렇지 않으면 재귀 적으로 작업 할 수 있습니다.

또한 Monte-Carlo를 사용하여 반복 영역을 근사화하는 것과 관련하여 임의의 수의 원의 교차점을 정확히 계산할 수있는 4 개의 원의 교차점으로 줄일 수 있다고 생각합니다 (이 작업을 수행하는 방법을 모릅니다 하나).

이 작업을 수행하는 더 좋은 방법이있을 것입니다. 추가 된 각 추가 원에 대해 복잡성이 상당히 증가합니다 (아마도 기하 급수적으로 증가하지만 확실하지 않습니다).


서식은 어떻습니까? 또한 교차와 결합에 n과 u를 사용하는 것에 대해 미안합니다. 아마도 더 나은 방법이있을 것입니다.
Justin

1
일부 유니 코드 통합 (∪) 및 교차 (∩) 기호가 추가되었습니다. 바라건대 그들은 작동합니다.
Spoike 2009

3

나는 더 큰 밝은 별이 희미한 별을 가릴 수있는 조밀 한 필드의 실제 디스크 영역에서 실제 별 수를 추정하려고 시도하면서 겹치는 별 필드를 시뮬레이션하는 문제를 연구 해 왔습니다. 저도 엄격한 공식 분석을 통해이를 수행 할 수 있기를 바랐지만 작업에 대한 알고리즘을 찾을 수 없었습니다. 파란색 배경에 별 필드를 녹색 디스크로 생성하여 지름이 확률 알고리즘에 의해 결정되었습니다. 간단한 루틴을 통해 겹치는 부분이 있는지 확인하기 위해 페어링 할 수 있습니다 (별표 쌍이 노란색으로 바뀜). 그런 다음 색상의 픽셀 수는 이론적 영역과 비교할 관찰 영역을 생성합니다. 그러면 실제 개수에 대한 확률 곡선이 생성됩니다. 무차별 대입 일 수도 있지만 괜찮은 것 같습니다. (출처 : 2from.com )


2

다음은 실제로 구현하기 쉽고 임의의 작은 오류를 생성하도록 조정할 수있는 알고리즘입니다.

  1. 같은 지점을 중심으로하는 정다각형으로 각 원을 근사화합니다.
  2. 근사 된 원의 합집합 인 다각형을 계산합니다.
  3. 병합 된 다각형의 면적 계산

2 단계와 3 단계는 계산 기하학에서 찾기 쉬운 표준 알고리즘을 사용하여 수행 할 수 있습니다.

분명히 각 근사 다각형에 더 많은면을 사용할수록 정확한 답에 더 가깝습니다. 내접 다각형과 외접 다각형을 사용하여 정확한 답에 대한 경계를 얻을 수 있습니다.


2

전력 다이어그램이라고하는 것을 사용하여이 문제에 대한 효율적인 솔루션이 있습니다. 이것은 정말 무거운 수학이며 내가 직접 다루고 싶지 않은 것이 아닙니다. "쉬운"솔루션을 위해 라인 스윕 알고리즘을 찾아보십시오. 여기서 기본 원칙은 그림을 스트립으로 나누는 것입니다. 여기서 각 스트립의 면적을 계산하는 것은 비교적 쉽습니다.

따라서 문지르지 않은 모든 원을 포함하는 그림에서 원의 상단, 원의 하단 또는 두 원의 교차점 인 각 위치에 수평선을 그립니다. 이 스트립 내부에서 계산해야하는 모든 영역은 동일하게 보입니다. 두면이 원형 세그먼트로 대체 된 "사다리꼴"입니다. 따라서 이러한 모양을 계산하는 방법을 알아낼 수 있다면 모든 개별 모양에 대해 수행하고 함께 추가하면됩니다. 이 순진한 접근 방식의 복잡성은 O (N ^ 3)이며, 여기서 N은 그림에서 원의 수입니다. 데이터 구조를 영리하게 사용하면이 라인 스윕 방법을 O (N ^ 2 * log (N))로 개선 할 수 있지만 실제로 필요한 경우가 아니면 문제가되지 않을 것입니다.



1

해결하려는 문제에 따라 상한과 하한을 얻는 데 충분할 수 있습니다. 상한은 간단합니다. 모든 원의 합입니다. 하한의 경우 원이 겹치지 않도록 단일 반경을 선택할 수 있습니다. 겹치지 않도록 각 원에 대해 가장 큰 반경 (실제 반경까지)을 찾는 것이 좋습니다. 완전히 겹친 원을 제거하는 것도 매우 간단해야합니다 (이러한 모든 원은 | P_a-P_b | <= r_a를 충족 함). 여기서 P_a는 원 A의 중심, P_b는 원 B의 중심, r_a는 A의 반경입니다. ) 그리고 이것은 상한과 하한 모두를 향상시킵니다. 모든 원의 합계 대신 임의의 쌍에 쌍 공식을 사용하면 더 나은 상한을 얻을 수도 있습니다. "최고"를 선택하는 좋은 방법이있을 수 있습니다.

상한과 하한이 주어지면 Monte-carlo 접근 방식을 더 잘 조정할 수 있지만 구체적인 것은 생각 나지 않습니다. 또 다른 옵션 (응용 프로그램에 따라 다름)은 원을 래스터 화하고 픽셀을 계산하는 것입니다. 기본적으로 고정 분포를 사용하는 Monte-carlo 접근 방식입니다.


0

이것은 Green 's Theorem을 사용하여 n ^ 2log (n)의 복잡성을 사용하여 풀 수 있습니다 . Green 's Theorem에 익숙하지 않고 더 알고 싶다면 여기 칸 아카데미 의 비디오메모가 있습니다. 그러나 우리 문제를 위해 내 설명으로 충분할 것이라고 생각합니다.

이미지를 게시 할 수 없어서 사진 링크에 대해 죄송합니다. (평판 포인트 부족)

그린 정리의 일반 방정식

나는 넣으면 LM은 그와 같은

질환

RHS는 단순히 영역 R 의 영역이며 닫힌 적분 또는 LHS를 풀면 얻을 수 있습니다. 이것이 바로 우리가하려는 일입니다.

모든 결합은 서로 교차하는 원의 분리 된 집합으로 나눌 수 있습니다.

따라서 반 시계 방향으로 경로를 따라 적분하면 영역 의 면적 이 제공되고 시계 방향으로 적분하면 면적의 음수가 됩니다. 그래서

AreaOfUnion = (시계 반대 방향으로 빨간색 호를 따라 적분 + 시계 방향으로 파란색 호를 따라 적분)

그러나 멋진 트릭은 각 원에 대해 다른 원 안에없는 호를 통합하면 필요한 영역을 얻습니다. 즉, 모든 빨간색 호를 따라 시계 반대 방향으로 통합하고 시계 방향을 따라 모든 파란색 호를 따라 통합합니다. 작업 완료 !!!

원이 다른 원과 교차하지 않는 경우도 처리됩니다.

다음은 내 C ++ 코드에 대한 GitHub 링크입니다.


-1

픽셀 페인팅 방식 (@Loadmaster에서 제안한대로)은 다양한 방식에서 수학적 솔루션보다 우수합니다.

  1. 구현이 훨씬 간단합니다. 위의 문제는 이 JSFiddle 솔루션이 보여주는 것처럼 100 줄 미만의 코드로 해결할 수 있습니다 (주로 개념적으로 훨씬 간단하고 처리 할 가장자리 케이스 나 예외가 없기 때문입니다).
  2. 보다 일반적인 문제에 쉽게 적응합니다. 원, 타원, 스플라인, 다각형 등 2D 드로잉 라이브러리 (즉, "모두!")로 렌더링 할 수있는 한 형태에 관계없이 모든 모양에서 작동합니다. 비트 맵 이미지도 마찬가지입니다.
  3. 픽셀 페인팅 솔루션의 복잡성은 수학적 솔루션의 ~ O [n * n]에 비해 ~ O [n]입니다. 이것은 모양의 수가 증가할수록 더 잘 수행 될 것임을 의미합니다.
  4. 성능에 대해 말하면 대부분의 최신 2D 라이브러리 (예 : HTML5의 캔버스)가 렌더링 작업을 그래픽 가속기로 오프로드하기 때문에 종종 하드웨어 가속을 무료로받을 수 있습니다.

픽셀 페인팅의 한 가지 단점은 솔루션의 유한 한 정확도입니다. 그러나 상황에 따라 더 크거나 더 작은 캔버스로 간단히 렌더링하여 조정할 수 있습니다. 참고도, 그 안티 앨리어싱 코드를 렌더링 2D에서 (보통 기본적으로 켜져)는보다 좋은 픽셀 수준 얻을 것 정도. 예를 들어, 100x100 그림을 같은 크기의 캔버스로 렌더링하면 1 / (100 x 100 x 255) = .000039 % 정도의 정확도를 얻을 수 있습니다. 가장 까다로운 문제를 제외한 모든 문제를 해결합니다.

<p>Area computation of arbitrary figures as done thru pixel-painting, in which a complex shape is drawn into an HTML5 canvas and the area determined by comparing the number of white pixels found in the resulting bitmap.  See javascript source for details.</p>

<canvas id="canvas" width="80" height="100"></canvas>

<p>Area = <span id="result"></span></p>
// Get HTML canvas element (and context) to draw into
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');

// Lil' circle drawing utility
function circle(x,y,r) {
  ctx.beginPath();
  ctx.arc(x, y, r, 0, Math.PI*2);
  ctx.fill();
}

// Clear canvas (to black)
ctx.fillStyle = 'black';
ctx.fillRect(0, 0, canvas.width, canvas.height);

// Fill shape (in white)
ctx.fillStyle = 'white';
circle(40, 50, 40);
circle(40, 10, 10);
circle(25, 15, 12);
circle(35, 90, 10);

// Get bitmap data
var id = ctx.getImageData(0, 0, canvas.width, canvas.height);
var pixels = id.data; // Flat array of RGBA bytes

// Determine area by counting the white pixels
for (var i = 0, area = 0; i < pixels.length; i += 4) {
  area += pixels[i]; // Red channel (same as green and blue channels)
}

// Normalize by the max white value of 255
area /= 255;

// Output result
document.getElementById('result').innerHTML = area.toFixed(2);

이 솔루션은 원의 영역에 대한 수학적 계산을 설명하지 못합니다. OP 질문의 요점을 놓친다. 매우 자주 렌더링 지오메트리는 기하학적 모양을 다룰 때 절반에 불과합니다
Steve
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.