加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

CASS或CAD中删除多余结点

(2008-04-09 18:37:11)
标签:

it

分类: 工作/开发方面
有两种方式:
注意:两点线如果距离小于0.1,则删除;且两点线不参加判断。
废话少说,贴代码啊!
 

Option Explicit

'正确的删除复合线多余结点过程
'错误的见DelOverlayVertex_Wrong过程
'但是DelOverlayVertex_Wrong能一次得到一组正确的坐标

Public Sub DelOverlayVertex()
'On Error Resume Next
  '定义选择集
  Dim LwPOlvtSelset As AcadSelectionSet
  Set LwPOlvtSelset = CreateSelectionSet
    
  '建立选择集过滤器
  Dim TypeArray As Variant
  Dim DateArray As Variant
  BuildFilter TypeArray, DateArray, 0, "LWPOLYLINE", 8, "jmd"
 
  LwPOlvtSelset.Select acSelectionSetAll, , , TypeArray, DateArray
 
  Dim LwPOlvt As AcadLWPolyline
  Dim i As Integer  '选择集的个数
  Dim k As Integer  '单个lwpolyline的结点
  '定义新旧结点
  Dim PtVtxOld As Variant
  Dim NewVtxCor() As Double
  ReDim Preserve NewVtxCor(1)
  '定义新坐标数组上维
  Dim UBound_K As Integer
 
  Dim d As Double   '定义结点距离
 
  Dim PtVtxAX As Double
  Dim PtVtxAY As Double
  Dim PtVtxAftAX As Double
  Dim PtVtxAftAY As Double
 
  For i = 0 To LwPOlvtSelset.Count - 1
     Set LwPOlvt = LwPOlvtSelset.Item(i)
         PtVtxOld = LwPOlvt.Coordinates
     Dim m As Integer
         m = UBound(PtVtxOld)    '第一次得到复合线上结点的个数
     '一组数据进行循环
     For k = 2 To m Step 2

        '线的长度小于规定值0.1,则删除这条线
        If LwPOlvt.Length < 0.1 Then LwPOlvt.Delete
       
        If k > m Then GoTo Do_Next
       
        '如果是两点线,则跳出循环
        If (m + 1) / 2 = 2 Then GoTo Do_Next
         '得到线实体的坐标数组
         PtVtxOld = LwPOlvt.Coordinates
         '第一个结点的坐标赋值给新坐标数组
         NewVtxCor(0) = PtVtxOld(0)
         NewVtxCor(1) = PtVtxOld(1)
        
        
         PtVtxAX = PtVtxOld(k - 2): PtVtxAY = PtVtxOld(k - 1)
         '新坐标数组的末尾
         'PtVtxAX = NewVtxCor(UBound(NewVtxCor()) - 1): PtVtxAY = NewVtxCor(UBound(NewVtxCor()))
         PtVtxAftAX = PtVtxOld(k): PtVtxAftAY = PtVtxOld(k + 1)
        
         d = Distance(PtVtxAX, PtVtxAftAX, PtVtxAY, PtVtxAftAY)
        
         '如果两结点距离小于规定值0.1,重新定义新坐标数组的维数
         Dim n As Integer
         If d < 4 Then
            UBound_K = UBound(PtVtxOld) - 2
            ReDim Preserve NewVtxCor(UBound_K)
            For n = k To UBound_K
              NewVtxCor(n) = PtVtxOld(n + 2)
            Next n
         Else
            UBound_K = UBound(PtVtxOld)
            ReDim Preserve NewVtxCor(UBound_K)
            For n = k To UBound(PtVtxOld)
              NewVtxCor(n) = PtVtxOld(n)
            Next n
         End If

         LwPOlvt.Coordinates = NewVtxCor()
         LwPOlvt.Update
         PtVtxOld = LwPOlvt.Coordinates   '更新复合线后再次得到复合线上结点的坐标数组
         m = UBound(PtVtxOld)             '更新复合线后再次得到复合线上结点的个数
        
     Next k

Do_Next:

  Next i
 
 
    '刷新操作
    ThisDrawing.Application.Update

End Sub

'错误
'*************************************************************************
'原因:
   LwPolyLine.Coordinates只能进行一个结点坐标更新,如果同时变动了很多
'结点坐标,那么程序运行CASS或CAD将出现致命错误。

'——————————————————————————————————
'调试方法1:
   根据新得到的一组坐标重新绘制LwPolyline,并提取以前那条线的扩展属性
'通过SetXData命令,把获取到的扩展属性赋值给新绘制的LwPolyLine。
   弊端:
   由于CAD中对于弧的存储是储存的弧的凸度,对凸度的描述如下图,那么重新
'绘制的时候就把以前的凸度去掉了。如果要重新绘制,就必须把以前有凸度的线条
'的凸度值取出来,然后再重新赋值给新绘制的线,对于这个还没有去研究

'——————————————————————————————————'
'调试方法2:
   见DelOverlayVertex过程,原理是选取前后两个结点坐标,执行一次,如果
