新浪博客

CASS或CAD中删除多余结点

2008-04-09 18:37阅读:
有两种方式:
注意:两点线如果距离小于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

我的更多文章

下载客户端阅读体验更佳

APP专享