乐筑天下

搜索
欢迎各位开发者和用户入驻本平台 尊重版权,从我做起,拒绝盗版,拒绝倒卖 签到、发布资源、邀请好友注册,可以获得银币 请注意保管好自己的密码,避免账户资金被盗
查看: 174|回复: 10

如何用VBA连接相邻的长折线?

[复制链接]

14

主题

78

帖子

1

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
134
发表于 2006-5-25 04:28:37 | 显示全部楼层 |阅读模式
已经醒了大约30个小时,我的项目越来越慢。我想我很快就会“睡觉”。我希望今天晚上醒来,找到以下问题的解决方案。
在一层上是一堆开放的LW折线。从视觉上看,它们形成了一个封闭的轮廓,因为它们的端点都相邻。该图层上没有其他东西,只有这个LW多段线的集合。
我需要知道这个轮廓的封闭区域。
一个普通的Autocad用户会选择修改-加入,选择一条多段线,然后用栅栏选择其他的,或者冻结所有其他图层,然后选择剩下的所有(Ctrl-A)。瞧,所有的多段线现在都是一条巨大的封闭多段线,其中的区域可以在属性窗口中找到。
我可以通过在VBA中使用send命令来模仿这样一个普通的Autocad用户,但老实说,我讨厌这样,它们会在你最意想不到的时候咬你。我也可以使用算术。形状是一堆参数化建模例程的副产品,这是我之前完成的程序的一部分,所以我也许可以通过“回溯”这些例程来收集必要的信息。
但我相信你们中的一个人有一个使用干净VB(A)的简单解决方案,所以当我醒来时,我会有一些期待,并且能够在本周末的某个时候完成d***项目,至少是具有挑战性的部分。
现在是上午10点30分,我又开始看到眼角的那些小动作。睡觉时间!在声音开始之前......:丑陋:

本帖以下内容被隐藏保护;需要你回复后,才能看到!

游客,如果您要查看本帖隐藏内容请回复
回复

使用道具 举报

14

主题

78

帖子

1

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
134
发表于 2006-5-25 06:45:43 | 显示全部楼层
不错的功能Jürg
回复

使用道具 举报

170

主题

1424

帖子

8

银币

顶梁支柱

Rank: 50Rank: 50

铜币
2119
发表于 2006-5-25 11:05:16 | 显示全部楼层
(哎呀,我在完成之前就发布了我的回复!这是最终版本。)
我总是羡慕那些只需阅读音符就能“听到”音乐的音乐家。同样使用VBA,我可能永远不会达到那种水平的监视。所以我花了一些时间来“听到你的代码的音乐”。用我简单的话来说,我发现它的作用是:
检查您呈现的两条折线是否可以连接。如果是这样,请将第二个的顶点等添加到第一个,删除第二个并报告“任务完成!我加入了两个折线”。
所以,现在,所需要的只是一个嵌入例程:
创建一个要研究的折线选择集
-比较/连接集合中的第一个与所有其他的(使用您的函数)
-在所有比较之后,如果可能,与第一个连接,刷新选择集
-执行新运行,另一个(或使用递归或嵌套循环),直到只剩下一个折线或无法进行进一步的连接
然后关闭此折线并获取我需要的区域值。(除此之外,这幅画已经被清理了一些,但是无知的观众看不到区别。)
谢谢尤尔格!与此同时,我为我的问题找到了一个更简单的解决方案(今天早上我昏昏欲睡,看不见它),但我认为许多其他读者很可能会利用你的杰作!
回复

使用道具 举报

170

主题

1424

帖子

8

银币

顶梁支柱

Rank: 50Rank: 50

铜币
2119
发表于 2006-5-25 13:32:39 | 显示全部楼层
像这样的东西应该可以工作
  1. Sub JoininJoininJoinin()
  2. 'Get them plines joinin'
  3. 'This song is quite anoyin'
  4. 'raw code
  5. Dim objSelSet As AcadSelectionSet
  6. Dim objSelSets As AcadSelectionSets
  7. Dim intGroup(0 To 1) As Integer
  8. Dim varData(0 To 1) As Variant
  9. Dim intcnt As Integer
  10. Set objSelSets = ThisDrawing.SelectionSets
  11. For Each objSelSet In objSelSets
  12.   If objSelSet.Name = "PolyJoin" Then
  13.     objSelSets.Item(objSelSet.Name).Delete
  14.     Exit For
  15.   End If
  16. Next objSelSet
  17. intGroup(0) = 0: varData(0) = "LWPolyline": intGroup(1) = 8: varData(1) = "LayerName"
  18. Set objSelSet = objSelSets.Add("PolyJoin")
  19. objSelSet.Select acSelectionSetAll, , , intGroup, varData
  20. For intcnt = 1 To objSelSet.Count - 1
  21.   MeJoinPline objSelSet.Item(0), objSelSet.Item(intcnt), 0.01
  22. Next intcnt
  23. End Sub

回复

使用道具 举报

170

主题

1424

帖子

8

银币

顶梁支柱

Rank: 50Rank: 50

铜币
2119
发表于 2006-5-25 15:39:17 | 显示全部楼层
仔细想想,只有当它们在选择集中都按顺序排列时,它才起作用。如果它们不按顺序排列,很可能,它不会连接所有的东西。您可以将选择集分解为一个函数,填充它,运行连接函数,重新填充选择集,然后循环,直到选择集计数= 1。不过要打个勾,因为如果他们中的任何一个不在你的模糊因素之内,不能加入,你就会永远循环下去。
回复

使用道具 举报

170

主题

1424

帖子

8

银币

顶梁支柱

Rank: 50Rank: 50

