明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 530|回复: 0

Jigging an AutoCAD circle from three points in arbitrary 3D space using .NET

[复制链接]
发表于 2011-5-17 13:38:38 | 显示全部楼层 |阅读模式

作者:kean

原文地址:http://through-the-interface.typepad.com/through_the_interface/2011/05/jigging-an-autocad-circle-from-three-points-in-arbitrary-3d-space-using-net.html

 

I suspect that many of you who have worked with point clouds will have come across this issue: the standard CIRCLE command in AutoCAD will create the circle on the plane of the active User Coordinate System (UCS), even when the circle is defined by three points on its circumference. This behaviour is probably fine for the majority of 2D drafting activities, but if you want to create circles from a point cloud – by selecting points from its perimeter using the Node object snap – then it’s less than ideal.

The code in today’s post implements a very simple jig that creates the circle in 3D, irrespective of the current UCS. It works especially well when picking points from point clouds, which is something I’ll be showing in a future post.

Here’s the C# code:

using Autodesk.AutoCAD.ApplicationServices;

using Autodesk.AutoCAD.DatabaseServices;

using Autodesk.AutoCAD.EditorInput;

using Autodesk.AutoCAD.Geometry;

using Autodesk.AutoCAD.Runtime;

 

namespace EntityJigging

{

  public class ThreePtCircleJig : EntityJig

  {

    Point3d _first, _second, _third;

 

    public ThreePtCircleJig(

      Point3d first, Point3d second

    )

      : base(new Circle())

    {

      _first = first;

      _second = second;

    }

 

    protected override SamplerStatus Sampler(

      JigPrompts jp

    )

    {

      // We acquire a single 3D point

 

      JigPromptPointOptions jo =

        new JigPromptPointOptions(

          "\nSelect third point"

        );

      jo.UserInputControls =

        UserInputControls.Accept3dCoordinates;

 

      PromptPointResult ppr = jp.AcquirePoint(jo);

 

      if (ppr.Status == PromptStatus.OK)

      {

        // Check whether it's basically unchanged

 

        if (

          _third.DistanceTo(ppr.Value) <

          Tolerance.Global.EqualPoint

        )

        {

          return SamplerStatus.NoChange;

        }

 

        // Otherwise just set the jig's state

 

        _third = ppr.Value;

        return SamplerStatus.OK;

      }

      return SamplerStatus.Cancel;

    }

 

    protected override bool Update()

    {

      // Create a temporary CircularArc3d by three points

      // and use it to create our Circle

 

      CircularArc3d ca =

        new CircularArc3d(_first, _second, _third);

 

      Circle cir = Entity as Circle;

      cir.Center = ca.Center;

      cir.Normal = ca.Normal;

      cir.Radius = ca.Radius;

 

      return true;

    }

 

    public Entity GetEntity()

    {

      return Entity;

    }

  }

 

  public class Commands

  {

    [CommandMethod("ADNPLUGINS", "3PCIR", CommandFlags.Modal)]

    public void CreateCircle()

    {

      Document doc =

        Autodesk.AutoCAD.ApplicationServices.

          Application.DocumentManager.MdiActiveDocument;

      Editor ed = doc.Editor;

 

      // Ask the user to select the first two points

      // outside the jig

 

      PromptPointOptions ppo =

        new PromptPointOptions(

          "\nSelect first point"

        );

      ppo.AllowNone = false;

 

      PromptPointResult ppr = ed.GetPoint(ppo);

 

      if (ppr.Status != PromptStatus.OK)

        return;

 

      Point3d first = ppr.Value;

 

      ppo.Message = "\nSelect second point";

 

      ppr = ed.GetPoint(ppo);

 

      if (ppr.Status != PromptStatus.OK)

        return;

 

      Point3d second = ppr.Value;

 

      // Pass the points into the jig

 

      ThreePtCircleJig cj =

        new ThreePtCircleJig(first, second);

 

      // Then execute it

 

      PromptResult pr = ed.Drag(cj);

 

      if (pr.Status != PromptStatus.OK)

        return;

 

      Transaction tr =

        doc.TransactionManager.StartTransaction();

      using (tr)

      {

        // Add our circle to the current space

 

        BlockTableRecord btr =

          (BlockTableRecord)tr.GetObject(

            doc.Database.CurrentSpaceId,

            OpenMode.ForWrite

          );

 

        Entity ent = cj.GetEntity();

        btr.AppendEntity(ent);

        tr.AddNewlyCreatedDBObject(ent, true);

 

        tr.Commit();

      }

    }

  }

} 

The 3PCIR command isn’t especially exciting, in action. If you’re interested, you can see it in my next YouTube video about integrating AutoCAD with Kinect (which I’ll post a link to before long).

"觉得好,就打赏"
还没有人打赏,支持一下

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-12-24 22:18 , Processed in 0.195723 second(s), 31 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表