[algorithm] 폴리곤 팽창 / 팽창 (오프셋, 버퍼링) 알고리즘

다각형을 어떻게 “부 풀리게”합니까? 즉, 나는 이것과 비슷한 것을하고 싶다 :

대체 텍스트

요구 사항은 새로운 (팽창 된) 다각형의 가장자리 / 점이 모두 기존 (원래의) 다각형과 같은 일정한 거리에 있어야한다는 것입니다 (예제에서는 그렇지 않습니다. 지금은 잊어라;)).

내가 찾고있는 것에 대한 수학적 용어는 실제로 안쪽 / 바깥 쪽 다각형 오프셋 입니다. 이것을 지적하기 위해 발린 +1. 다른 이름은 다각형 버퍼링 입니다.

내 검색 결과 :

다음은 몇 가지 링크입니다.



답변

나는 잠시 내 자신의 언급 거라고 생각 다각형 클리핑 및 상쇄 라이브러리클리퍼를 .

Clipper 는 주로 다각형 클리핑 작업을 위해 설계 되었지만 다각형 오프셋도 수행합니다. 라이브러리는 Delphi, C ++ 및 C #으로 작성된 오픈 소스 프리웨어 입니다 . 무료 라이센스와 상용 응용 프로그램 모두에서 무료로 사용할 수 있는 매우 강화 된 Boost 라이센스가 있습니다.

다각형 오프셋은 사각형, 원형 ​​및 연귀의 세 가지 오프셋 스타일 중 하나를 사용하여 수행 할 수 있습니다.

다각형 오프셋 스타일


답변

찾고있는 다각형 을 계산 기하학에서 안쪽 / 바깥 쪽 오프셋 다각형 이라고 하며 직선 골격 과 밀접한 관련이 있습니다.

다음은 복잡한 다각형에 대한 여러 오프셋 다각형입니다.

그리고 이것은 다른 다각형의 직선 골격입니다.

다른 의견에서도 지적했듯이 다각형을 얼마나 “팽창 / 팽창”시킬 계획인지에 따라 출력에 다른 연결성을 가질 수 있습니다.

계산 관점에서 : 일단 직선 골격을 가지면 오프셋 다각형을 비교적 쉽게 구성 할 수 있어야합니다. 공개 소스 및 (비 상업용 무료) CGAL 라이브러리에는 이러한 구조를 구현하는 패키지가 있습니다. CGAL을 사용하여 오프셋 다각형을 계산하려면 이 코드 예제 를 참조하십시오 .

패키지 매뉴얼은 당신이 CGAL를 사용하지 않을 경우에도 이러한 구조를 구성하는 방법에 대한 시작점 당신에게 좋은를 제공하고, 수학적 정의와 속성을 사용하여 논문에 대한 참조를 포함한다 :

CGAL 매뉴얼 : 2D 직선 스켈레톤 및 다각형 오프셋


답변

이런 종류의 것들에 대해서는 보통 JTS를 사용 합니다. 데모 목적으로 JSTS (JavaScript port of JTS) 를 사용하는 이 jsFiddle 을 작성했습니다 . 필요한 좌표를 JSTS 좌표로 변환하면됩니다.

function vectorCoordinates2JTS (polygon) {
  var coordinates = [];
  for (var i = 0; i < polygon.length; i++) {
    coordinates.push(new jsts.geom.Coordinate(polygon[i].x, polygon[i].y));
  }
  return coordinates;
}

결과는 다음과 같습니다.

여기에 이미지 설명을 입력하십시오

추가 정보 : 나는 일반적으로지도에 그려진 다각형 (리플렛 또는 Google지도)에 반경으로 경계를 설정하기 위해이 유형의 팽창 / 수축 (내 목적에 약간 수정)을 사용합니다. (lat, lng) 쌍을 JSTS 좌표로 변환하면 다른 모든 항목이 동일합니다. 예:

여기에 이미지 설명을 입력하십시오


답변

