马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
用了 高飞版主 Lisp版的 Graham 扫描算法,用 Stack<T>维护一个凸包 - using System;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.Linq;
- using Autodesk.AutoCAD.ApplicationServices;
- using Autodesk.AutoCAD.DatabaseServices;
- using Autodesk.AutoCAD.EditorInput;
- using Autodesk.AutoCAD.Geometry;
- using Autodesk.AutoCAD.Runtime;
- using AcAp = Autodesk.AutoCAD.ApplicationServices.Application;[assembly: CommandClass(typeof(AutoCAD_CSharp_plug_in13.MyCommands))]namespace AutoCAD_CSharp_plug_in13
- {
- public class MyCommands
- {
- private Point2d _p0; private bool Clockwise(Point2d p1, Point2d p2, Point2d p3)
- {
- return ((p2.X - p3.X )*(p2.Y - p1.Y ) - (p2.X - p1.X )*(p2.Y - p3.Y )) > -1e-6;
- }
- //按角度
- private double Cosine(Point2d pt)
- {
- double d = _p0.GetDistanceTo(pt);
- return d == 0.0 ? 1.0 : Math.Round((pt.Y - _p0.Y)/d, 9);
- }
-
- private Point2d[] ConvexHull(List<Point2d> pts)
- {
- _p0 = pts.OrderBy(p => p.X).ThenBy(p => p.Y).Last( );//最右边点
- pts = pts.OrderByDescending(p => Cosine(p)).ThenBy(p => _p0.GetDistanceTo(p)).ToList();//按角度及距离排序
- Stack<Point2d> outPoint2Ds = new Stack<Point2d>();
- outPoint2Ds.Push(_p0);
- outPoint2Ds.Push(pts[1]);
- bool tf = true;
- for (int i = 2; i < pts.Count ; i++)
- {
- Point2d n = pts[i];
- Point2d p = outPoint2Ds.Pop();//出栈 car
- Point2d q = outPoint2Ds.Pop();//取第一个 cadr
- while (tf && Clockwise(n, p, q))
- {
- if (outPoint2Ds.Count > 1)
- {
- p = q;//出栈
- q = outPoint2Ds.Pop() ;//car
-
- }
- else
- {
- tf = false;
- }
- }
- outPoint2Ds.Push(q);
- outPoint2Ds.Push(p);
- outPoint2Ds.Push(n);
- tf = true;
- }
- return outPoint2Ds.ToArray() ;
- } [CommandMethod("Test")]
- public void Test()
- {
- Document doc = AcAp.DocumentManager.MdiActiveDocument;
- Database db = doc.Database;
- Editor ed = doc.Editor;
- TypedValue[] filter = new TypedValue[1] {new TypedValue(0, "POINT")};
- PromptSelectionResult psr = ed.GetSelection(new SelectionFilter(filter));
- if (psr.Status != PromptStatus.OK) return;
- using (Transaction tr = db.TransactionManager.StartTransaction())
- using (Polyline pline = new Polyline())
- {
- List<Point2d> pts = new List<Point2d>();
- foreach (SelectedObject so in psr.Value)
- {
- DBPoint dbPt = (DBPoint) tr.GetObject(so.ObjectId, OpenMode.ForRead);
- pts.Add(new Point2d(dbPt.Position.X, dbPt.Position.Y));
- }
- Stopwatch watch = new Stopwatch();
- watch.Restart();
- Point2d [] npts = ConvexHull(pts);
- watch.Stop();
- ed.WriteMessage("\nTime = " + watch.Elapsed.TotalMilliseconds.ToString());
- for (int i = 0; i < npts.Length ; i++)
- {
- pline.AddVertexAt(i, npts[i], 0.0, 0.0, 0.0);
- }
- pline.Closed = true;
- pline.SetDatabaseDefaults();
- BlockTableRecord btr = (BlockTableRecord) tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
- btr.AppendEntity(pline);
- tr.AddNewlyCreatedDBObject(pline, true);
- tr.Commit();
- }
- }
- }
- }
|