single-yu 发表于 2010-8-31 13:07:00

[求助]关于搜索最近节点!

我想为下图的每个Point,求出一个线段上的最近节点!
我的思路是:用Point来遍历每个多线段实体的节点,然后比较距离,把最小的节点提取出来!
但是这样对于实体比较多的情况,非常的慢,估计我的方法不对,请高手给我个思路,谢谢了!

如图:
d:\3.jpg

雪山飞狐_lzh 发表于 2010-8-31 15:46:00

看不见图。。。
把代码也贴上吧?

single-yu 发表于 2010-8-31 16:19:00

代码在单位呢,有时间贴上!

single-yu 发表于 2010-8-31 22:52:00


d:\4.gif

代码如下:

Public Sub GetClosedPoint()
      Dim ClosedPt As New List(Of Point2d) '保存最近点
      Dim db As Database = HostApplicationServices.WorkingDatabase
      '获取数据库
      Dim ed As Editor = Application.DocumentManager.MdiActiveDocument.Editor
      '获取editor对象
      Dim values As TypedValue() = {New TypedValue(DxfCode.Operator, "")}
      Dim filter As New SelectionFilter(values)
      Dim entOpt As New PromptSelectionOptions
      entOpt.MessageForAdding = "请选择要处理的实体"
      Dim entRes As PromptSelectionResult = ed.GetSelection(entOpt, filter)
      If entRes.Status = PromptStatus.OK Then
            Dim sSet As SelectionSet = entRes.Value
            Dim pts As New List(Of DBPoint)
            Dim plines As New List(Of Polyline)
            Using trans As Transaction = db.TransactionManager.StartTransaction()
                Dim bt As BlockTable = trans.GetObject(db.BlockTableId, OpenMode.ForRead)
                Dim btr As BlockTableRecord = trans.GetObject(bt.Item(BlockTableRecord.ModelSpace), OpenMode.ForWrite)
                For Each id As ObjectId In sSet.GetObjectIds
                  Dim ent As Entity = trans.GetObject(id, OpenMode.ForRead)
                  If TypeOf (ent) Is DBPoint Then
                        pts.Add(ent)
                  Else
                        plines.Add(ent)
                  End If
                Next
                For Each pt As DBPoint In pts
                  Dim ptPosition As Point2d = New Point2d(pt.Position.X, pt.Position.Y)
                  Dim Cdist As Double = 1000 '给一个相当大的值作为比较值
                  Dim Cpt As New Point2d
                  For Each pline As Polyline In plines
                        For i As Integer = 0 To pline.NumberOfVertices - 1
                            Dim dist As Double = ptPosition.GetDistanceTo(pline.GetPoint2dAt(i))
                            If dist         
      public static void test26()
      {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;
            Database db = doc.Database;
            var resSel =
                ed.SelectAll(
                  new ResultList
                  {
                        { 0, "point,lwpolyline" }
                  });
            List&ltoint3d> pts = new List&ltoint3d>();
            List&ltoint3d> nodes = new List&ltoint3d>();
            using (var tr = db.TransactionManager.StartTransaction())
            {
                foreach (ObjectId id in resSel.Value.GetObjectIds())
                {
                  Entity ent = tr.GetObject(id, OpenMode.ForRead) as Entity;
                  if (ent is DBPoint)
                  {
                        pts.Add(((DBPoint)ent).Position);
                  }
                  else
                  {
                        Polyline pl = ent as Polyline;
                        for (int i = 0; i
                foreach (Point3d pt in pts)
                {
                  Point3d res = nodes.FindByMinKey(p => p.DistanceTo(pt));
                  ed.DrawPoint(res.Convert2d(new Plane()), 2, res.DistanceTo(pt), 8);
                }

            }
      }

single-yu 发表于 2010-8-31 23:09:00

谢谢版主!
new ResultList{{ 0, "point,lwpolyline" }}和nodes.FindByMinKey(p => p.DistanceTo(pt));是自定义函数吧
能否提供!特别是FindByMinKey!谢了!

雪山飞狐_lzh 发表于 2010-9-1 09:36:00

是扩展函数,VS要2008版本的哈,

      ///
      /// 按转换函数找出序列中最小键值的对应值
      ///
      ///
      ///
      ///
      ///
      ///
      public static TValue FindByMinKey(this IEnumerable enumerable, Func func)
            where TKey : IComparable
      {
            var itor = enumerable.GetEnumerator();
            if (!itor.MoveNext())
                throw new ArgumentNullException();
            TValue value = itor.Current;
            TKey key = func(value);
            while (itor.MoveNext())
            {
                TKey tkey = func(itor.Current);
                if (tkey.CompareTo(key)

single-yu 发表于 2010-9-1 12:43:00

ResultList:


雪山飞狐_lzh 发表于 2010-9-1 14:23:00

谢谢老大,拜读了!
页: [1]
查看完整版本: [求助]关于搜索最近节点!