铜币
2119
发表于 2006-5-25 16:21:25 | 显示全部楼层
我已经为此工作了2年,它的99.5%,其中一些3D有点棘手。我为cnc画了很多,所以我不想要额外的顶点或线。这应该删除坏蛋。至于应该加入什么,你必须做出决定。我不知道我是否应该先把所有的线都做成多边形。我很确定我可以在这里消除一些步骤,但是越来越难看到树木的觅食。

  1. Option Explicit
  2. Declare Function GetCursor Lib "user32" () As Long
  3. Public Declare Function GetAsyncKeyState Lib "user32" _
  4.         (ByVal vKey As Long) As Integer
  5. Public Declare Sub CopyMemory Lib "kernel32" _
  6.     Alias "RtlMoveMemory" _
  7.     (dest As Any, source As Any, ByVal Length As Long) 'AlmostEqual
  8. Private DeleteCol As Collection
  9. Private StartEndCol As Collection
  10. Private SlopeCol As Collection
  11. Private CoordList As Collection
  12. Private Const PolyClosedFudge As Double = 0.005
  13. 'If the first coordinate and last coordinate are within this distance
  14. 'The poly will be closed.
  15. Const Pi As Double = 3.14159265358979
  16. Public Property Get CurrentSpace() As AcadBlock
  17.   If ThisDrawing.GetVariable("CVPORT") = 1 Then
  18.     Set CurrentSpace = ThisDrawing.PaperSpace
  19.   Else
  20.     Set CurrentSpace = ThisDrawing.ModelSpace
  21.   End If
  22. End Property
  23. 'Aims
  24. '1) To select a group of lines,arcs and polys
  25. 'and create clean polys w/ no double ups
  26. 'or double points.
  27. '2) Delete unnecessary geometry
  28. 'Some will want to add a layer control here.
  29. '3) Note 2d and 3dpolys are not included
  30. '4) I have used line formulas rather than polar angles
  31. 'hoping that it will be faster.
  32. Sub VBAPLJoin()
  33.     'On Error GoTo Err_Control
  34.     Dim oLine As AcadLine
  35.     Dim LineCol As New Collection
  36.     Dim oPline As AcadLWPolyline
  37.     Dim CoordsCt As Integer
  38.     Dim oArc As AcadArc
  39.     Dim oSSets As AcadSelectionSets
  40.     Dim ss As AcadSelectionSet
  41.     Dim FilterType(6) As Integer
  42.     Dim FilterData(6) As Variant
  43.     Dim i As Integer, j As Integer, k As Integer
  44.     Dim intNotParallel As Integer
  45.     Dim PtsCount As Integer, Count As Integer
  46.     Dim StartPt As Variant, EndPt As Variant
  47.     Dim StartP(2) As Double, EndP(2) As Double
  48.     Dim Pt As Variant
  49.     Dim pts() As Double
  50.     Dim SE(4) As Variant
  51.     Dim obj(0) As AcadEntity
  52.     Dim M As Double, OrigY As Double
  53.     Dim UcsNormal As Variant, N As Variant
  54.     Dim blnRemove As Boolean
  55.     Dim dblElev As Double
  56.     Dim strlayer As String
  57.     Dim util As AcadUtility
  58.     PtsCount = 1
  59.     Set util = ThisDrawing.Utility
  60.     Set StartEndCol = New Collection
  61.         
  62.     'Stage 1  Create the selectionset
  63.     Set oSSets = ThisDrawing.SelectionSets
  64.     For Each ss In oSSets
  65.         If ss.Name = "SS" Then
  66.             ss.Delete
  67.             Exit For
  68.         End If
  69.     Next
  70.     Set ss = oSSets.Add("SS")
  71.    
  72.    
  73.     FilterType(0) = 0: FilterData(0) = "Line,Arc,LWPolyline"
  74.     FilterType(1) = -4: FilterData(1) = ""
  75.     FilterType(6) = -4: FilterData(6) = "NOT>"
  76.    
  77.      Do ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  78.         ss.SelectOnScreen FilterType:=FilterType, FilterData:=FilterData
  79.     Loop Until GetCursor = 0
  80.    
  81.     If ss.Count > 500 Then
  82.         MsgBox "You have selected " & ss.Count & " objects. Please select less :"
  83.         Exit Sub
  84.     End If
  85.     If ss.Count = 0 Then
  86.         Set ss = Nothing
  87.         ''''''''''''MsgBox "Nothing selected."
  88.         Exit Sub
  89.     End If
  90.     If ss.Count = 1 Then
  91.         If TypeOf ss(0) Is AcadLWPolyline Then
  92.             Set oPline = ss(0)
  93.             If UBound(oPline.Coordinates) = 3 Then
  94.                 Exit Sub
  95.             End If
  96.         End If
  97.     End If
  98.     UcsNormal = CurrentUcsNormal
  99.     'We're using the SS set index to keep track of the objects
  100.     'So first pass is just to clean up the set
  101.     'From then on the order wont change
  102.    
  103.     'Stage 2- delete zero length ents, remove non applicable ents
  104.      For i = ss.Count - 1 To 0 Step -1
  105.         If TypeOf ss(i) Is AcadLine Then
  106.             Set oLine = ss(i)
  107.             If oLine.Length  0 Then
  108.         CheckLines LineCol 'Sub checks for equal, overlapping lines
  109.     End If
  110.     If ss.Count = 0 Then 'items may have been removed
  111.         Exit Sub
  112.     End If
  113.     If intNotParallel = 1 Then
  114.         MsgBox intNotParallel & " object was not parallel to the current UCS."
  115.     ElseIf intNotParallel > 1 Then
  116.         MsgBox intNotParallel & " objects were not parallel to the current UCS."
  117.     End If
  118.    
  119.     'Stage 5
  120.     'This function sorts the start and end points into order
  121.     If StartEndCol.Count > 1 Then
  122.         SortPts
  123.     End If
  124.    
  125.     Dim blnClosed As Boolean, blnNewLine As Boolean
  126.     Dim BulgeCol() As Double, PolyBulgeCol() As Double
  127.     Dim MPt(2) As Double, Seg As Double, Ht As Double
  128.     Dim sPt, ePt
  129.     ReDim pts(1)
  130. AddNewLine:
  131.    
  132.     Count = StartEndCol.Count
  133.     j = 0
  134.     If Count > 1 Then
  135.         For i = 1 To Count
  136.             If StartEndCol(i)(2) = "NewLine" Then
  137.                 j = i - 1
  138.                 Exit For
  139.             End If
  140.         Next
  141.         If j = 0 Then j = Count
  142.         If EqualPts(StartEndCol(1)(0), StartEndCol(j)(1)) Then
  143.             blnClosed = True
  144.         End If
  145.     End If
  146.    
  147.     N = ss(StartEndCol(1)(2)).Normal
  148.     dblElev = ElevationFromPt(StartEndCol(1)(0), N) '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  149.     strlayer = ss(StartEndCol(1)(2)).Layer
  150.     'Stage 6
  151.     'Draw a pline for each set of continuous points
  152.     'NewLine signifies there are no more points to add
  153.     'to the last poly so a new poly is reqd.
  154.    
  155.    
  156.     sPt = StartEndCol(1)(0)
  157.     sPt = util.TranslateCoordinates(sPt, acWorld, acOCS, 1, N)
  158.     pts(0) = sPt(0)
  159.     pts(1) = sPt(1)
  160.     PtsCount = 1
  161.     For i = 1 To StartEndCol.Count
  162.         If StartEndCol(i)(2) = "NewLine" Then
  163.             StartEndCol.Remove i
  164.             blnNewLine = True
  165.             Exit For
  166.         End If
  167.         
  168.         If TypeOf ss(StartEndCol(i)(2)) Is AcadArc Then
  169.             Set oArc = ss(StartEndCol(i)(2))
  170.             ePt = StartEndCol(i)(1)
  171.             ePt = util.TranslateCoordinates(ePt, acWorld, acOCS, 1, N)
  172.                        
  173.             ReDim Preserve pts(PtsCount + 2)
  174.             pts(PtsCount + 1) = ePt(0)
  175.             pts(PtsCount + 2) = ePt(1)
  176.             'Now get the bulge
  177.             sPt = ToUcs(oArc.Startpoint): ePt = ToUcs(oArc.Endpoint)
  178.             Dim CPt As Variant
  179.             CPt = ToUcs(oArc.Center)
  180.             MPt(0) = sPt(0) + ((ePt(0) - sPt(0)) / 2)
  181.             MPt(1) = sPt(1) + ((ePt(1) - sPt(1)) / 2)
  182.             MPt(2) = sPt(2)
  183.             Seg = (Length(sPt, ePt)) / 2
  184.             If oArc.TotalAngle > Pi Then
  185.                 Ht = (2 * oArc.radius) - (oArc.radius - Length(CPt, MPt))
  186.             Else
  187.                 Ht = oArc.radius - Length(CPt, MPt)
  188.             End If
  189.             ReDim Preserve BulgeCol((PtsCount - 1) / 2)
  190.              If EqualPts(oArc.Startpoint, StartEndCol(i)(0)) Then
  191.             
  192.                 BulgeCol((PtsCount - 1) / 2) = Ht / Seg 'Bulge
  193.             Else
  194.                 BulgeCol((PtsCount - 1) / 2) = -Ht / Seg
  195.                            
  196.             End If
  197.             PtsCount = PtsCount + 2
  198.             StartEndCol.Remove i
  199.             i = i - 1
  200.             GoTo Skip3
  201.         End If
  202.         If TypeOf ss(StartEndCol(i)(2)) Is AcadLine Then
  203. PlineLine:
  204.             ePt = StartEndCol(i)(1)
  205.             ePt = util.TranslateCoordinates(ePt, acWorld, acOCS, 1, N)
  206.             'addpt EPt, , 2
  207.             ReDim Preserve pts(PtsCount + 2)
  208.             pts(PtsCount + 1) = ePt(0)
  209.             pts(PtsCount + 2) = ePt(1)
  210.             ReDim Preserve BulgeCol((PtsCount - 1) / 2)
  211.             BulgeCol((PtsCount - 1) / 2) = 0
  212.             PtsCount = PtsCount + 2
  213.             StartEndCol.Remove i
  214.             i = i - 1
  215.             GoTo Skip3
  216.         End If
  217.         If TypeOf ss(StartEndCol(i)(2)) Is AcadLWPolyline Then
  218.             Set oPline = ss(StartEndCol(i)(2))
  219.             CoordsCt = (UBound(oPline.Coordinates) - 1) / 2
  220.             If CoordsCt = 1 Then
  221.                 If oPline.GetBulge(0) = 0 Then
  222.                     GoTo PlineLine
  223.                 End If
  224.             End If
  225.             Dim Coord, coords()
  226.             ReDim coords(CoordsCt)
  227.             ReDim PolyBulgeCol(CoordsCt - 1)
  228.             For j = 0 To 1
  229.                 StartPt(j) = oPline.Coordinates(j)
  230.             Next j
  231.             StartPt(2) = oPline.Elevation
  232.             Pt = util.TranslateCoordinates(StartPt, acOCS, acWorld, 1, oPline.Normal)
  233.             If Not EqualPts(Pt, StartEndCol(i)(0)) Then 'swap''''''''''''''''''
  234.                 k = 0
  235.                 For j = CoordsCt To 0 Step -1
  236.                     coords(k) = oPline.Coordinate(j)
  237.                     k = k + 1
  238.                 Next
  239.                 k = 0
  240.                 For j = CoordsCt - 1 To 0 Step -1
  241.                     PolyBulgeCol(k) = -oPline.GetBulge(j)
  242.                     k = k + 1
  243.                 Next
  244.             Else
  245.                 For j = 0 To CoordsCt
  246.                     coords(j) = oPline.Coordinate(j)
  247.                 Next
  248.                 For j = 0 To CoordsCt - 1
  249.                     PolyBulgeCol(j) = oPline.GetBulge(j)
  250.                 Next
  251.                
  252.             End If
  253.             ReDim Preserve pts(PtsCount + (CoordsCt * 2))
  254.             For j = 1 To CoordsCt 'We already have the first pair
  255.             
  256.                 pts(PtsCount + 1) = coords(j)(0)
  257.                 pts(PtsCount + 2) = coords(j)(1)
  258.                 ReDim Preserve BulgeCol((PtsCount - 1) / 2)
  259.                 BulgeCol((PtsCount - 1) / 2) = PolyBulgeCol(j - 1)
  260.                 PtsCount = PtsCount + 2
  261.             Next
  262.             StartEndCol.Remove i
  263.             i = i - 1
  264.             GoTo Skip3
  265.         End If
  266. Skip3:
  267.         If StartEndCol.Count = 0 Then
  268.             Exit For
  269.         End If
  270.     Next i
  271.    
  272.    
  273.     If blnClosed Then
  274.         ReDim Preserve pts(PtsCount - 2)
  275.     End If
  276.    
  277.     Set oPline = ThisDrawing.ModelSpace.AddLightWeightPolyline(pts)
  278.     oPline.Elevation = dblElev
  279.     'oPline.Normal = N ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  280.     'oPline.Color = acMagenta
  281.     oPline.Layer = strlayer
  282.     For i = 0 To UBound(BulgeCol)
  283.         oPline.SetBulge i, BulgeCol(i)
  284.     Next
  285.     If blnClosed Then
  286.         oPline.Closed = True
  287.     Else
  288.         PolyVertexCheck oPline ''''''''''''''''''''''''''''''''''
  289.     End If
  290.    
  291.    
  292.     If blnNewLine Then
  293.         blnNewLine = False
  294.         blnClosed = False
  295.         If StartEndCol.Count > 0 Then
  296.             GoTo AddNewLine
  297.         End If
  298.     End If
  299.    
  300.     ss.Erase 'Delete the selection set leaving us w/ nice new polys
  301.     ss.Delete
  302. Exit_Here:
  303.     Exit Sub
  304. Err_Control:
  305.     Select Case Err.Number
  306.     'Add your Case selections here
  307.         Case Else
  308.         MsgBox Err.Description
  309.         Err.Clear
  310.         Resume Exit_Here
  311.     End Select
  312. End Sub

