2013-05-13 2 views
0

AutoCAD 용 .NET API를 사용하고 있는데, 점이 다각형 (직선 만) 내에 있는지 확인하기위한 알고리즘이 있습니다. .폴리 라인 내부의 점에 대한 알고리즘이 설명 할 수 없게 실패합니다. (AutoCAD)

동일한 51 개의 폴리곤에 대해 내 명령을 반복적으로 테스트했습니다. 99 % 완벽하게 작동합니다. 가끔씩 하나 이상의 폴리곤에서 실패 할 것이고 폴리 라인의 경계 상자 내부에 만드는 2000 포인트 이상을 false로 반환합니다. 나는 폴리 라인이 단순한 직사각형이고 모든 점들이 폴리 라인 내의 그리드에 분포되어 있으면 실패하는 것을 보았습니다. 이 경우 2000 년에 걸쳐 사실로 돌아 갔어야합니다. 1 점만으로 실패하지는 않을 것이며, 모두 실패 할 것입니다. 나는 그 점들이 내가 기대하는 곳에서 올바르게 만들어졌으며 다각형의 꼭지점이 내가 기대하는 곳에 있다는 것을 확인했다. 실패하면 마지막 점에 대한 마지막 각도 변수는 정확히 두 배의 PI입니다.

나는 멀티 스레딩을하고 있지 않습니다. 내가하고있는 유일한 '우스운'일은 Excel과 COM Interop입니다. 이 알고리즘을 사용하여 트랜잭션이 커밋 된 후에이 문제가 발생하며 모든 COM 개체를 정리하고 있습니다. 나는 COM Interop 부분없이 실패를 재현 할 수 없었지만 아직 충분히 증거가없는 것을 충분히 테스트하지 못했다고 생각합니다.

어떤 아이디어가 잘못되었을 수 있습니까?

bool IsInsidePolygon(Polyline polygon, Point3d pt) 
    { 
     int n = polygon.NumberOfVertices; 
     double angle = 0; 
     Point pt1, pt2; 

     for (int i = 0; i < n; i++) 
     { 
      pt1.X = polygon.GetPoint2dAt(i).X - pt.X; 
      pt1.Y = polygon.GetPoint2dAt(i).Y - pt.Y; 
      pt2.X = polygon.GetPoint2dAt((i + 1) % n).X - pt.X; 
      pt2.Y = polygon.GetPoint2dAt((i + 1) % n).Y - pt.Y; 
      angle += Angle2D(pt1.X, pt1.Y, pt2.X, pt2.Y); 
     } 

     if (Math.Abs(angle) < Math.PI) 
      return false; 
     else 
      return true; 
    } 

    public struct Point 
    { 
     public double X, Y; 
    }; 

    public static double Angle2D(double x1, double y1, double x2, double y2) 
    { 
     double dtheta, theta1, theta2; 

     theta1 = Math.Atan2(y1, x1); 
     theta2 = Math.Atan2(y2, x2); 
     dtheta = theta2 - theta1; 
     while (dtheta > Math.PI) 
      dtheta -= (Math.PI * 2); 
     while (dtheta < -Math.PI) 
      dtheta += (Math.PI * 2); 
     return (dtheta); 
    } 

답변

1

몇 가지 아이디어 : 포인트가를 Point3D의 폴리 라인 (같은 발언에 자리하고있는 곳

  • 부동 소수점 비교가 tolerence를 사용하여 수행 할 수 있고, 특히 경우에 종류의 임의의 결과가 발생할 수 있습니다

  • 어쩌면 폴리 라인의 마지막 점이 첫 번째 점과 동일한 위치에있을 수 있습니다.이 경우 각도를 계산할 수 없습니다 (아마도 이것이 이중 파이를 얻는 이유 일 수 있습니다). 마지막 점에 대한 값). 그런 다음 첫 번째 점과 마지막 점이 같음을 테스트해야합니다.

  • 나는 폴리 라인은 시계 반대 방향으로의 경우, 또는 알고리즘에 관계없이 작동 잘 모르겠어요

  • 당신이 영역에 폴리 라인을 변환 할 수 있습니다 (I 네 생각) 및 지역 포인트 봉쇄 방법에 의존

+0

, 나는 BREP API를 사용하여 영역로 변환 끝 않았다. –

1

다른 방법. 하나의 "임시"점을 다각형 외부에 놓으십시오 (최소 X와 Y를 찾고 X-1과 Y-1로 점을 만드십시오). 그런 다음 지점과 새로운 "임시"지점 사이에 선을 긋습니다. 이 선이 다각형을 가로 지르는 지 확인하십시오 - 폴리 라인을 사용하십시오 .IntersectWith. 교차점 수가 홀수 인 경우 - 내부에 포인트가있는 경우 교차점 수가 짝수 인 경우 - 내부 포인트가 아닙니다. 이것은 저에게 효과적이며 도움이되기를 바랍니다. 이것을 구현하는 데 문제가 있으면 예제 코드를 보내 줄 수 있습니다. 감사합니다, Dobriyan Benov

0

저는 Kean Walmsley의 코드를 사용하여 3d 라인을 2d 라인으로 변환했습니다. 그러나 사실 다음이하지 (항상)임을주의 :

Point2d pt = lwp.GetPoint2dAt(i); 
Point2d npt = new Point2d(lwp.GetPoint3dAt(i).X, lwp.GetPoint3dAt(i).Y); 

pt == npt; 

나는 3D 정점으로하는 폴리 라인에 그것을 사용하여 발생했습니다. 나는 npt을 사용하여 끝냈다.내가 알고리즘이 결함이 있음을 발견했습니다

http://through-the-interface.typepad.com/through_the_interface/2007/04/iterating_throu.html