[求助]关于搜索最近节点!
本帖最后由 作者 于 2010-8-31 18:51:14 编辑 <br /><br /> <p>我想为下图的每个Point,求出一个线段上的最近节点!</p><p>我的思路是:用Point来遍历每个多线段实体的节点,然后比较距离,把最小的节点提取出来!</p>
<p>但是这样对于实体比较多的情况,非常的慢,估计我的方法不对,请高手给我个思路,谢谢了!</p>
<p> </p>
<p>如图:<img src="d:\3.jpg"/></p> <p>看不见图。。。</p>
<p>把代码也贴上吧?</p> <p>代码在单位呢,有时间贴上!</p>
d:\4.gif
代码如下:
<CommandMethod("GetClosePt")> 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, "<or"), New TypedValue(DxfCode.Start, "Point"), _
New TypedValue(DxfCode.Start, "LWPOLYLINE"), New TypedValue(DxfCode.Operator, "or>")}
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 < Cdist Then
Cdist = dist
Cpt = pline.GetPoint2dAt(i)
End If
Next
Next
ClosedPt.Add(Cpt)
Next
For Each pt1 As Point2d In ClosedPt
Dim circle As New Circle(New Point3d(pt1(0), pt1(1), 0), Vector3d.ZAxis, 8)
btr.AppendEntity(circle)
trans.AddNewlyCreatedDBObject(circle, True)
Next
trans.Commit()
End Using
End If
End Sub
各位高手帮我看看,我是新手呀!
处理400个点,需要大概5秒中,太慢了!有没有好点的办法呢?我用的平台是VS2005,AutoCad2008! <p><font face="Verdana"> <br/> public static void test26()<br/> {</font></p>
<p><font face="Verdana"> Document doc = Application.DocumentManager.MdiActiveDocument;<br/> Editor ed = doc.Editor;<br/> Database db = doc.Database;</font></p>
<p><font face="Verdana"> var resSel =<br/> ed.SelectAll(<br/> new ResultList<br/> {<br/> { 0, "point,lwpolyline" }<br/> });</font></p>
<p><font face="Verdana"> List<Point3d> pts = new List<Point3d>();<br/> List<Point3d> nodes = new List<Point3d>();</font></p>
<p><font face="Verdana"> using (var tr = db.TransactionManager.StartTransaction())<br/> {<br/> foreach (ObjectId id in resSel.Value.GetObjectIds())<br/> {<br/> Entity ent = tr.GetObject(id, OpenMode.ForRead) as Entity;<br/> if (ent is DBPoint)<br/> {<br/> pts.Add(((DBPoint)ent).Position);<br/> }<br/> else<br/> {<br/> Polyline pl = ent as Polyline;<br/> for (int i = 0; i < pl.NumberOfVertices; i++)<br/> {<br/> nodes.Add(pl.GetPoint3dAt(i));<br/> }<br/> }<br/> }</font></p>
<p><font face="Verdana"> foreach (Point3d pt in pts)<br/> {<br/> Point3d res = nodes.FindByMinKey(p => p.DistanceTo(pt));<br/> ed.DrawPoint(res.Convert2d(new Plane()), 2, res.DistanceTo(pt), 8);<br/> }</font></p>
<p><font face="Verdana"><br/> }<br/> }<br/></font></p> <p>谢谢版主!</p>
<p>new ResultList{{ 0, "point,lwpolyline" }}和nodes.FindByMinKey(p => p.DistanceTo(pt));是自定义函数吧</p>
<p>能否提供!特别是FindByMinKey!谢了!</p> <p>是扩展函数,VS要2008版本的哈,</p>
<p> </p>
<p><font face="Verdana"> /// <summary><br/> /// 按转换函数找出序列中最小键值的对应值<br/> /// </summary><br/> /// <typeparam name="TValue"></typeparam><br/> /// <typeparam name="TKey"></typeparam><br/> /// <param name="enumerable"></param><br/> /// <param name="func"></param><br/> /// <returns></returns><br/> public static TValue FindByMinKey<TValue, TKey>(this IEnumerable<TValue> enumerable, Func<TValue, TKey> func)<br/> where TKey : IComparable<TKey><br/> {<br/> var itor = enumerable.GetEnumerator();<br/> if (!itor.MoveNext())<br/> throw new ArgumentNullException();<br/> TValue value = itor.Current;<br/> TKey key = func(value);<br/> while (itor.MoveNext())<br/> {<br/> TKey tkey = func(itor.Current);<br/> if (tkey.CompareTo(key) < 0)<br/> {<br/> key = tkey;<br/> value = itor.Current;<br/> }<br/> }<br/> return value;<br/> }</font></p> <p><font face="Verdana">ResultList:<br/><a href="http://bbs.mjtd.com/forum.php?mod=viewthread&tid=79849">http://bbs.mjtd.com/forum.php?mod=viewthread&tid=79849</a></font></p>
<p> </p> <p>谢谢老大,拜读了!</p>
页:
[1]