2016-06-21 1 views
1

아치의 한계를 정하려고 노력하고 있습니다. 프로그래밍보다 형상 유형 문제가 더 많습니다. 그러나 여기서는 많은 성공을 거두지 못했습니다. 그것은 간다. 먼저 내가 C#에서 성취하고자하는 것을 상세히 설명하기 위해이 이미지를 보여 주자. enter image description hereG 코드에서 아치의 림을

위의 이미지에서 '가장 왼쪽'지점이 X 축에 있는지 (그리고 가장 오른쪽에있는 것이 가장 중요한지)를 결정하려고합니다. 그러나 단순함을 위해 '가장 왼쪽 지점'에 초점을 맞 춥니 다. X 축에서이 이미지 '왼쪽에서 가장 왼쪽'의 답은 5입니다. 참고 : 아치의 스윕 각도가 더 크더라도 답은 여전히 ​​5이지만 스윕 각도가 대답은 5보다 많을 것입니다. 텍스트 기반 G 코드 파일에서이 정보를 읽으며 여기에 G 코드 파일에 그려진 호의 샘플이 있습니다.

G1 X10. Y15. 
G3 X5. Y10. I10. J10. 

첫 줄 아치의 시작점을 나타내고, 마녀 이때 X 10이고 Y 15 번째 줄은 종점, 아치 중심점과 회전을 나타낸다. G3은 아치의 반 시계 방향 회전을 나타냅니다 (G2는 시계 방향 회전을 나타냄). X & Y는 엔드 포인트를 나타내며 I & J는 (X & Y) 아치 - 중심점 값입니다. 먼저 시도한 것은 아치가 180 *

else if (Gval == 3) 
{ 
    //Values read from G-Code File 
    double startX = Convert.ToDouble(oldXval); 
    double startY = Convert.ToDouble(oldYval); 
    double endX = Convert.ToDouble(Xval); 
    double endY = Convert.ToDouble(Yval); 
    double midX = Convert.ToDouble(Ival); 
    double midY = Convert.ToDouble(Jval); 

    //Get Start angle of Line 
    double startAngle = Math.Atan2(startY - midY, startX - midX); 
    startAngle = Math.Round(startAngle * (180.0/Math.PI), 5);//Radiants to Degrees 
    startAngle = ((startAngle % 360) + 360) % 360;//Normalise 

    //Get End angle of line 
    double EndAngle = Math.Atan2(endY - midY, endX - midX); 
    EndAngle = Math.Round(EndAngle * (180.0/Math.PI), 5);//Radiants to Degrees 
    EndAngle = ((EndAngle % 360) + 360) % 360;//Normalise 
    if (EndAngle == 0) EndAngle = 360; 

    //Get Raiduis 
    double raduis = Math.Round((Math.Sqrt(Math.Pow(Math.Abs(startX - midX), 2) + Math.Pow(Math.Abs(startY - midY), 2))),5); 

    double deltaY = (midY) - (startX); 
    double deltaX = (midX) - (startY); 
    double angleInDegrees = Math.Atan(deltaY/deltaX)*180/Math.PI; 

    if (startAngle <= 180 && EndAngle >= 180) 
    { 
    double LeftValue = midX - raduis; 
    } 
} 

코드 만 이상 : 나는 coordinates.Here의 다른 유형을 처리 할 때 제대로 작동 각도 계산을 얻이 수없는 것 때문에 주로 많은 성공없이 빨간색 선은 내가 끝내지 못한거야 코드의 샘플입니다 일부 특정 호에 대해 작동합니다. 나는 주위를 봤 발견 라인 교차로 라인 및 원형 교차로에 주로 주제를하지만 호를 교차 라인에 관한 특히 단 하나의 대답은 여기 일이 생각되고 있는지 확인 너무 모호 한 외에 Link

입니다 아마 Pathegorem의 일종에 의해 다르게 처리되어야 할 것이라고 생각되는 아치 유형이 있지만, 나는 그것을 어떻게 할 수 있는지에 관해서 시작하지 않았습니다.

여기 enter image description here

는 G-코드 : 그러나 여기의 이미지입니다

G1 X30. Y15. 
    G3 X25.4 Y11.96 I30. J10. 

그리고 나는 '가장 왼쪽'X 값이 내가 좋아하는 것 25.4

생각 만약 당신이이 방법으로 도울 수있는 방법이나 도서관을 알고 있다면. 알겠습니다. 고마워요.

답변

0

이것은 호의 X와 ​​Y 범위를 계산해야합니다. 성능 향상을 위해 많은 최적화가 이루어졌지만 이해하기 쉽습니다.

class Bounds 
    { 
     public double MinX, MinY, MaxX, MaxY; 
    } 

    Bounds GetArcBounds(float cx, float cy, float x1, float y1, float x2, float y2) 
    { 
     var a1 = GetAngle(y1 - cy, x1 - cx); 
     var a2 = GetAngle(y2 - cy, x2 - cx); 
     var r = (float)Math.Sqrt(Math.Pow(y1 - cy, 2) + Math.Pow(x1 - cx, 2)); 

     var bounds = new Bounds(); 
     bounds.MinX = double.MaxValue; 
     bounds.MinY = double.MaxValue; 
     bounds.MaxX = double.MinValue; 
     bounds.MaxY = double.MinValue; 

     ExpandBounds(bounds, x1, y1); 
     ExpandBounds(bounds, x2, y2); 

     if (IsAngleInArc(a1, a2, 0)) 
      ExpandBounds(bounds, cx + r, cy); 
     if (IsAngleInArc(a1, a2, (float)Math.PI * 0.5f)) 
      ExpandBounds(bounds, cx, cy + r); 
     if (IsAngleInArc(a1, a2, (float)Math.PI)) 
      ExpandBounds(bounds, cx - r, cy); 
     if (IsAngleInArc(a1, a2, (float)Math.PI * 1.5f)) 
      ExpandBounds(bounds, cx, cy - r); 

     return bounds; 
    } 

    float GetAngle(float dy, float dx) 
    { 
     var a = (float)Math.Atan2(dy, dx); 
     if (a < 0) a += (float)Math.PI * 2.0f; 
     return a; 
    } 

    void ExpandBounds(Bounds bounds, float x, float y) 
    { 
     if (x < bounds.MinX) bounds.MinX = x; 
     if (y < bounds.MinY) bounds.MinY = y; 
     if (x > bounds.MaxX) bounds.MaxX = x; 
     if (y > bounds.MaxY) bounds.MaxY = y; 
    } 

    bool IsAngleInArc(float a1, float a2, float test) 
    { 
     if (a2 < a1) 
     { 
      a2 += (float)Math.PI * 2.0f; 
     } 
     if (test < a1) 
     { 
      test += (float)Math.PI * 2.0f; 
     } 
     return a1 <= test && test <= a2; 
    } 

당신이 반 시계 방향과 시계 방향으로 모두를 할 수 있기를 원한다면

, 나는 내가 아직 테스트하지 않은 있지만 당신이 다음에 논리를 변경할 수 있으리라 생각합니다.

if (IsAngleInArc(a1, a2, 0)^clockwise) 
     ExpandBounds(bounds, cx + r, cy); 
    if (IsAngleInArc(a1, a2, (float)Math.PI * 0.5f)^clockwise) 
     ExpandBounds(bounds, cx, cy + r); 
    if (IsAngleInArc(a1, a2, (float)Math.PI)^clockwise) 
     ExpandBounds(bounds, cx - r, cy); 
    if (IsAngleInArc(a1, a2, (float)Math.PI * 1.5f)^clockwise) 
     ExpandBounds(bounds, cx, cy - r);