당신이 원하는 것 같아요.

  • 정점에서 시작하여 인접한 가장자리를 따라 시계 반대 방향으로 향합니다.
  • 모서리를 기존 모서리 d의 “왼쪽” 에 떨어진 새 평행 모서리로 교체하십시오 .
  • 모든 모서리에 대해 반복하십시오.
  • 새로운 꼭지점을 얻기 위해 새로운 모서리의 교차점을 찾으십시오.
  • 교차 다각형이되었는지 감지하고 그에 대한 조치를 결정하십시오. 교차점에 새로운 정점을 추가하고 오래된 정점을 제거하십시오. 인접하지 않은 모든 모서리 쌍을 비교하여 두 쌍의 정점 사이에 교차점이 있는지 확인하는 것보다 이것을 감지하는 더 좋은 방법이 있는지 확실하지 않습니다.

결과 다각형은 정점에서 “충분한”기존 다각형으로부터 필요한 거리에 있습니다. 정점 근처 d에서 기존 다각형으로부터 떨어진 점 세트는 다각형이 아니므로 명시된 요구 사항을 충족시킬 수 없습니다.

이 알고리즘에 이름, 웹상의 예제 코드 또는 최종 최적화가 있는지는 모르지만 원하는 것을 설명한다고 생각합니다.


답변

GIS 세계에서는이 작업에 네거티브 버퍼링을 사용합니다 :
http://www-users.cs.umn.edu/~npramod/enc_pdf.pdf

JTS 라이브러리는 당신을 위해이 작업을 수행해야합니다. 버퍼 조작에 대한 문서를 참조하십시오. http://tsusiatsoftware.net/jts/javadoc/com/vividsolutions/jts/operation/buffer/package-summary.html

대략적인 개요는 개발자 안내서를 참조하십시오 :
http://www.vividsolutions.com/jts/bin/JTS%20Developer%20Guide.pdf


답변

각 선은 평면을 “내부”및 “개요”로 분할해야합니다. 일반적인 내부 제품 방법을 사용하여 찾을 수 있습니다.

모든 선을 일정 거리만큼 바깥쪽으로 이동하십시오.

모든 인접 선 쌍 (선 세그먼트가 아닌 선)을 고려하고 교차점을 찾으십시오. 이들은 새로운 정점입니다.

교차하는 부분을 제거하여 새 정점을 정리하십시오. -여기 몇 가지 사례가 있습니다

(a) 사례 1 :

 0--7  4--3
 |  |  |  |
 |  6--5  |
 |        |
 1--------2

하나만 소비하면 다음과 같은 결과를 얻습니다.

0----a----3
|    |    |
|    |    |
|    b    |
|         |
|         |
1---------2

7과 4가 겹칩니다.이 경우이 점과 그 사이의 모든 점이 제거됩니다.

(b) 사례 2

 0--7  4--3
 |  |  |  |
 |  6--5  |
 |        |
 1--------2

두 개를 소비하면 다음과 같은 결과를 얻습니다.

0----47----3
|    ||    |
|    ||    |
|    ||    |
|    56    |
|          |
|          |
|          |
1----------2

이 문제를 해결하려면 각 선분에 대해 후자의 선분과 겹치는 지 확인해야합니다.

(c) 사례 3

       4--3
 0--X9 |  |
 |  78 |  |
 |  6--5  |
 |        |
 1--------2

이것은 1로 소비됩니다. 이것은 사례 1의 경우보다 일반적인 경우입니다.

(d) 사례 4

case3과 동일하지만 2만큼 소비됩니다.

실제로 사례 4를 처리 할 수있는 경우 다른 모든 사례는 선이나 정점이 겹치는 특수한 경우입니다.

경우 4를 수행하기 위해 정점 스택을 유지합니다. 후행과 겹치는 선을 찾을 때 푸시하고 후자의 선을 가져올 때 팝합니다. -볼록 껍질에서하는 것과 같습니다.


답변

다음은 대체 솔루션입니다. 더 좋아하는지 확인하십시오.

  1. DO가 삼각 측량을 , 그것은 들로네가 될 필요가 없습니다 – 어떤 삼각 측량 할 것입니다.

  2. 각 삼각형을 부 풀리십시오-이것은 사소한 것입니다. 시계 반대 방향으로 삼각형을 저장하는 경우 선을 오른쪽으로 이동하고 교차로를 수행하십시오.

  3. 수정 된 Weiler-Atherton 클리핑 알고리즘을 사용하여 병합