'距离小于规定值,则删除错误的节点,然后执行
                   LwPolyline.Coordinates=PTs() PTs是新的一组坐标
                   LwPolyline.Update
'这样两组坐标循环一次,依次类推。

'——————————————————————————————————'
   本人采取调试方法2,因为调试方法1种对凸度怎么获取?怎么赋值没有了解。
'**************************************************************************
Public Sub DelOverlayVertex_Wrong()
'On Error Resume Next
  '定义选择集
  Dim LwPOlvtSelset As AcadSelectionSet
  Set LwPOlvtSelset = CreateSelectionSet
    
  '建立选择集过滤器
  Dim TypeArray As Variant
  Dim DateArray As Variant
  BuildFilter TypeArray, DateArray, 0, "LWPOLYLINE", 8, "jmd"
 
  LwPOlvtSelset.Select acSelectionSetAll, , , TypeArray, DateArray
 
  Dim LwPOlvt As AcadLWPolyline
  Dim i As Integer  '选择集的个数
  Dim k As Integer  '单个lwpolyline的结点
  '定义新旧结点
  Dim PtVtxOld As Variant
  Dim NewVtxCor() As Double
  ReDim Preserve NewVtxCor(1)
  '定义新坐标数组上维
  Dim UBound_K As Integer
 
  Dim d As Double   '定义结点距离
 
  Dim PtVtxAX As Double
  Dim PtVtxAY As Double
  Dim PtVtxAftAX As Double
  Dim PtVtxAftAY As Double
 
  For i = 0 To LwPOlvtSelset.Count - 1
     Set LwPOlvt = LwPOlvtSelset.Item(i)
         PtVtxOld = LwPOlvt.Coordinates
         '第一个结点的坐标赋值给新坐标数组
         NewVtxCor(0) = PtVtxOld(0)
         NewVtxCor(1) = PtVtxOld(1)
        
     '一组数据进行循环
     For k = 2 To UBound(PtVtxOld) Step 2
         'PtVtxAX = PtVtxOld(k - 2): PtVtxAY = PtVtxOld(k - 1)
         '新坐标数组的末尾
         PtVtxAX = NewVtxCor(UBound(NewVtxCor()) - 1): PtVtxAY = NewVtxCor(UBound(NewVtxCor()))
         PtVtxAftAX = PtVtxOld(k): PtVtxAftAY = PtVtxOld(k + 1)
        
         d = Distance(PtVtxAX, PtVtxAftAX, PtVtxAY, PtVtxAftAY)
        
         '如果两结点距离小于规定值0.1,则不赋值给新坐标数组
         If d > 1 Then
         '确定新坐标上维
           UBound_K = UBound(NewVtxCor()) + 2
           '重新定义新坐标数组上维
           ReDim Preserve NewVtxCor(UBound_K)
          
           NewVtxCor(UBound_K - 1) = PtVtxAftAX
           NewVtxCor(UBound_K) = PtVtxAftAY
        
         End If
     Next k

     '把坐标点导出
     Call aaa(NewVtxCor)
    
     '把新坐标数组赋值给lwpolyline的坐标数组
     LwPOlvt.Coordinates = NewVtxCor()

    'Dim nnn As AcadLWPolyline
    'ThisDrawing.ModelSpace.AddLightWeightPolyline NewVtxCor
   
   
  Next i
 
 
    '刷新操作
    ThisDrawing.Application.Update

End Sub

Public Sub aaa(p1)

'''
'''我将生成的文件保存在c盘,下面的目录是可以随便更改的
'''


Dim jj As Integer

 Open "C:\DelOlvtVtx.txt" For Output As #2
 For jj = 0 To UBound(p1)
 Print #2, p1(jj)
 
 Next jj
 Close #2
End Sub

 

'创建过滤器的函数
Public Sub BuildFilter(TypeArray, DataArray, ParamArray gCodes())
    Dim fType() As Integer, fData()
    Dim index As Long, i As Long
   
    index = LBound(gCodes) - 1
    For i = LBound(gCodes) To UBound(gCodes) Step 2
        index = index + 1
        ReDim Preserve fType(0 To index)
        ReDim Preserve fData(0 To index)
        fType(index) = CInt(gCodes(i))
        fData(index) = gCodes(i + 1)
    Next
    TypeArray = fType: DataArray = fData
   
End Sub


'创建空间选择集的函数
Public Function CreateSelectionSet(Optional ssName As String = "ss") As AcadSelectionSet

    Dim ss As AcadSelectionSet
    On Error Resume Next
    Set ss = ThisDrawing.SelectionSets(ssName)
    If Err Then Set ss = ThisDrawing.SelectionSets.Add(ssName)
    ss.Clear
    Set CreateSelectionSet = ss

End Function

'创建距离函数
Public Function Distance(x0 As Double, x1 As Double, y0 As Double, y1 As Double) As Double
   Dim d As Double
   d = Sqr((x0 - x1) ^ 2 + (y0 - y1) ^ 2)
   Distance = d
End Function

 

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有