乐筑天下

搜索
欢迎各位开发者和用户入驻本平台 尊重版权,从我做起,拒绝盗版,拒绝倒卖 签到、发布资源、邀请好友注册,可以获得银币 请注意保管好自己的密码,避免账户资金被盗
查看: 148|回复: 6

优化多段线的倒角

[复制链接]

72

主题

2726

帖子

9

银币

社区元老

Rank: 75Rank: 75Rank: 75

铜币
3014
发表于 2010-6-9 20:28:00 | 显示全部楼层 |阅读模式
在QQ群为风吹桥动改写优化多段线的倒角程序,
原代码使用DB库的曲线并用纯数学计算方式
  1.         ///
  2.         /// 通过一个顶点将多义线倒圆角,本程序不支持多义线起点和终点处倒圆角
  3.         ///
  4.         /// 多义线对象
  5.         /// 顶点索引号
  6.         /// 圆弧半径
  7.         public static void FilletatVertex(Polyline polyline, int vertexIndex, double radius)
  8.         {
  9.             Database db = HostApplicationServices.WorkingDatabase;//获取数据库
  10.             Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;//获取editor对象
  11.             using (Transaction trans = db.TransactionManager.StartTransaction())//开始事务     
  12.             {
  13.                 try
  14.                 {
  15.                     //判断顶点索引号是否属于多义线;
  16.                     if (vertexIndex = polyline.NumberOfVertices)
  17.                     {
  18.                         ed.WriteMessage("\n顶点无效。");
  19.                         return;
  20.                     }
  21.                     else if ((polyline.GetBulgeAt(vertexIndex - 1) != 0) && (polyline.GetBulgeAt(vertexIndex) != 0))
  22.                     {
  23.                         ed.WriteMessage("\n顶点两侧不是直线。");
  24.                         return;
  25.                     }
  26.                     else
  27.                     {
  28.                         Point2d pnt = polyline.GetPoint2dAt(vertexIndex);
  29.                         Vector2d vec1 = polyline.GetPoint2dAt(vertexIndex - 1) - pnt;//由顶点与前一个顶点组成的向量
  30.                         Vector2d vec2 = polyline.GetPoint2dAt(vertexIndex + 1) - pnt;//由顶点与后一个顶点组成的向量
  31.                         double angle = vec1.GetAngleTo(vec2);//获得角点两侧线段间的角度变化
  32.                         ed.WriteMessage(angle.ToString());
  33.                         ed.WriteMessage("\n" + vec1.Length.ToString());
  34.                         ed.WriteMessage("\n" + (radius / Math.Tan(angle / 2)).ToString());
  35.                         ed.WriteMessage("\n" + vec2.Length.ToString());
  36.                         ed.WriteMessage("\n" + (radius / Math.Tan(angle / 2)).ToString());
  37.                         if ((vec1.Length
  38.         /// 为优化多段线倒角
  39.         ///
  40.         /// 优化多段线
  41.         /// 顶点索引号
  42.         /// 倒角半径
  43.         /// 倒角类型
  44.         public static void ChamferAt(this Polyline polyline, int index, double radius, bool isFillet)
  45.         {
  46.             if (index  polyline.NumberOfVertices - 2)
  47.                 throw new System.Exception("错误的索引号");
  48.             if (polyline.GetSegmentType(index - 1) != SegmentType.Line || polyline.GetSegmentType(index) != SegmentType.Line)
  49.                 throw new System.Exception("非直线段不能倒角");
  50.             //获取当前索引号的前后两段直线,并组合为Ge复合曲线
  51.             Curve3d[] c3ds =
  52.                 new Curve3d[]
  53.                     {
  54.                         polyline.GetLineSegmentAt(index - 1),
  55.                         polyline.GetLineSegmentAt(index)
  56.                     };
  57.             var cc3d = new CompositeCurve3d(c3ds);
  58.             //试倒直角
  59.             //子曲线的个数有三种情况:
  60.             //1、=3时倒角方向正确
  61.             //2、=2时倒角方向相反
  62.             //3、=0或为直线时失败
  63.             c3ds =
  64.                 cc3d.GetTrimmedOffset
  65.                 (
  66.                     radius,
  67.                     Vector3d.ZAxis,
  68.                     OffsetCurveExtensionType.Chamfer
  69.                 );
  70.             if (c3ds.Length > 0 && c3ds[0] is CompositeCurve3d)
  71.             {
  72.                     var newcc3d = c3ds[0] as CompositeCurve3d;
  73.                     c3ds = newcc3d.GetCurves();
  74.                     if (c3ds.Length == 3)
  75.                     {
  76.                         c3ds =
  77.                             cc3d.GetTrimmedOffset
  78.                             (
  79.                                 -radius,
  80.                                 Vector3d.ZAxis,
  81.                                 OffsetCurveExtensionType.Chamfer
  82.                             );
  83.                         if (c3ds.Length == 0 || c3ds[0] is LineSegment3d)
  84.                         {
  85.                             throw new System.Exception("倒角半径过大");
  86.                         }
  87.                     }
  88.                     else if (c3ds.Length == 2)
  89.                     {
  90.                         radius = -radius;
  91.                     }
  92.             }
  93.             else
  94.             {
  95.                 throw new System.Exception("倒角半径过大");
  96.             }
  97.             //GetTrimmedOffset会生成倒角+偏移,故先反方向倒角,再倒回
  98.             c3ds =
  99.                 cc3d.GetTrimmedOffset
  100.                 (
  101.                     -radius,
  102.                     Vector3d.ZAxis,
  103.                     OffsetCurveExtensionType.Extend
  104.                 );
  105.             OffsetCurveExtensionType type =
  106.                 isFillet ?
  107.                 OffsetCurveExtensionType.Fillet : OffsetCurveExtensionType.Chamfer;
  108.             c3ds =
  109.                 c3ds[0].GetTrimmedOffset
  110.                 (
  111.                     radius,
  112.                     Vector3d.ZAxis,
  113.                     type
  114.                 );
  115.             //将结果Ge曲线转为Db曲线,并将相关的数值反映到原曲线
  116.             Polyline plTemp = c3ds[0].ToCurve() as Polyline;
  117.             polyline.RemoveVertexAt(index);
  118.             polyline.AddVertexAt(index, plTemp.GetPoint2dAt(1), plTemp.GetBulgeAt(1), 0, 0);
  119.             polyline.AddVertexAt(index + 1, plTemp.GetPoint2dAt(2), 0, 0, 0);
  120.         }
  121.         [CommandMethod("CTest")]
  122.         public void test()
  123.         {
  124.             var db = HostApplicationServices.WorkingDatabase;
  125.             var doc = Application.DocumentManager.GetDocument(db);
  126.             var ed = doc.Editor;
  127.             var resEnt = ed.GetEntity("\n请选择优化多段线:");
  128.             var resInt = ed.GetInteger("\n请输入索引号:");
  129.             bool isFillet = false;
  130.             PromptDoubleOptions opt = new PromptDoubleOptions("\n请输入倒角半径:");
  131.             opt.Keywords.Add("F");
  132.             var resDbl = ed.GetDouble(opt);
  133.             if (resDbl.Status == PromptStatus.Keyword)
  134.             {
  135.                 isFillet = true;
  136.                 resDbl = ed.GetDouble(opt);
  137.             }
  138.             using (Transaction tr = db.TransactionManager.StartTransaction())
  139.             {
  140.                 Polyline pl = resEnt.ObjectId.GetObject(OpenMode.ForWrite) as Polyline;
  141.                 ChamferAt(pl, resInt.Value, resDbl.Value, isFillet);
  142.                 tr.Commit();
  143.             }
  144.         }

命令行的输入:
命令: ctest
请选择优化多段线:
请输入索引号: 3
请输入倒角半径 [F]: f
请输入倒角半径 [F]: 5
命令: ctest
请选择优化多段线:
请输入索引号: 2
请输入倒角半径 [F]: 5

倒角效果:

mj3bwblwdvx.jpg

mj3bwblwdvx.jpg


回复

使用道具 举报

0

主题

1

帖子

1

银币

初来乍到

Rank: 1

铜币
1
发表于 2020-7-13 11:12:00 | 显示全部楼层
顶飞狐版主呀,学习了!
回复

使用道具 举报

17

主题

69

帖子

2

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
137
发表于 2010-6-9 20:34:00 | 显示全部楼层
楼主强大,顶
回复

使用道具 举报

3

主题

20

帖子

4

银币

初来乍到

Rank: 1

铜币
32
发表于 2010-6-9 20:36:00 | 显示全部楼层
修正试倒角时的Bug,2楼代码已更改
回复

使用道具 举报

3

主题

5

帖子

1

银币

初来乍到

Rank: 1

铜币
17
发表于 2010-6-9 22:01:00 | 显示全部楼层
太好的东西,正是需要的资料。
回复

使用道具 举报

72

主题

2726

帖子

9

银币

社区元老

Rank: 75Rank: 75Rank: 75

铜币
3014
发表于 2010-6-10 13:56:00 | 显示全部楼层
要是有LISP代码就好了。
回复

使用道具 举报

0

主题

1

帖子

1

银币

初来乍到

Rank: 1

铜币
1
发表于 2012-12-5 11:45:00 | 显示全部楼层
路过并表示强烈支持!
回复

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

  • 微信公众平台

  • 扫描访问手机版

  • 点击图片下载手机App

QQ|关于我们|小黑屋|乐筑天下 繁体中文

GMT+8, 2024-11-22 01:07 , Processed in 0.290157 second(s), 69 queries .

© 2020-2024 乐筑天下

联系客服 关注微信 帮助中心 下载APP 返回顶部 返回列表