找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 991|回复: 2

[分享] A new C# implementation of the ConvexHull using Ling

[复制链接]

已领礼包: 859个

财富等级: 财运亨通

发表于 2014-5-21 17:35:50 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
A new C# implementation of the ConvexHull using Ling (.NET Framework 3 or upper)
  1. using System.Collections.Generic;
  2. using Autodesk.AutoCAD.ApplicationServices;
  3. using Autodesk.AutoCAD.DatabaseServices;
  4. using Autodesk.AutoCAD.EditorInput;
  5. using Autodesk.AutoCAD.Geometry;
  6. using Autodesk.AutoCAD.Runtime;
  7. using AcAp = Autodesk.AutoCAD.ApplicationServices.Application;

  8. namespace ConvexHull
  9. {
  10.     public class Commands
  11.     {
  12.         private Point2d _p0;

  13.         private bool Clockwise(Point2d p1, Point2d p2, Point2d p3)
  14.         {
  15.             return ((p2.X - p1.X) * (p3.Y - p1.Y) - (p2.Y - p1.Y) * (p3.X - p1.X)) < 1e-8;
  16.         }

  17.         private int ComparePoints(Point2d p1, Point2d p2)
  18.         {
  19.             if (p1.IsEqualTo(p2)) return 0;
  20.             double d1 = _p0.GetDistanceTo(p1);
  21.             double d2 = _p0.GetDistanceTo(p2);
  22.             if (d1 == 0.0) return -1;
  23.             if (d2 == 0.0) return 1;
  24.             double cos = (p2.X - _p0.X) / d2 - (p1.X - _p0.X) / d1;
  25.             if (cos < -1e-8) return -1;
  26.             if (cos > 1e-8) return 1;
  27.             return d1.CompareTo(d2);
  28.         }

  29.         private List<Point2d> ConvexHull(List<Point2d> pts)
  30.         {
  31.             _p0 = pts[0];
  32.             for (int i = 1; i < pts.Count; i++)
  33.             {
  34.                 Point2d pt = pts[i];
  35.                 if (pt.Y < _p0.Y || (pt.Y == _p0.Y && pt.X < _p0.X))
  36.                     _p0 = pt;
  37.             }
  38.             pts.Sort(ComparePoints);
  39.             for (int i = 1; i < pts.Count - 1; i++)
  40.             {
  41.                 while (i > 0 && Clockwise(pts[i - 1], pts[i], pts[i + 1]))
  42.                 {
  43.                     pts.RemoveAt(i);
  44.                     i--;
  45.                 }
  46.             }
  47.             return pts;
  48.         }

  49.         [CommandMethod("ch")]
  50.         public void testCh()
  51.         {
  52.             Document doc = AcAp.DocumentManager.MdiActiveDocument;
  53.             Database db = doc.Database;
  54.             Editor ed = doc.Editor;
  55.             TypedValue[] filter = new TypedValue[1] { new TypedValue(0, "POINT") };
  56.             PromptSelectionResult psr = ed.GetSelection(new SelectionFilter(filter));
  57.             if (psr.Status != PromptStatus.OK) return;
  58.             using (Transaction tr = db.TransactionManager.StartTransaction())
  59.             using (Polyline pline = new Polyline())
  60.             {
  61.                 List<Point2d> pts = new List<Point2d>();
  62.                 foreach (SelectedObject so in psr.Value)
  63.                 {
  64.                     DBPoint dbPt = (DBPoint)tr.GetObject(so.ObjectId, OpenMode.ForRead);
  65.                     pts.Add(new Point2d(dbPt.Position.X, dbPt.Position.Y));
  66.                 }
  67.                 for (int i = 0; i < ConvexHull(pts).Count; i++)
  68.                 {
  69.                     pline.AddVertexAt(i, pts[i], 0.0, 0.0, 0.0);
  70.                 }
  71.                 pline.Closed = true;
  72.                 pline.SetDatabaseDefaults();
  73.                 BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
  74.                 btr.AppendEntity(pline);
  75.                 tr.AddNewlyCreatedDBObject(pline, true);
  76.                 tr.Commit();
  77.             }
  78.         }
  79.     }
  80. }
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

已领礼包: 859个

财富等级: 财运亨通

 楼主| 发表于 2014-5-21 17:37:01 | 显示全部楼层
