乐筑天下

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

[原创]TlsBoundary类,专用于在块内按点生成填充

[复制链接]

72

主题

2726

帖子

9

银币

社区元老

Rank: 75Rank: 75Rank: 75

铜币
3014
发表于 2004-5-24 11:25:00 | 显示全部楼层 |阅读模式
'TlsBoundary类,专用于在块内按点生成填充
'编制:天龙工作室' You may use the code included in this module in any way,
' provided that both the above copyright notice and the
' release of liability (stated below) appear in all copies.
回复

使用道具 举报

72

主题

2726

帖子

9

银币

社区元老

Rank: 75Rank: 75Rank: 75

铜币
3014
发表于 2004-5-27 19:27:00 | 显示全部楼层
  1. 'TlsBoundary类,专用于在块内按点生成填充
  2. '编制:天龙工作室 ' You may use the code included in this module in any way,
  3. ' provided that both the above copyright notice and the
  4. ' release of liability (stated below) appear in all copies.
  5. Private pSouce As Object
  6. Private pBlock As AcadBlock
  7. Private pWorkSpace As AcadObject
  8. Private pRegions As Variant
  9. Private OuterLoop As AcadRegion
  10. Private InnerLoop As AcadRegionPrivate Sub Class_Terminate()
  11. On Error Resume Next
  12.       
  13.        pWorkSpace.Delete
  14.       
  15. End SubPrivate Function IsEqual(ByVal Value1 As Double, ByVal Value2 As Double) As Boolean       IsEqual = Abs(Value1 - Value2)  "AcDbLine" And _
  16.                                i.ObjectName  "AcDbCircle" And _
  17.                                i.ObjectName  "AcDbArc" And _
  18.                                i.ObjectName  "AcDbEllipse" _
  19.                        Then
  20.                                i.Explode
  21.                                Err.Clear
  22.                                i.Delete
  23.                                pCanBeExploded = True
  24.                        End If
  25.                        
  26.                Next i
  27.                
  28.        Loop
  29.       
  30. End SubPrivate Sub SortValue(ByRef Values As Variant, ByVal Count As Integer)
  31. '值排序
  32.        Dim pTemp As Double
  33.       
  34.        For i = Count To 1 Step -1
  35.       
  36.                For j = 0 To i - 1
  37.                
  38.                        If Values(j) > Values(j + 1) Then
  39.                                pTemp = Values(j + 1)
  40.                                Values(j + 1) = Values(j)
  41.                                Values(j) = pTemp
  42.                        End If
  43.                        
  44.                Next j
  45.                
  46.        Next i
  47. End SubPrivate Sub SortPoint(ByRef Values As Variant, ByRef Points As Variant, ByVal Count As Integer)
  48. '按值将点数组排序
  49.        Dim pTemp As Double, pnt As Variant
  50.       
  51.        For i = Count To 1 Step -1
  52.       
  53.                For j = 0 To i - 1
  54.                
  55.                        If Values(j) > Values(j + 1) Then
  56.                                pTemp = Values(j + 1)
  57.                                Values(j + 1) = Values(j)
  58.                                Values(j) = pTemp
  59.                                pnt = Points(j + 1)
  60.                                Points(j + 1) = Points(j)
  61.                                Points(j) = pnt
  62.                        End If
  63.                        
  64.                Next j
  65.                
  66.        Next i
  67.       
  68. End SubPrivate Function GetIntersection(ByVal TlsObject As AcadEntity, Optional ByVal Count)
  69. '获取图元的全部交点
  70.        Dim pnts(), dot
  71.        Dim pnt(2) As Double
  72.        Dim n As Integer
  73.        Dim i, j
  74.        Dim pNum As Integer
  75.       
  76.        If IsMissing(Count) Then Count = pSouce.Count
  77.       
  78.        For i = 0 To Count - 1
  79.       
  80.                If Not (TlsObject Is pSouce(i)) Then
  81.                
  82.                        dot = TlsObject.IntersectWith(pSouce(i), acExtendNone)
  83.                        n = (UBound(dot) + 1) / 3
  84.                        For j = 0 To n - 1
  85.                                pnt(0) = dot(j * 3)
  86.                                pnt(1) = dot(j * 3 + 1)
  87.                                ReDim Preserve pnts(pNum)
  88.                                pnts(pNum) = pnt
  89.                                pNum = pNum + 1
  90.                        Next j
  91.                        
  92.                End If
  93.                
  94.        Next i
  95.       
  96.        If pNum = 0 Then
  97.                GetIntersection = False
  98.        ElseIf pNum = 1 Then
  99.                If TlsObject.ObjectName = "AcDbLine" Then
  100.                        GetIntersection = pnts
  101.                ElseIf TlsObject.ObjectName = "AcDbCircle" Then
  102.                        GetIntersection = False
  103.                ElseIf Abs(TlsObject.EndAngle - TlsObject.StartAngle - Atn(1) * 8) > 10 ^ -8 Then
  104.                        GetIntersection = False
  105.                Else
  106.                        GetIntersection = pnts
  107.                End If
  108.        Else
  109.                GetIntersection = pnts
  110.        End If
  111.       
  112. End Function
  113. Private Function BreakLineAtPoint(ByVal TlsLine As AcadEntity, ByVal Points)
  114. '按点打断直线
  115.        Dim pStart, PEnd
  116.        Dim pNum As Integer
  117.        Dim pCount As Integer
  118.        Dim pDistances() As Double
  119.       
  120.        pStart = TlsLine.StartPoint
  121.        PEnd = TlsLine.EndPoint
  122.        pCount = UBound(Points)
  123.       
  124.        If Abs(Tan(TlsLine.Angle))  PEnd And pAngles(i)  PEnd And pAngles(i)  PEnd Then PEnd = PEnd + Atn(1) * 8
  125.       
  126.        '将角度排序
  127.        SortValue pAngles, pCount
  128.       
  129.        '打断椭圆
  130.        For i = 0 To pCount - 1
  131.                If Not IsEqual(pAngles(i), pAngles(i + 1)) Then
  132.                        Set pEllipse = pWorkSpace.AddEllipse(pCenter, pMajorAxis, pRadius)
  133.                        pEllipse.StartAngle = pAngles(i)
  134.                        pEllipse.EndAngle = pAngles(i + 1)
  135.                End If
  136.        Next i
  137.       
  138.        If IsEqual(PEnd - pStart, Atn(1) * 8) Then
  139.                If Abs(pAngles(pCount) - pAngles(0)) > 10 ^ -8 Then
  140.                        Set pEllipse = pWorkSpace.AddEllipse(pCenter, pMajorAxis, pRadius)
  141.                        pEllipse.StartAngle = pAngles(pCount)
  142.                        pEllipse.EndAngle = pAngles(0)
  143.                End If
  144.        Else
  145.                If Not IsEqual(pStart, pAngles(0)) Then
  146.                        Set pEllipse = pWorkSpace.AddEllipse(pCenter, pMajorAxis, pRadius)
  147.                        pEllipse.StartAngle = pStart
  148.                        pEllipse.EndAngle = pAngles(0)
  149.                End If
  150.                If Not IsEqual(PEnd, pAngles(pCount)) Then
  151.                        Set pEllipse = pWorkSpace.AddEllipse(pCenter, pMajorAxis, pRadius)
  152.                        pEllipse.StartAngle = pAngles(pCount)
  153.                        pEllipse.EndAngle = PEnd
  154.                End If
  155.        End If
  156.       
  157. End Function
  158. Private Function BreakObjectAtPoint(ByVal TlsObject As AcadEntity, Optional Count)
  159. '按交点打断图元
  160.        Dim pnts As Variant
  161.        Dim pobjs(0) As AcadEntity
  162.       
  163.        If IsMissing(Count) Then
  164.                pnts = GetIntersection(TlsObject)
  165.        Else
  166.                pnts = GetIntersection(TlsObject, Count)
  167.        End If
  168.       
  169.        If Not IsArray(pnts) Then
  170.                TlsObject.Copy
  171.        Else
  172.                Select Case TlsObject.EntityType
  173.                Case acLine
  174.                          Dim pLine As AcadLine
  175.                        Set pLine = TlsObject
  176.                        BreakLineAtPoint pLine, pnts
  177.                Case acCircle
  178.                        Dim pCircle As AcadCircle
  179.                        Set pCircle = TlsObject
  180.                        BreakCircleAtPoint pCircle, pnts
  181.                Case acArc
  182.                        Dim pArc As AcadArc
  183.                        Set pArc = TlsObject
  184.                        BreakArcAtPoint pArc, pnts
  185.                Case acEllipse
  186.                        Dim pEllipse As AcadEllipse
  187.                        Set pEllipse = TlsObject
  188.                        BreakEllipseAtPoint pEllipse, pnts
  189.                End Select
  190.        End If
  191.       
  192. End FunctionPublic Sub BreakAllAtPoint()
  193. '按交点打断所有图元
  194.        Dim pCount As Integer
  195.        Dim i As Integer
  196.       
  197.        If TypeOf pSouce Is AcadBlock Then Explode
  198.       
  199.        pCount = pSouce.Count
  200.       
  201.        For i = 0 To pCount - 1
  202.                BreakObjectAtPoint pSouce(i), pCount
  203.        Next i
  204.        For i = 0 To pCount - 1
  205.                If TypeOf pSouce Is AcadBlock Then
  206.                      pSouce(0).Delete
  207.                Else
  208.                      pSouce(i).Delete
  209.                End If
  210.        Next i
  211.       
  212. End SubPublic Sub CreateRegions()
  213. '创建面域
  214.        Dim pobjs() As AcadEntity
  215.       
  216.        If pBlock Is Nothing Then Exit Sub
  217.        BreakAllAtPoint
  218.        ReDim pobjs(pWorkSpace.Count - 1) As AcadEntity
  219.        For i = 0 To pWorkSpace.Count - 1
  220.                Set pobjs(i) = pWorkSpace(i)
  221.        Next i
  222.       
  223. On Error Resume Next
  224.        pRegions = pWorkSpace.AddRegion(pobjs)
  225.       
  226. End SubPrivate Function PointInRegion(ByVal TlsRegion, ByVal Point) As Boolean
  227. '判断点是否在面域内
  228.        Dim pCopy As AcadRegion, pRegion As AcadRegion
  229.        Dim pobjs(0) As AcadEntity
  230.        Set pCopy = TlsRegion.Copy
  231.        Set pobjs(0) = pWorkSpace.AddCircle(Point, 0.0001)
  232.        Set pRegion = pWorkSpace.AddRegion(pobjs)(0)
  233.        pRegion.Boolean acIntersection, pCopy
  234.        If pRegion.Area > 0 Then PointInRegion = True
  235.        pRegion.Delete
  236.        pobjs(0).Delete
  237.       
  238. End FunctionPrivate Function InRegion(ByVal TlsRegion, ByVal SubRegion) As Boolean
  239. '判断面域是否在面域内
  240.        Dim pCopy As AcadRegion, pRegion As AcadRegion
  241.        Dim pArea As Double
  242.        If SubRegion.Area >= TlsRegion.Area Then Exit Function
  243.        Set pCopy = TlsRegion.Copy
  244.        Set pRegion = SubRegion.Copy
  245.        pArea = pRegion.Area
  246.        pRegion.Boolean acIntersection, pCopy
  247.        If pRegion.Area = pArea Then InRegion = True
  248.        pRegion.Delete
  249.       
  250. End FunctionPrivate Function CreateLoop(ByVal Point) As Integer
  251. '创建边界
  252. On Error Resume Next
  253.        Dim i As Integer, j As AcadEntity
  254.        Dim m As Integer, n As Integer
  255.        Dim pobjs(0) As AcadEntity
  256.        Dim pRegion As AcadRegion
  257.        Dim pArea As Double
  258.        Dim pJudge As Boolean
  259.        Dim pCount As Integer
  260.       
  261.        '遍历面域数组找到包含点的最小面域
  262.        For i = 0 To UBound(pRegions)
  263.                If PointInRegion(pRegions(i), Point) Then
  264.                        pJudge = True
  265.                        If pArea  0 Then
  266.                                If pArea > pRegions(i).Area Then
  267.                                        pArea = pRegions(i).Area
  268.                                        n = i
  269.                                End If
  270.                        Else
  271.                                pArea = pRegions(i).Area
  272.                                n = i
  273.                        End If
  274.                End If
  275.        Next i
  276.       
  277.        CreateLoop = 0
  278.       
  279.        '找到外边界
  280.        If pJudge Then
  281.       
  282.                '复制外边界到目标块
  283.                CreateLoop = 1
  284.                Set pobjs(0) = pRegions(n)
  285.                ThisDrawing.CopyObjects pobjs, pBlock
  286.                Set OuterLoop = pBlock(pBlock.Count - 1)
  287.                m = 0
  288.                For i = 0 To UBound(pRegions)
  289.                        If i  n Then
  290.                        
  291.                                '找到内边界
  292.                                If InRegion(pRegions(n), pRegions(i)) Then
  293.                                        CreateLoop = 2
  294.                                        If m = 0 Then
  295.                                                Set pRegion = pRegions(i).Copy
  296.                                        Else
  297.                                                pRegion.Boolean acUnion, pRegions(i).Copy
  298.                                        End If
  299.                                        m = m + 1
  300.                                End If
  301.                        End If
  302.                Next i
  303.                
  304.                '复制内边界到目标块
  305.                If CreateLoop = 2 Then
  306.                        Set pobjs(0) = pRegion
  307.                        ThisDrawing.CopyObjects pobjs, pBlock
  308.                        Set InnerLoop = pBlock(pBlock.Count - 1)
  309.                        pRegion.Delete
  310.                End If
  311.        End If
  312.       
  313. End FunctionPublic Function CreateHatch(ByVal Point, ByVal PatternName As String, Optional PatternScale As Double = 1, Optional PatternAngle As Double = 0) As AcadHatch
  314. '创建填充
  315. On Error Resume Next
  316.        Dim i As Integer
  317.        Dim phatch As AcadHatch
  318.        Dim pJudge As Integer
  319.        Dim pobjs(0) As AcadEntity
  320.        Dim pInObjs As Variant
  321.       
  322.        If pBlock Is Nothing Then Exit Function
  323.       
  324.        pJudge = CreateLoop(Point)
  325.       
  326.        '有外边界时填充
  327.        If pJudge > 0 Then
  328.                Set phatch = pBlock.AddHatch(0, PatternName, False)
  329.                Set pobjs(0) = OuterLoop
  330.                phatch.AppendOuterLoop pobjs
  331.                
  332.                '有内边界时加入内边界
  333.                If pJudge = 2 Then
  334.                        pInObjs = InnerLoop.Explode
  335.                        If pInObjs(0).ObjectName = "AcDbRegion" Then
  336.                                For i = 0 To UBound(pInObjs)
  337.                                        Set pobjs(0) = pInObjs(i)
  338.                                        phatch.AppendInnerLoop pobjs
  339.                                Next i
  340.                        Else
  341.                                        Set pobjs(0) = InnerLoop
  342.                                        phatch.AppendInnerLoop pobjs
  343.                        End If
  344.                End If
  345.                
  346.                '生成填充
  347.                phatch.PatternScale = PatternScale
  348.                phatch.PatternAngle = PatternAngle / 45 * Atn(1)
  349.                phatch.Evaluate
  350.        End If
  351.       
  352.        '删除临时实体
  353.        OuterLoop.Delete
  354.        InnerLoop.Delete
  355.        For i = 0 To UBound(pInObjs)
  356.                pInObjs(i).Delete
  357.        Next i
  358.        Set CreateHatch = phatch
  359.       
  360. End Function