回复

使用道具 举报

71

主题

928

帖子

8

银币

顶梁支柱

Rank: 50Rank: 50

铜币
1230
发表于 2006-5-25 16:44:06 | 显示全部楼层
一些函数
  1. Function GetSlope(DeltaX, DeltaY, StartPt As Variant, _
  2.                 M As Double, OrigY As Double) As Integer
  3.     DeltaX = CDbl(DeltaX)
  4.     DeltaY = CDbl(DeltaY)
  5.     If Rd(DeltaY, 0) Then   'Line is horizontal
  6.         M = 0
  7.         OrigY = StartPt(1)
  8.         GetSlope = 0
  9.     ElseIf Rd(DeltaX, 0) Then  'Line is vertical
  10.         M = StartPt(0)
  11.         OrigY = 0
  12.         GetSlope = 1
  13.     Else
  14.         M = DeltaY / DeltaX
  15.         OrigY = StartPt(1) - (M * StartPt(0))
  16.         GetSlope = 2
  17.     End If
  18. End Function
  19. Private Function SortPts()
  20.    
  21.     Dim A As Variant, b As Variant
  22.     Dim StartPt As Variant, EndPt As Variant
  23.     Dim NextStartPt As Variant, NextEndPt As Variant
  24.     Dim NewStartEndCol As New Collection
  25.     Dim blnRemoved As Boolean
  26.     Dim intBefore As Integer
  27.     Dim i As Integer
  28.    
  29.     intBefore = 1
  30.     A = StartEndCol(1)
  31.     StartPt = A(0): EndPt = A(1)
  32.     NewStartEndCol.Add A
  33.     StartEndCol.Remove 1
  34.     Do While StartEndCol.Count > 0
  35. Removed:
  36.         blnRemoved = False
  37.         For i = StartEndCol.Count To 1 Step -1
  38.             
  39.             NextStartPt = StartEndCol(i)(0)
  40.             NextEndPt = StartEndCol(i)(1)
  41.             
  42.             If EqualPts(StartPt, NextStartPt) Then
  43.                 StartPt = NextEndPt
  44.                 A = StartEndCol(i)
  45.                 'swap start and end points
  46.                 A(0) = NextEndPt
  47.                 A(1) = NextStartPt
  48.                 NewStartEndCol.Add A, , intBefore
  49.                 blnRemoved = True
  50.                 GoTo skip
  51.             End If
  52.             If EqualPts(StartPt, NextEndPt) Then
  53.                 StartPt = NextStartPt
  54.                 A = StartEndCol(i)
  55.                 NewStartEndCol.Add A, , intBefore
  56.                 blnRemoved = True
  57.                 GoTo skip
  58.             End If
  59.             If EqualPts(EndPt, NextStartPt) Then
  60.                 EndPt = NextEndPt
  61.                 A = StartEndCol(i)
  62.                 NewStartEndCol.Add A
  63.                 blnRemoved = True
  64.                 GoTo skip
  65.             End If
  66.             If EqualPts(EndPt, NextEndPt) Then
  67.                     EndPt = NextStartPt
  68.                     A = StartEndCol(i)
  69.                     'swap start and end points
  70.                     A(0) = NextEndPt
  71.                     A(1) = NextStartPt
  72.                     NewStartEndCol.Add A
  73.                     blnRemoved = True
  74.                     GoTo skip
  75.             End If
  76.             
  77. skip:
  78.             If blnRemoved Then
  79.                 StartEndCol.Remove i
  80.                 GoTo Removed
  81.             End If
  82.         Next
  83.         
  84.         If blnRemoved = False Then
  85.             If StartEndCol.Count > 0 Then
  86.                 A(2) = "NewLine"
  87.                 NewStartEndCol.Add A
  88.                 A = StartEndCol(1)
  89.                 StartPt = A(0): EndPt = A(1)
  90.                 NewStartEndCol.Add A
  91.                 intBefore = NewStartEndCol.Count
  92.                 StartEndCol.Remove 1
  93.             End If
  94.          End If
  95.     Loop
  96.         
  97.    
  98.     For i = 1 To NewStartEndCol.Count
  99.         StartEndCol.Add NewStartEndCol(i)
  100.     Next
  101. End Function
  102. 'Rules used
  103. '1)identical-
  104. '   delete one
  105. '2)line within line-and no arms off the smaller-delete smaller
  106.         'if within has arm and the larger doesn't-remove the larger
  107.         'intWithin 1=start equal,2=end equal,3=neither
  108. '3)Overlapping
  109.     'if no arms off the inside pts then delete both, add one long line
  110.     'intWithin=4
  111. Private Sub CheckLines(LineCol As Collection)
  112.     Dim oLine As AcadLine
  113.     Dim Si  As Variant, Sj  As Variant, varSE  As Variant
  114.     Dim blnSti As Boolean, blnStj As Boolean
  115.     Dim blnEndi As Boolean, blnEndj As Boolean
  116.     Dim Starti As Variant, Endi As Variant
  117.     Dim Startj As Variant, Endj As Variant
  118.     Dim i As Integer, j As Integer, k As Integer
  119.     Dim intWithin As Integer '1=start equal,2=end equal,3=neither
  120.     Dim blnRemoved As Boolean
  121.     Dim intVertical As Integer
  122.    
  123.     For i = LineCol.Count To 1 Step -1 'allows removal from set
  124.         Si = LineCol(i)
  125.         Starti = Si(0): Endi = Si(1)
  126.         'now do the expensive point checks we will need to
  127.         'check if a line has an arm coming off it
  128.         'we only want to do this once
  129.         blnSti = PtCheck(Starti, i)
  130.         blnEndi = PtCheck(Endi, i)
  131.         For j = LineCol.Count To 1 Step -1
  132.             blnRemoved = False
  133.             If Not j = i Then
  134.                 If Rd(LineCol(j)(4), LineCol(i)(4)) Then 'Check origY values
  135.                     If Rd(LineCol(j)(3), LineCol(i)(3)) Then  'Check slope values
  136.                     'Check z values''''''''''''''''''''''''''''''''
  137.                         Sj = LineCol(j)
  138.                         Startj = Sj(0): Endj = Sj(1)
  139.             
  140.                         'now we dont have to factor in Line direction
  141.                         'Make i the most left or the lowest
  142.                         If Startj(0)  Endi(0) Or Startj(1) > Endi(1) Then
  143.                             GoTo skip 'Get it the next time
  144.                         End If
  145.                      
  146.                         'Check for identical
  147.                         If Rd(Startj(0), Starti(0)) And Rd(Endj(0), Endi(0)) Then   'Could be vertical
  148.                             If Rd(Startj(1), Starti(1)) Then
  149.                                 If Rd(Endj(1), Endi(1)) Then   'identical
  150.                                     DeleteIt LineCol, j
  151.                                     blnRemoved = True
  152.                                     'i = i - 1
  153.                                     GoTo skip
  154.                                  End If
  155.                             End If
  156.                         End If
  157.         
  158.                         intWithin = 0
  159.                         intVertical = 0
  160.                         'Check for within or overlapping
  161.                         'Do the verticals first
  162.                         If Rd(Startj(0), Starti(0)) And Rd(Endj(0), Endi(0)) Then  'vertical now
  163.                             intVertical = 1
  164.                             If Rd(Startj(1), Starti(1)) Then
  165.                                 intWithin = 1
  166.                             End If
  167.                             If Startj(1) > Starti(1) Then
  168.                                 If Endj(1)  i Then ''''''''''''''''
  169.                                                 j = j - 1
  170.                                             End If
  171.                                             DeleteIt LineCol, j
  172.                                             LineCol.Add Si
  173.                                             StartEndCol.Add Si
  174.                                             'i = i - 1
  175.                                             GoTo skip
  176.                                         End If
  177.                                     End If
  178.                                 End If
  179.                             End If
  180.                             GoTo BranchControl
  181.                         End If
  182.                                 
  183.                         'Now horiz. lines and the rest
  184.                         If Rd(Startj(0), Starti(0)) Then
  185.                             intWithin = 1
  186.                             GoTo BranchControl
  187.                         End If
  188.                         
  189.                         If Startj(0) > Starti(0) Then
  190.                             If Endj(0)  i Then
  191.                                             j = j - 1
  192.                                         End If
  193.                                         DeleteIt LineCol, j
  194.                                         LineCol.Add Si
  195.                                         StartEndCol.Add Si
  196.                                         'i = i - 1
  197.                                         GoTo skip
  198.                                     End If
  199.                                 End If
  200.                             End If
  201.                         End If
  202.                         
  203.                         If intWithin = 0 Then GoTo skip
  204.                
  205. BranchControl:
  206.                         'now do the expensive point checks we will need to
  207.                         'check if a line has an arm coming off it
  208.                         'we only want to do this once
  209.                         blnStj = PtCheck(Startj, j)
  210.                         blnEndj = PtCheck(Endj, j)
  211.    
  212.                         If intWithin = 4 Then 'overlapping
  213.                             If Not blnStj And Not blnEndi Then 'make one line
  214.                                 Si = LineCol(i)
  215.                                 Si(1) = Endj
  216.                                 DeleteIt LineCol, i
  217.                                 blnRemoved = True
  218.                                 If j > i Then ''''''''''''''''
  219.                                     j = j - 1
  220.                                 End If
  221.                                 DeleteIt LineCol, j
  222.                                 LineCol.Add Si
  223.                                 StartEndCol.Add Si
  224.                                 'i = i - 1
  225.                                 GoTo skip
  226.                             End If
  227.                         End If
  228.                         
  229.                         If intWithin = 1 Then
  230.                             If Endj(intVertical)  i Then
  231.                 j = j - 1
  232.             End If
  233.             If i > j Then
  234.                 i = i - 1
  235.             End If
  236.         End If
  237.         Next j
  238.     Next i
  239. End Sub
  240. Private Sub DeleteIt(COL As Collection, i As Integer)
  241.     'Add layermanagement here if you need it.
  242.     Dim k As Integer
  243.     For k = 1 To StartEndCol.Count
  244.         If StartEndCol(k)(2) = COL(i)(2) Then
  245.             StartEndCol.Remove k
  246.             Exit For
  247.         End If
  248.     Next
  249.     COL.Remove i
  250. End Sub
  251. Function SortStartEnd(StartPt, EndPt)
  252.     Dim varPt As Variant
  253.     If EndPt(0) - StartPt(0) > 0.00000001 Then
  254.     'If StartPt(0)  EndPt(1) Then
  255.                  varPt = StartPt
  256.                  StartPt = EndPt
  257.                  EndPt = varPt
  258.             Else
  259.                 Exit Function
  260.             End If
  261.         Else
  262.             varPt = StartPt
  263.             StartPt = EndPt
  264.             EndPt = varPt
  265.         End If
  266.     End If
  267. End Function
  268. Function CurrentUcsNormal() As Variant
  269.     Dim UcsX, UcsY, UcsZ(2) As Double
  270.     UcsX = ThisDrawing.GetVariable("Ucsxdir")
  271.     UcsY = ThisDrawing.GetVariable("Ucsydir")
  272.     'get CrossProduct
  273.     UcsZ(0) = UcsX(1) * UcsY(2) - UcsX(2) * UcsY(1)
  274.     UcsZ(1) = UcsX(2) * UcsY(0) - UcsX(0) * UcsY(2)
  275.     UcsZ(2) = UcsX(0) * UcsY(1) - UcsX(1) * UcsY(0)
  276.     CurrentUcsNormal = UcsZ
  277.     'Debug.Print UcsZ(0), UcsZ(1), UcsZ(2)
  278. End Function
  279. Function ToUcs(Pt As Variant) As Variant
  280.     ToUcs = ThisDrawing.Utility.TranslateCoordinates(Pt, acWorld, acUCS, False)
  281. End Function
  282. Function ToWcs(Pt As Variant) As Variant
  283.     ToWcs = ThisDrawing.Utility.TranslateCoordinates(Pt, acUCS, acWorld, False)
  284. End Function
  285. Function Rd(num1 As Variant, num2 As Variant) As Boolean
  286.     Dim dRet As Double
  287.     dRet = num1 - num2
  288.     If Abs(dRet)  2 Or i  0 Then
  289.             Stx = Startpoint(0): Sty = Startpoint(1)
  290.             Enx = Endpoint(0): Eny = Endpoint(1)
  291.             dX = Stx - Enx
  292.             dY = Sty - Eny
  293.             If i = 1 Then
  294.                 Length = Sqr(dX * dX + dY * dY)
  295.             Else
  296.                 Stz = Startpoint(2): Enz = Endpoint(2)
  297.                 dZ = Stz - Enz
  298.                 Length = Sqr((dX * dX) + (dY * dY) + (dZ * dZ))
  299.             End If
  300.         Else
  301.             Exit Function
  302.         End If
  303.     Else
  304.         Exit Function
  305.     End If
  306. End Function
  307. Function ElevationFromPt(Pt As Variant, varNormal As Variant) As Double
  308.     'Ax+ By + Cz + d = 0 formula for a plane where d=-oLWP.Elevation
  309.     'ElevationFromPt = Pt(0) * UcsNormal(0) + Pt(1) * UcsNormal(1) + Pt(2) * UcsNormal(2)
  310.     ElevationFromPt = (Pt(0) * varNormal(0)) + (Pt(1) * varNormal(1)) + (Pt(2) * varNormal(2))
  311. End Function