I repalced the lambda function with a delegate (ComparePoints) so that it can be used with NET Framework 2.0 (default for A2007 -> A2009)

  1. using System.Collections.Generic;
  2. using Autodesk.AutoCAD.ApplicationServices;
  3. using Autodesk.AutoCAD.DatabaseServices;
  4. using Autodesk.AutoCAD.EditorInput;
  5. using Autodesk.AutoCAD.Geometry;
  6. using Autodesk.AutoCAD.Runtime;
  7. using AcAp = Autodesk.AutoCAD.ApplicationServices.Application;

  8. namespace ConvexHull
  9. {
  10.     public class Commands
  11.     {
  12.         private Point2d _p0;

  13.         private bool Clockwise(Point2d p1, Point2d p2, Point2d p3)
  14.         {
  15.             return ((p2.X - p1.X) * (p3.Y - p1.Y) - (p2.Y - p1.Y) * (p3.X - p1.X)) < 1e-8;
  16.         }

  17.         private int ComparePoints(Point2d p1, Point2d p2)
  18.         {
  19.             if (p1.IsEqualTo(p2)) return 0;
  20.             double d1 = _p0.GetDistanceTo(p1);
  21.             double d2 = _p0.GetDistanceTo(p2);
  22.             if (d1 == 0.0) return -1;
  23.             if (d2 == 0.0) return 1;
  24.             double cos = (p2.X - _p0.X) / d2 - (p1.X - _p0.X) / d1;
  25.             if (cos < -1e-8) return -1;
  26.             if (cos > 1e-8) return 1;
  27.             return d1.CompareTo(d2);
  28.         }

  29.         private List<Point2d> ConvexHull(List<Point2d> pts)
  30.         {
  31.             _p0 = pts[0];
  32.             for (int i = 1; i < pts.Count; i++)
  33.             {
  34.                 Point2d pt = pts[i];
  35.                 if (pt.Y < _p0.Y || (pt.Y == _p0.Y && pt.X < _p0.X))
  36.                     _p0 = pt;
  37.             }
  38.             pts.Sort(ComparePoints);
  39.             for (int i = 1; i < pts.Count - 1; i++)
  40.             {
  41.                 while (i > 0 && Clockwise(pts[i - 1], pts[i], pts[i + 1]))
  42.                 {
  43.                     pts.RemoveAt(i);
  44.                     i--;
  45.                 }
  46.             }
  47.             return pts;
  48.         }

  49.         [CommandMethod("ch")]
  50.         public void testCh()
  51.         {
  52.             Document doc = AcAp.DocumentManager.MdiActiveDocument;
  53.             Database db = doc.Database;
  54.             Editor ed = doc.Editor;
  55.             TypedValue[] filter = new TypedValue[1] { new TypedValue(0, "POINT") };
  56.             PromptSelectionResult psr = ed.GetSelection(new SelectionFilter(filter));
  57.             if (psr.Status != PromptStatus.OK) return;
  58.             using (Transaction tr = db.TransactionManager.StartTransaction())
  59.             using (Polyline pline = new Polyline())
  60.             {
  61.                 List<Point2d> pts = new List<Point2d>();
  62.                 foreach (SelectedObject so in psr.Value)
  63.                 {
  64.                     DBPoint dbPt = (DBPoint)tr.GetObject(so.ObjectId, OpenMode.ForRead);
  65.                     pts.Add(new Point2d(dbPt.Position.X, dbPt.Position.Y));
  66.                 }
  67.                 for (int i = 0; i < ConvexHull(pts).Count; i++)
  68.                 {
  69.                     pline.AddVertexAt(i, pts[i], 0.0, 0.0, 0.0);
  70.                 }
  71.                 pline.Closed = true;
  72.                 pline.SetDatabaseDefaults();
  73.                 BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
  74.                 btr.AppendEntity(pline);
  75.                 tr.AddNewlyCreatedDBObject(pline, true);
  76.                 tr.Commit();
  77.             }
  78.         }
  79.     }
  80. }



[url]http://www.theswamp.org/index.php?topic=31865.msg373462#msg373462[/url]
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 859个

财富等级: 财运亨通

 楼主| 发表于 2014-5-22 19:48:16 | 显示全部楼层
本帖最后由 csharp 于 2014-5-23 08:54 编辑

第一个程序测试 12W 个点时用时 32s 左右,3W个点时 3s 左右

效率有问题,还不如高飞版主的 lisp 效率高
http://bbs.xdcad.net/thread-603103-1-1.html
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

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

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|辽公网安备|晓东CAD家园 ( 辽ICP备15016793号 )

GMT+8, 2024-12-19 00:00 , Processed in 0.173618 second(s), 33 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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