回复

使用道具 举报

0

主题

3

帖子

2

银币

初来乍到

Rank: 1

铜币
3
发表于 2013-12-3 00:57:00 | 显示全部楼层
感谢分享,学习
回复

使用道具 举报

1

主题

19

帖子

4

银币

初来乍到

Rank: 1

铜币
23
发表于 2017-12-6 22:33:00 | 显示全部楼层

哦哦,谢谢您
回复

使用道具 举报

72

主题

2726

帖子

9

银币

社区元老

Rank: 75Rank: 75Rank: 75

铜币
3014
发表于 2004-5-24 11:28:00 | 显示全部楼层

其中Break???AtPoint、GetIntersection、PointInRegion和InRegion函数可单独使用下面两个例子说明如何使用
  1. Sub Sample_TlsBoundary()
  2.        Dim pBlock As AcadBlock, pObj As AcadBlockReference
  3.        Dim a As New TlsBoundary
  4.        Dim pnt(2) As Double
  5.        Dim p1(2) As Double, p2(2) As Double, p3(2) As Double, p4(2) As Double
  6.        Set pBlock = ThisDrawing.Blocks.Add(pnt, "*U")
  7.        p2(0) = 10: p3(1) = 10
  8.        p4(0) = 3: p4(1) = 3
  9.        pBlock.AddLine(p1, p2).Layer = "01"
  10.        pBlock.AddLine(p1, p3).Layer = "01"
  11.        pBlock.AddLine(p2, p3).Layer = "01"
  12.        pBlock.AddCircle(p1, 1).Layer = "01"
  13.        pBlock.AddCircle(p2, 1).Layer = "01"
  14.        pBlock.AddCircle(p3, 1).Layer = "01"
  15.        pBlock.AddCircle(p4, 1).Layer = "01"
  16.        pnt(0) = 2: pnt(1) = 2
  17.        a.WorkSpace = pBlock
  18.        a.CreateRegions
  19.        a.CreateHatch(pnt, "ansi31", 0.5).Layer = "02"
  20.        a.CreateHatch(p4, "ansi31", 0.1, 90).Layer = "02"
  21.        p1(0) = -0.5
  22.        a.CreateHatch(p1, "ansi31", 0.1, 30).Layer = "02"
  23.        p2(0) = p2(0) + 0.5
  24.        a.CreateHatch(p2, "ansi31", 0.1, 60).Layer = "02"
  25.        p3(1) = p3(1) + 0.5
  26.        a.CreateHatch(p3, "ansi31", 0.1, 90).Layer = "02"
  27.        Set pObj = ThisDrawing.ModelSpace.InsertBlock(ThisDrawing.Utility.GetPoint(, vbCrLf & "请输入插入点"), pBlock.Name, 1, 1, 1, 0)
  28. End Sub
  1. Sub Sample_TlsBoundary_Break()
  2.        Dim pBoundary As New TlsBoundary
  3.        Dim SS As AcadSelectionSet
  4.        Dim pnts As Variant
  5.        Dim i As AcadEntity
  6.        Dim ft(0) As Integer, fd(0)
  7.        ft(0) = 0
  8.        fd(0) = "Line,Circle,Arc,Ellipse"
  9.        Set SS = ThisDrawing.ActiveSelectionSet
  10.        pBoundary.WorkSpace = SS
  11.        SS.SelectOnScreen ft, fd
  12.        pBoundary.BreakAllAtPoint
  13. End Sub
