2013-12-10 1 views
3

Here is an album of screenshots and corresponding descriptions which should storyboard the problem I'm about to describe. 이제.NET에서 AutoCAD의 수직/접선 물체 스냅 문제

, 내가 (C#을) 수학 용어 및 코드에서 내 문제를 설명하자

========================

주어 :

  • (0,0) 및 반경 기원의 중심 원 = 0.0364

  • 원의 상부에 평행하고 의해 분리 된 선분 작은 여백 (그래서 라인 segmen t는 원에 접하지 않는다). 여백의 크기는 중요하지 않습니다. 선 세그먼트의 길이는 원의 직경의 40 %입니다.

해결할 님

상기 라인의 시작점 시작점 및 원형 가장자리를 만지고 그 종료점과 수직 선분.

I의 AutoCAD의 객체 스냅 기능을 사용하여 내 원하는 결과를 수신하지 못하는 경우

========================. 내가 그리려하는 선분은 접선과 직각의 OSnap 모드를 사용하여 대각선으로 렌더링합니다. (다음 C# 1 실시 예 참조)

예 1

bigCircle.GetObjectSnapPoints(
    ObjectSnapModes.ModePerpendicular, 
    0, 
    tipTopCenterPoint1, 
    hatTopP3Dstart1, 
    fakematrix1, 
    p3dcolright, 
    icol1 
) 

...이 새로운 라인에 대각선 접음되고 렌더링. 나는 그것이 무엇에 부딪 치고 있는지 모른다. 그러나 그것이 내가 원하는 것이 아니다.

예 2 :이 함수 ...

bigCircle.GetObjectSnapPoints(
    ObjectSnapModes.ModeTangent, 
    0, 
    tipTopCenterPoint1, 
    hatTopP3Dstart1, 
    fakematrix1, 
    p3dcolright, 
    icol1 
); 

....는 새로운 광고가 대각선되고 밖으로 연장 렌더링한다. 선이 원에 접하는 점에 붙어 있다고 생각하지만, 원하는 것은 아닙니다.

내가 원하는 것은 다음과 같습니다. 내가 어떻게 할 수 있니?

desired result

+0

기본적으로 수직선과 원 사이의 교차점이 필요합니다. 수평선을 회전시켜 수직선을 얻을 수 있습니다. 그 라인을 자르거나 지우고 더 짧은 것을 그립니다 (정확한 길이로). –

+2

수평 세그먼트의 시작점은 수직 세그먼트의 시작점과 수직 세그먼트의 끝점의 x 값을 제공합니다. 이제 필요한 것은 종점의 Y 값입니다. 원의 방정식은 x의 함수로 원의 상단의 y 값을 제공합니다. – mbeckish

답변

2

오히려 주변의 사용자로이 작업을 수행하는 것 어떻게 프로그램을 시도보다, 나는 속도와 단순성에 대한 좋은 오래된 수학에 충실 것입니다. 찾고있는 낙하 거리를 Sagitta라고합니다. http://www.mathopenref.com/sagitta.html

편집 :

[CommandMethod("MathIsCool")] 
public void Draw_Method() 
{ 
    Database db = HostApplicationServices.WorkingDatabase; 
    Editor ed = AcadApplication.DocumentManager.MdiActiveDocument.Editor; 

    // Parameters (get from user prompt if desired) 
    var startP = new Point3d(0, 0, 0); 
    var r = 5.64; 
    var lineGap = 0.4; 
    var chordLen = r * 0.40; 

    try 
    { 
     using (Transaction acTrans = db.TransactionManager.StartOpenCloseTransaction()) 
     { 
      var bt = (BlockTable)acTrans.GetObject(db.BlockTableId, OpenMode.ForWrite); 
      var btr = (BlockTableRecord)acTrans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite); 

      // Create the circle 
      var circ = new Circle(startP, Vector3d.ZAxis, r); 
      btr.AppendEntity(circ); 
      acTrans.AddNewlyCreatedDBObject(circ, true); 

      // Create the horizontal line 
      var hPt1 = new Point3d(startP.X - (chordLen/2), startP.Y + (r + lineGap), 0); 
      var hPt2 = new Point3d(hPt1.X + chordLen, hPt1.Y, 0); 
      var hLine = new Line(hPt1, hPt2); 
      btr.AppendEntity(hLine); 
      acTrans.AddNewlyCreatedDBObject(hLine, true); 

      // Create the vertical line 
      // Arc sagitta = Sqrt(r*r-l*l); 
      var sag = Math.Sqrt(r * r - (chordLen/2) * (chordLen/2)); 
      var vPt2 = new Point3d(hPt1.X, startP.Y + sag, 0); 
      var vLine = new Line(hPt1, vPt2); 
      btr.AppendEntity(vLine); 
      acTrans.AddNewlyCreatedDBObject(vLine, true); 

      acTrans.Commit(); 
     } 
    } 
    catch (System.Exception ex) 
    { 
     Debug.WriteLine(ex.ToString()); 
     ed.WriteMessage(ex.ToString()); 
    } 
} 

당신은 여기에서 화살에 대한 자세한 내용을보실 수 있습니다 : 여기 그것이 그것을 동적으로 만들 코드에서 구현 될 수있는 방법이다 업데이트 60 % 증가를 기반으로 StartOpenCloseTransaction에 거래 100,000 회 이상의 반복 성능.

+0

고마워요! 내 지오메트리 기술은 매우 녹슬다. 나는 내가 "sagitta"를 얻어야한다는 것을 결코 알지 못했다. – sqyttles