明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 2507|回复: 9

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

[复制链接]
发表于 2010-8-31 13:07 | 显示全部楼层 |阅读模式
本帖最后由 作者 于 2010-8-31 18:51:14 编辑

我想为下图的每个Point,求出一个线段上的最近节点!

我的思路是:用Point来遍历每个多线段实体的节点,然后比较距离,把最小的节点提取出来!

但是这样对于实体比较多的情况,非常的慢,估计我的方法不对,请高手给我个思路,谢谢了!

 

如图:

发表于 2010-8-31 15:46 | 显示全部楼层

看不见图。。。

把代码也贴上吧?

 楼主| 发表于 2010-8-31 16:19 | 显示全部楼层

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

 楼主| 发表于 2010-8-31 22:52 | 显示全部楼层

d:\4.gif


代码如下:
  1. <CommandMethod("GetClosePt")> Public Sub GetClosedPoint()
  2.         Dim ClosedPt As New List(Of Point2d) '保存最近点
  3.         Dim db As Database = HostApplicationServices.WorkingDatabase
  4.         '获取数据库
  5.         Dim ed As Editor = Application.DocumentManager.MdiActiveDocument.Editor
  6.         '获取editor对象
  7.         Dim values As TypedValue() = {New TypedValue(DxfCode.Operator, "<or"), New TypedValue(DxfCode.Start, "Point"), _
  8.                               New TypedValue(DxfCode.Start, "LWPOLYLINE"), New TypedValue(DxfCode.Operator, "or>")}
  9.         Dim filter As New SelectionFilter(values)
  10.         Dim entOpt As New PromptSelectionOptions
  11.         entOpt.MessageForAdding = "请选择要处理的实体"
  12.         Dim entRes As PromptSelectionResult = ed.GetSelection(entOpt, filter)
  13.         If entRes.Status = PromptStatus.OK Then
  14.             Dim sSet As SelectionSet = entRes.Value
  15.             Dim pts As New List(Of DBPoint)
  16.             Dim plines As New List(Of Polyline)
  17.             Using trans As Transaction = db.TransactionManager.StartTransaction()
  18.                 Dim bt As BlockTable = trans.GetObject(db.BlockTableId, OpenMode.ForRead)
  19.                 Dim btr As BlockTableRecord = trans.GetObject(bt.Item(BlockTableRecord.ModelSpace), OpenMode.ForWrite)
  20.                 For Each id As ObjectId In sSet.GetObjectIds
  21.                     Dim ent As Entity = trans.GetObject(id, OpenMode.ForRead)
  22.                     If TypeOf (ent) Is DBPoint Then
  23.                         pts.Add(ent)
  24.                     Else
  25.                         plines.Add(ent)
  26.                     End If
  27.                 Next
  28.                 For Each pt As DBPoint In pts
  29.                     Dim ptPosition As Point2d = New Point2d(pt.Position.X, pt.Position.Y)
  30.                     Dim Cdist As Double = 1000 '给一个相当大的值作为比较值
  31.                     Dim Cpt As New Point2d
  32.                     For Each pline As Polyline In plines
  33.                         For i As Integer = 0 To pline.NumberOfVertices - 1
  34.                             Dim dist As Double = ptPosition.GetDistanceTo(pline.GetPoint2dAt(i))
  35.                             If dist < Cdist Then
  36.                                 Cdist = dist
  37.                                 Cpt = pline.GetPoint2dAt(i)
  38.                             End If
  39.                         Next
  40.                     Next
  41.                     ClosedPt.Add(Cpt)
  42.                 Next
  43.                 For Each pt1 As Point2d In ClosedPt
  44.                     Dim circle As New Circle(New Point3d(pt1(0), pt1(1), 0), Vector3d.ZAxis, 8)
  45.                     btr.AppendEntity(circle)
  46.                     trans.AddNewlyCreatedDBObject(circle, True)
  47.                 Next
  48.                 trans.Commit()
  49.             End Using
  50.         End If
  51.     End Sub
各位高手帮我看看,我是新手呀!
 楼主| 发表于 2010-8-31 23:09 | 显示全部楼层
处理400个点,需要大概5秒中,太慢了!有没有好点的办法呢?我用的平台是VS2005,AutoCad2008!
发表于 2010-9-1 09:36 | 显示全部楼层

        [CommandMethod("tt6")]
        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<oint3d> pts = new List<oint3d>();
            List<oint3d> nodes = new List<oint3d>();

            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 < pl.NumberOfVertices; i++)
                        {
                            nodes.Add(pl.GetPoint3dAt(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);
                }


            }
        }

 楼主| 发表于 2010-9-1 12:43 | 显示全部楼层

谢谢版主!

new ResultList{{ 0, "point,lwpolyline" }}和nodes.FindByMinKey(p => p.DistanceTo(pt));是自定义函数吧

能否提供!特别是FindByMinKey!谢了!

发表于 2010-9-1 14:23 | 显示全部楼层

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

 

        /// <summary>
        /// 按转换函数找出序列中最小键值的对应值
        /// </summary>
        /// <typeparam name="TValue"></typeparam>
        /// <typeparam name="TKey"></typeparam>
        /// <param name="enumerable"></param>
        /// <param name="func"></param>
        /// <returns></returns>
        public static TValue FindByMinKey<TValue, TKey>(this IEnumerable<TValue> enumerable, Func<TValue, TKey> func)
            where TKey : IComparable<TKey>
        {
            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) < 0)
                {
                    key = tkey;
                    value = itor.Current;
                }
            }
            return value;
        }

发表于 2010-9-1 14:25 | 显示全部楼层
 楼主| 发表于 2010-9-1 20:47 | 显示全部楼层

谢谢老大,拜读了!

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

本版积分规则

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

GMT+8, 2024-5-9 11:57 , Processed in 0.166935 second(s), 23 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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