回复

使用道具 举报

72

主题

2726

帖子

9

银币

社区元老

Rank: 75Rank: 75Rank: 75

铜币
3014
发表于 2004-5-24 11:32:00 | 显示全部楼层
这是例子的填充效果图
        

e13rob3cf4j.jpg

e13rob3cf4j.jpg

回复

使用道具 举报

27

主题

103

帖子

7

银币

后起之秀

Rank: 20Rank: 20Rank: 20Rank: 20

铜币
211
发表于 2004-5-27 09:37:00 | 显示全部楼层
谢谢>学习
回复

使用道具 举报

0

主题

2

帖子

1

银币

初来乍到

Rank: 1

铜币
2
发表于 2004-9-30 09:10:00 | 显示全部楼层
版主,为什么会有出错提示:未找到主键?
回复

使用道具 举报

0

主题

2

帖子

1

银币

初来乍到

Rank: 1

铜币
2
发表于 2004-9-30 12:13:00 | 显示全部楼层
还有执行
Sub Sample_TlsBoundary_Break()
                         Dim pBoundary As New TlsBoundary
                         Dim SS As AcadSelectionSet
                         Dim pnts As Variant
                         Dim i As AcadEntity
                         Dim ft(0) As Integer, fd(0)
                         ft(0) = 0
                         fd(0) = "Line,Circle,Arc,Ellipse"
                         Set SS = ThisDrawing.ActiveSelectionSet
                         pBoundary.WorkSpace = SS
                         SS.SelectOnScreen ft, fd
                         pBoundary.BreakAllAtPoint
End Sub
       
时pBoundary.WorkSpace = SS处有类型不匹配提示!
回复

使用道具 举报

72

主题

2726

帖子

9

银币

社区元老

Rank: 75Rank: 75Rank: 75

铜币
3014
发表于 2004-9-30 20:36:00 | 显示全部楼层
这里要改一下 Public Property Let WorkSpace(ByVal Value As AcadBlock)
改为
Public Property Let WorkSpace(ByVal Value)
未找到主键的问题我没有碰到过,我在2002和2005下都调试通过了的
回复

使用道具 举报

发表回复

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

本版积分规则

  • 微信公众平台

  • 扫描访问手机版

  • 点击图片下载手机App

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

GMT+8, 2024-11-21 23:58 , Processed in 0.302848 second(s), 75 queries .

© 2020-2024 乐筑天下

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