回复

使用道具 举报

170

主题

1424

帖子

8

银币

顶梁支柱

Rank: 50Rank: 50

铜币
2119
发表于 2006-5-25 20:38:10 | 显示全部楼层
这个是棘手的
  1. Function PolyVertexCheck(oPline As AcadLWPolyline, Optional j As Integer = -1) As Boolean
  2.     'Checks for duplicate verticies
  3.     'Should be closed.
  4.     'Some Double backs
  5.     Dim cCount As Integer
  6.     Dim Dist As Double
  7.     Dim NewCoordList As New Collection
  8.     Dim i As Integer, k As Integer
  9.     Dim Coord As Variant, PrevCoord As Variant, coord2 As Variant
  10.     Dim Coord3 As Variant, Coord4 As Variant
  11.     Dim SlopeCol As New Collection
  12.     Dim BulgeCol As New Collection
  13.     Dim DeltaX As Double, DeltaY As Double
  14.     Dim StartPt As Variant
  15.     Dim M As Double, OrigY As Double
  16.     Dim Slopes(3) As Double
  17.     Dim intXY As Integer
  18.     Dim Rem1 As Integer, Rem2 As Integer
  19.     Dim intSlope As Integer
  20.     Dim obj(0) As AcadEntity
  21.     Dim ss As AcadSelectionSet
  22.     Dim blnBeginning As Boolean
  23.     Dim blnRemoved As Boolean
  24.    
  25.     cCount = (UBound(oPline.Coordinates) - 1) / 2
  26.    
  27.     NewCoordList.Add (0)
  28.     For i = 1 To cCount
  29.         Coord = oPline.Coordinate(i): PrevCoord = oPline.Coordinate(i - 1)
  30.         'Here we check for two equal verticies. Dont add them if they are equal.
  31.         If Rd(Coord(0), PrevCoord(0)) And Rd(Coord(1), PrevCoord(1)) Then GoTo skip
  32.             
  33.         DeltaX = Coord(0) - PrevCoord(0): DeltaY = Coord(1) - PrevCoord(1)
  34.         Slopes(2) = GetSlope(DeltaX, DeltaY, PrevCoord, M, OrigY)
  35.         Slopes(0) = M: Slopes(1) = OrigY
  36.         Slopes(3) = oPline.GetBulge(i - 1)
  37.         SlopeCol.Add Slopes
  38.         k = i
  39.         NewCoordList.Add (k)
  40. skip:
  41.     Next
  42.       
  43.     cCount = NewCoordList.Count
  44.     Debug.Print cCount
  45.     If cCount = 1 Then 'zero length pline
  46.         Set ss = ThisDrawing.SelectionSets("SS")
  47.         If j > -1 Then
  48.             Set obj(0) = ss(j)
  49.             ss.RemoveItems obj
  50.         End If
  51.         oPline.Delete
  52.         PolyVertexCheck = False
  53.         Exit Function '''''
  54.     End If
  55. BeginCheck:
  56.      If cCount > 2 Then
  57.         If SlopeCol.Count = 2 Then
  58.         'check for unneeded middle point in a straigth line
  59.             If SlopeCol(1)(3)  0 Then GoTo Skip2
  60.             If SlopeCol(2)(3)  0 Then GoTo Skip2
  61.             If Rd(SlopeCol(1)(0), SlopeCol(2)(0)) Then
  62.                 If Rd(SlopeCol(1)(1), SlopeCol(2)(1)) Then
  63.                     Coord = oPline.Coordinate(0)
  64.                     coord2 = oPline.Coordinate(1)
  65.                     Coord3 = oPline.Coordinate(2)
  66.                     If EqualPts(Coord, Coord3) Then
  67.                         NewCoordList.Remove cCount
  68.                         GoTo Skip2
  69.                     End If
  70.                     intSlope = SlopeCol(1)(2)
  71.                     If intSlope = 1 Then
  72.                         intXY = 1  'vertical
  73.                     Else
  74.                         intXY = 0
  75.                     End If
  76.                     
  77.                     If Coord(intXY) > coord2(intXY) Then
  78.                         If coord2(intXY) > Coord3(intXY) Then
  79.                             NewCoordList.Remove 2
  80.                         Else
  81.                             If Coord(intXY) > Coord3(intXY) Then
  82.                                 NewCoordList.Remove 3
  83.                             Else
  84.                                 NewCoordList.Remove 1
  85.                             End If
  86.                         End If
  87.                     Else
  88.                         If Coord(intXY) > Coord3(intXY) Then
  89.                                 NewCoordList.Remove 1
  90.                         Else
  91.                             If Coord3(intXY) > coord2(intXY) Then
  92.                                 NewCoordList.Remove 2
  93.                             Else
  94.                                 NewCoordList.Remove 3
  95.                             End If
  96.                         End If
  97.                     End If
  98.                 End If
  99.             End If
  100.         Else
  101.             For i = cCount To 3 Step -1
  102.                 'check for unneeded middle point in a straigth line
  103.                 If oPline.GetBulge(i - 1)  0 Then GoTo Skipi
  104.                 If oPline.GetBulge(i - 2)  0 Then GoTo Skipi
  105.                 If Rd(SlopeCol(i - 1)(0), SlopeCol(i - 2)(0)) Then
  106.                     If Rd(SlopeCol(i - 1)(1), SlopeCol(i - 2)(1)) Then
  107.                         Coord = oPline.Coordinate(NewCoordList(i))
  108.                         coord2 = oPline.Coordinate(NewCoordList(i - 1))
  109.                         Coord3 = oPline.Coordinate(NewCoordList(i - 2))
  110.                         If Rd(Coord(0), coord2(0)) Then 'vertical
  111.                             intXY = 1
  112.                         Else
  113.                             intXY = 0
  114.                         End If
  115.          
  116.    
  117.                          If i = cCount Then 'Double back at end
  118.                             If Coord(intXY) > Coord3(intXY) Then
  119.                                 If Coord(intXY)  coord2(intXY) Then
  120.                                     NewCoordList.Remove (i)
  121.                                     SlopeCol.Remove i - 1
  122.                                     blnRemoved = True
  123.                                     GoTo Skipi ''''''''''''''''''
  124.                                 End If
  125.                             End If
  126.                         End If
  127.                         
  128.                         If i - 3 = 0 Then 'Double back at beginning
  129.                             If Coord(intXY) > coord2(intXY) Then
  130.                                 If Coord(intXY) > Coord3(intXY) Then
  131.                                     If Coord3(intXY) > coord2(intXY) Then
  132.                                         NewCoordList.Remove (1)
  133.                                         SlopeCol.Remove 1
  134.                                         blnBeginning = True
  135.                                         blnRemoved = True
  136.                                         GoTo Skipi ''''''''''''''''''
  137.                                     End If
  138.                                 End If
  139.                             Else
  140.                                 If Coord(intXY)  coord2(intXY) Then
  141.                             If coord2(intXY) > Coord3(intXY) Then
  142.                                 NewCoordList.Remove (i - 1)
  143.                                 SlopeCol.Remove i - 2
  144.                                 blnRemoved = True
  145.                                 GoTo Skipi ''''''''''''''''''
  146.                             End If
  147.                         Else
  148.                             If coord2(intXY)  2 Then
  149.                 cCount = NewCoordList.Count
  150.                 For i = cCount To 4 Step -1
  151.                     If oPline.GetBulge(i - 1)  0 Then GoTo Skip2i
  152.                     If oPline.GetBulge(i - 2)  0 Then GoTo Skip2i
  153.                     If oPline.GetBulge(i - 3)  0 Then GoTo Skip2i
  154.                     If oPline.GetBulge(i - 4)  0 Then GoTo Skip2i
  155.                     'Not checking for arc double backs as they are so rare.
  156.                     intSlope = SlopeCol(i - 1)(2)
  157.                     If Not intSlope = SlopeCol(i - 2)(2) Then GoTo Skip2i
  158.                     If Not intSlope = SlopeCol(i - 3)(2) Then GoTo Skip2i
  159.                     If intSlope = 0 Then intXY = 0  'horiz
  160.                     If intSlope = 1 Then intXY = 1  'vertical
  161.                     If intSlope = 2 Then
  162.                         intXY = 2 ''''''''''''''''''''''2-15
  163.                         If Rd(SlopeCol(i - 1)(0), SlopeCol(i - 2)(0)) Then
  164.                             If Rd(SlopeCol(i - 2)(0), SlopeCol(i - 3)(0)) Then
  165.                                 If Rd(SlopeCol(i - 1)(1), SlopeCol(i - 2)(1)) Then
  166.                                     If Rd(SlopeCol(i - 2)(1), SlopeCol(i - 3)(1)) Then
  167.                                         intXY = 0
  168.                                     'Else: GoTo Skip2i ''''''''''''''''''''''''''
  169.                                     End If
  170.                                 End If
  171.                             End If
  172.                         End If
  173.                     End If
  174.                     
  175.                     If intXY > 1 Then GoTo Skip2i
  176.                                     
  177.    
  178.                     Coord = oPline.Coordinate(NewCoordList(i - 3))
  179.                     coord2 = oPline.Coordinate(NewCoordList(i - 2))
  180.                     Coord3 = oPline.Coordinate(NewCoordList(i - 1))
  181.                     Coord4 = oPline.Coordinate(NewCoordList(i))
  182.                     If Rd(Coord(0), coord2(0)) Then 'vertical
  183.                         intXY = 1
  184.                     Else
  185.                         intXY = 0
  186.                     End If
  187.                     Rem1 = -1: Rem2 = -1
  188.                     'code for double backs''''''''''''''''''''''''''''''
  189.                     If Coord(intXY)  Coord(intXY) Then
  190.                                     Rem1 = i - 1: Rem2 = i - 2
  191.                                 Else
  192.                                     Rem1 = i - 2: Rem2 = i - 3
  193.                                 End If
  194.                             End If
  195.                         Else
  196.                             If Coord3(intXY) > Coord(intXY) Then
  197.                                 Rem1 = i: Rem2 = i - 1
  198.                             Else
  199.                                 Rem1 = i: Rem2 = i - 3
  200.                             End If
  201.                         End If
  202.                     Else
  203.                         If coord2(intXY) > Coord4(intXY) Then
  204.                             If Coord3(intXY) > coord2(intXY) Then
  205.                                 If Coord3(intXY)  -1 Then
  206.                         NewCoordList.Remove Rem1
  207.                         SlopeCol.Remove Rem1 - 1
  208.                         i = i - 1
  209.                     End If
  210.                     If Rem2 > -1 Then
  211.                         NewCoordList.Remove Rem2
  212.                         'i = i - 1
  213.                         If Rem2 > 1 Then
  214.                             SlopeCol.Remove Rem2 - 1
  215.                         Else
  216.                             SlopeCol.Remove Rem2
  217.                         End If
  218.                     End If
  219.             
  220.                      
  221. Skip2i:
  222.             Next i
  223.         End If
  224.     End If
  225. End If
  226. Skip2:
  227.    
  228.    
  229.    
  230.     Dim NewPline As AcadLWPolyline
  231.     Dim Cwidth As Double
  232.     Dim blnNonConstantWidth As Boolean
  233.    
  234.     On Error Resume Next
  235.     Cwidth = oPline.ConstantWidth
  236.     If Err.Description = "Invalid input" Then
  237.         blnNonConstantWidth = True
  238.         Err.Clear
  239.     End If
  240.     On Error GoTo 0
  241.    
  242.     'check for should be closed
  243.     If oPline.Closed = False Then
  244.        Dim X1 As Double, Y1 As Double
  245.        Dim X2 As Double, Y2 As Double
  246.        Dim blnClosed As Boolean
  247.        X1 = oPline.Coordinate(NewCoordList(1))(0)
  248.        Y1 = oPline.Coordinate(NewCoordList(1))(1)
  249.        X2 = oPline.Coordinate(NewCoordList(NewCoordList.Count))(0)
  250.        Y2 = oPline.Coordinate(NewCoordList(NewCoordList.Count))(1)
  251.        If Fuzzed(X1, X2, PolyClosedFudge) Then
  252.            If Fuzzed(Y1, Y2, PolyClosedFudge) Then
  253.                NewCoordList.Remove (NewCoordList.Count)
  254.                blnClosed = True
  255.            End If
  256.        End If
  257.     End If
  258.     If Not NewCoordList.Count - 1 = (UBound(oPline.Coordinates) - 1) / 2 Then
  259.         Dim PtsCount As Integer
  260.         PtsCount = (NewCoordList.Count * 2) - 1
  261.         Dim pts() As Double
  262.         ReDim pts(PtsCount) As Double
  263.         cCount = NewCoordList.Count
  264.         For i = 1 To cCount
  265.             k = (i - 1) * 2
  266.             pts(k) = oPline.Coordinate(NewCoordList(i))(0)
  267.             pts(k + 1) = oPline.Coordinate(NewCoordList(i))(1)
  268.         Next
  269.         
  270.         
  271.         Set NewPline = CurrentSpace.AddLightWeightPolyline(pts)
  272.         If oPline.Closed = True Then
  273.             NewPline.Closed = True
  274.         End If
  275.         With NewPline
  276.             .Color = oPline.Color
  277.             .Elevation = oPline.Elevation
  278.             .Layer = oPline.Layer
  279.             .LineType = oPline.LineType
  280.             .LinetypeGeneration = oPline.LinetypeGeneration
  281.             .LineWeight = oPline.LineWeight
  282.             .Normal = oPline.Normal
  283.             .Thickness = oPline.Thickness
  284.             If Cwidth > 0 Then
  285.                 .ConstantWidth = Cwidth
  286.             End If
  287.             On Error GoTo 0
  288.             
  289.         End With
  290.         'For i = 1 To NewCoordList.Count
  291.         For i = 1 To SlopeCol.Count
  292.             k = i - 1
  293.             NewPline.SetBulge k, SlopeCol(i)(3)
  294.             If blnNonConstantWidth Then
  295.                 Dim StartWidth As Double, endWidth As Double
  296.                 oPline.GetWidth NewCoordList(i), StartWidth, endWidth
  297.                 NewPline.SetWidth k, StartWidth, endWidth
  298.             End If
  299.         Next
  300.         
  301.         If j = -1 Then
  302.             oPline.Delete
  303.             Set oPline = NewPline
  304.         Else
  305.             Set ss = ThisDrawing.SelectionSets("SS")
  306.             Set obj(0) = ss(j)
  307.             ss.RemoveItems obj
  308.             oPline.Delete
  309.             Set oPline = NewPline
  310.             If blnClosed = True Then
  311.                 oPline.Closed = True
  312.             Else
  313.                 Set obj(0) = oPline
  314.                 ss.AddItems obj
  315.             End If
  316.         End If
  317.         oPline.Update
  318.     End If
  319.    PolyVertexCheck = True
  320. End Function

回复

使用道具 举报

170

主题

1424

帖子

8

银币

顶梁支柱

Rank: 50Rank: 50

铜币
2119
发表于 2006-5-25 20:42:04 | 显示全部楼层
哦,他们看起来太久了,每个人在到达这里之前都会睡着。
回复

使用道具 举报

170

主题

1424

帖子

8

银币

顶梁支柱

Rank: 50Rank: 50

铜币
2119
发表于 2006-5-25 20:44:09 | 显示全部楼层
你有展示你的代码所做的例子的图像吗?
谢谢。
回复

使用道具 举报

发表回复

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

本版积分规则

  • 微信公众平台

  • 扫描访问手机版

  • 点击图片下载手机App

QQ|关于我们|小黑屋|乐筑天下 繁体中文

GMT+8, 2025-7-5 18:51 , Processed in 0.546180 second(s), 72 queries .

© 2020-2025 乐筑天下

联系客服 关注微信 帮助中心 下载APP 返回顶部 返回列表