포인트가 모든 다각형 안에 있는지 알아보기위한 표준 광선 캐스팅 알고리즘을 알고 있습니다. 그러나 볼록 다각형으로 제한하면 더 빠른 방법이 있습니까?포인트가 N 시간보다 빠르게 2D convex 폴리곤 안에 있는지 확인하는 방법
2
A
답변
7
예, 이진 검색을 사용할 수 있습니다. 이 작업은 재귀 적으로 크기의 일부 (예 : 반)로 다각형을 자르고 현재 어느면에 있는지 확인하여 수행 할 수 있습니다. 예를 들어, 정점 0과 정점 n/2를 지나는 선에서 양수인지 음수인지 확인하여 시작할 수 있습니다. 3 개의 꼭지점을 가지면 나머지 두면을 테스트하고 해당 삼각형에 대한 테스트를 마칩니다.
function TestConvexPolygon(point, polygon)
if polygon.size == 3 then
return TestTriangle(point, polygon) // constant time
if (TestLine(point, polygon[0], polygon[polygon.size/2]) > 0)
return TestConvexPolygon(point, new polygon from polygon.size/2 to polygon.size-1 and 0)
else
return TestConvexPolygon(point, new polygon from 0 to polygon.size/2)
또 다른 방법을 생각하면 삼각형 팬으로 다각형을 볼 수 있다는 것입니다 시각화 :
여기 잘하면 쉽게이 이해할 수 있도록 몇 가지 의사 코드입니다. 그런 다음 포인트를 중앙 대 내부 중앙을 테스트하여 시작합니다. 그것은 팬으로부터 가능한 삼각형의 절반을 제거합니다. 삼각형 팬의 절반은 여전히 삼각형 팬이므로 삼각형이 팬에 남아있을 때까지이 작업을 반복적으로 수행 할 수 있습니다. 그러면 삼각형이 명시 적으로 테스트됩니다.
실제 구현에는 인덱스 저글링이 필요하지만 그렇지 않으면 쉽고 강력합니다.
0
답으로, 알고리즘은 재귀 적입니다. 각 단계에서 포인트가 될 수없는 다각형 부분을 잘라냅니다. 다음은 C++ 코드입니다.
#include "stdafx.h"
#include <vector>
#include <iostream>
struct vec2d {
double x, y;
vec2d(double _x, double _y) : x(_x), y(_y) {}
};
// Finds the cross product of the vectors: AB x BC
double crossProduct(vec2d pointA, vec2d pointB, vec2d pointC) {
vec2d vectorAB = vec2d(pointB.x - pointA.x, pointB.y - pointA.y);
vec2d vectorBC = vec2d(pointC.x - pointB.x, pointC.y - pointB.y);
return vectorAB.x * vectorBC.y - vectorBC.x * vectorAB.y;
}
// Finds area for the triangle ABC
double S(vec2d A, vec2d B, vec2d C) {
return crossProduct(A, B, C)/2;
}
bool isPointInsideTriangle(vec2d A, vec2d B, vec2d C, vec2d point)
{
return S(A, B, point) >= 0 && S(B, C, point) >= 0 && S(C, A, point) >= 0;
}
bool isPointAboveLine(vec2d A, vec2d B, vec2d point)
{
return S(A, B, point) >= 0;
}
// O(logN), works only for convex polygons
bool isPointInsidePolygon(std::vector<vec2d> polygon, vec2d point) {
if (polygon.size() == 3) {
return isPointInsideTriangle(polygon[0], polygon[1], polygon[2], point);
}
if (isPointAboveLine(polygon[0], polygon[polygon.size()/2], point)) {
std::vector<vec2d> polygonAbove(polygon.begin() + polygon.size()/2, polygon.end());
polygonAbove.emplace(polygonAbove.begin(), polygon[0]);
return isPointInsidePolygon(polygonAbove, point);
}
else {
std::vector<vec2d> polygonBelow(polygon.begin(), polygon.begin() + polygon.size()/2 + 1);
return isPointInsidePolygon(polygonBelow, point);
}
}
int main()
{
std::vector<vec2d> convexPolygon;
convexPolygon.push_back(vec2d(0, 2));
convexPolygon.push_back(vec2d(2, 0));
convexPolygon.push_back(vec2d(4, 1));
convexPolygon.push_back(vec2d(6, 3));
convexPolygon.push_back(vec2d(6, 4));
convexPolygon.push_back(vec2d(5, 6));
convexPolygon.push_back(vec2d(2, 6));
convexPolygon.push_back(vec2d(1, 4));
std::cout << isPointInsidePolygon(convexPolygon, vec2d(2, 5));
return 0;
}
관련 문제
- 1. 포인트가 삼각형 (2D) 안에 있는지 확인
- 2. 포인트가 타원 안에 있는지 확인하는 방법은 무엇입니까?
- 3. 모서리가 2D 폴리곤 안에 있는지 확인하는 모범 사례 (다각형의 꼭지점이 테이블에 있음)
- 4. 포인트가 폴리 토프 안에 있는지 확인
- 5. 어떤 특정 폴리곤 안에 있는지 확인하는 효율적인 방법
- 6. 포인트가 배열의 경계에 있는지 확인하는 방법
- 7. 주어진 포인트가 사각형 안에 있는지 알아내는 방법
- 8. 마커가 Google지도에서 다각형 안에 있는지 확인하는 방법
- 9. 포인트가 직사각형 안에 포함되어 있는지 확인하는 중 오류가 발생했습니다.
- 10. 포인트가 대각선 주위의 직사각형 안에 있는지 확인하는 방법은 무엇입니까?
- 11. 포인트가 지오 펜스 안에 있는지 확인하십시오.
- 12. 포인트가 Quad2DCurve에 있는지 여부를 확인하는 방법
- 13. 볼록한 다각형 안에 원이 있는지 확인하는 방법
- 14. 포인트가 볼록 쿼드 다각형 안에 있는지 또는 가장 위에 있는지 확인하는 가장 효율적인 방법
- 15. 포인트가 Raphael.js의 경로 요소 안에 있는지 확인합니다.
- 16. 포인트가 삼각형 (3D) 안에 있는지 확인하기위한 성능
- 17. 포인트가 자바 스크립트에서 폴리곤인지 확인하는 방법
- 18. 개체가 파이썬의 목록에 있는지 빠르게 확인하는 방법
- 19. 포인트가 내부에 있는지 확인하는 방법은 무엇입니까?
- 20. 3D 점이 2D 원 안에 있는지 확인합니다.
- 21. 마우스 클릭이 요소 안에 있는지 확인하는 방법
- 22. NSRect 안에 NSPoint가 있는지 확인하는 방법
- 23. POINT가 버튼 영역 안에 있는지 확인하는 방법
- 24. 마우스 커서가 컨트롤 안에 있는지 확인하는 방법
- 25. 위도와 경도가 타원 안에 있는지 확인하는 방법
- 26. 포인트가 빠르게 바뀝니다
- 27. 포인트가 도로에 있는지 확인
- 28. 포인트가 원호에 있는지 c를 확인하는 가장 좋은 방법 #
- 29. 포인트가 Emacs Lisp에서 들여 쓰기 지점에 있는지 확인하는 방법?
- 30. 2D 점이 사변형 안에 있는지 확인하십시오.
알고리즘에 대해 다소 혼란 스럽습니다. 정점 0이 가장 왼쪽 정점입니까? 정점은 중간 정점입니까? 일단 정점이 3 개라면 무엇을 의미합니까? 버텍스는 어떻게 선택합니까? –
실제로 어떤 꼭지점을 선택하든 중요하지 않은 것은 다각형의 절반 정도를 잘라낼 수 있다는 것입니다. 영역이 아닌 꼭지점의 개수 만 신경 써야합니다. 이 예제는 0에서 n-1까지의 번호가 매겨진 정점이 있다고 가정합니다. 이것은 꼭지점 중 하나의 꼭지점에서 다른 꼭지점까지의 선이 다각형을 두 개의 볼록한 다각형으로 자르기 때문에 일정한 시간에 둘 중 어느 것을 계속보아야하는지 결정할 수 있기 때문에 효과적입니다. – ltjax