乐筑天下

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

偏移折线

[复制链接]

15

主题

109

帖子

6

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
169
发表于 2005-9-27 13:16:18 | 显示全部楼层 |阅读模式
有人有类似于AutoCAD中offset命令的偏移多段线的代码示例吗?

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

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

使用道具 举报

71

主题

928

帖子

8

银币

顶梁支柱

Rank: 50Rank: 50

铜币
1230
发表于 2005-9-27 16:31:15 | 显示全部楼层
几年前,我用vba做了一件事,用拉伸一边的折线轮廓来计算一些断裂金属弯曲。这是相当多的代码。如果你想解析它得到你想要的,我会很乐意张贴。
回复

使用道具 举报

15

主题

109

帖子

6

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
169
发表于 2005-9-27 18:46:31 | 显示全部楼层

谢谢你的提议,我很感激。
我对需要做什么有一个很好的想法,但我似乎无法弄清楚起点。我看到的方式是,折线可以由数百个段组成(我只对直线段感兴趣,没有像凸起这样的花哨的东西),并且可以打开或关闭。第一步是确定偏移位于哪一侧(左、右、上、下、内或外)。每个线段需要沿垂直于线段的线偏移一定量。垂直线是指向正确偏移方向(正或负)的垂直方向。一旦我有了正确的垂直线,我就可以很容易地创建线段的偏移量。由于所有折线都是顺时针或逆时针的,我几乎可以使用第一个垂直线作为参考,告诉我每个段都使用正或负垂直偏移。从那里开始,只需找到相邻线段的所有交点并构造偏移图元即可。
我希望这是有道理的。我在确定垂直偏移应为负数还是正数时遇到问题。我很想发布一个图表,但我要到下周才能访问适当的系统。
回复

使用道具 举报

15

主题

109

帖子

6

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
169
发表于 2005-9-27 19:01:32 | 显示全部楼层
嗨,Troy,
我觉得你对这件事看得太深了。偏移直线而不是单个线段不是更容易吗?相对于绘制方向,折线向右偏移一个正值,向左偏移一个负值。因此,当偏移为给定距离时,只需找到所选的边,并找到指定点处的垂直距离作为“通过”距离。
这是否使事情变得更简单了?
回复

使用道具 举报

15

主题

109

帖子

6

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
169
发表于 2005-9-28 07:42:55 | 显示全部楼层

杰夫,这确实让事情更简单了!我看看今天能不能算出这道数学题。谢谢
回复

使用道具 举报

116

主题

996

帖子

9

银币

顶梁支柱

Rank: 50Rank: 50

铜币
1466
发表于 2005-9-28 08:07:35 | 显示全部楼层
好吧,如果你能做到这一点,那么这可能是过度杀戮,但无论如何都是这样。这里会有比你感兴趣的更多的东西,我很抱歉糟糕的编码技术,但这是几年前的事了。当然,您不会对凸起感兴趣,但我需要它们来显示钣金弯曲。
这是表单代码:
  1. 'frmMain
  2. Option Explicit
  3. ' form scope variables
  4. ' the offset (thickness of the shape)
  5. Private dOffset As Double
  6. ' Insertion Point
  7. Private Ipt(0 To 2) As Double
  8. ' Viewport scale
  9. Private ViewScale As Double
  10. ' how many breaks
  11. Private Breaks As Integer
  12. ' the blank length
  13. Private brkLength As Double
  14. ' break calculation modifier
  15. Private dblModifier As Double
  16. Private Sub Go()
  17.     Dim varCoords As Variant
  18.     Dim NewCoords() As Double
  19.     ' the three points necessary to build an angular dimension
  20.     Dim pt1(0 To 2) As Double
  21.     Dim pt2(0 To 2) As Double
  22.     Dim pt3(0 To 2) As Double
  23.     Dim varRet As Variant
  24.     Dim varStPt As Variant
  25.     Dim ObjEntity As AcadLWPolyline
  26.     Dim objNewEntity As AcadLWPolyline
  27.     Dim angle1 As Double
  28.     Dim angle2 As Double
  29.     Dim angle3 As Double
  30.     Dim Dir1 As Double
  31.     Dim Dir2 As Double
  32.     Dim DistTemp As Double
  33.     Dim Dist1 As Double
  34.     Dim Dist2 As Double
  35.     Dim Plus As Boolean
  36.     Dim aPlus As Boolean
  37.     Dim I As Integer
  38.     Dim J As Integer
  39.     Dim count As Integer
  40.     Dim NewCount As Integer
  41.     Dim currentY As Integer
  42.     Dim currentOppY As Integer
  43.     Dim ProjectExist As Boolean
  44.     Dim CurrSegCount As Integer
  45.     Dim CurrOppSegCount As Integer
  46.     Dim BulgeArray() As Integer
  47.     Dim AngleArray() As Double
  48.     Const x = 0
  49.     Const y = 1
  50.    
  51.     ' get the ployline
  52.     Set ObjEntity = Get_Poly
  53.    
  54.     ' if it's a closed polyline then it's going to look funky
  55.     If ObjEntity.Closed Then
  56.         MsgBox "This is a closed polyline, Hmmm..." & vbCr & _
  57.                "I REALLY Don't think you want to do that.. I quit"
  58.         End
  59.     End If
  60.    
  61.     varCoords = ObjEntity.Coordinates
  62.     ' if there are less than 5 points then you can't
  63.     ' get an angle
  64.     If UBound(varCoords)  9.3 Or Height > 6.5 Then
  65.         ThisDrawing.SetVariable "Dimscale", 2
  66.         ViewScale = 0.5
  67.     Else
  68.         ThisDrawing.SetVariable "Dimscale", 1
  69.         ViewScale = 1
  70.     End If
  71.    
  72.     ' dimension the original one
  73.     Call DoDims(varCoords, ObjEntity)
  74.    
  75. End Sub
  76. ' takes a vector and a direction from the vector and returns
  77. ' whether or not the offset side perpendicular would be an addition
  78. ' of ninety degrees or a subtraction of ninety degrees from the
  79. ' original vector direction
  80. Private Function isPlus(Vector As Double, Side As Double) As Boolean
  81.     Dim angle1 As Double
  82.     Dim angle2 As Double
  83.     angle1 = Vector
  84.     angle2 = Vector + dtr(180)
  85.     If angle2 > dtr(360) Then angle2 = angle2 - dtr(360)
  86.     If angle2 > angle1 Then ' angle 2 is the large one
  87.         If Side > angle1 And Side  angle2 And Side  Vector2 Then
  88.         SmallAngle = Vector1 - Vector2
  89.     Else
  90.         SmallAngle = Vector2 - Vector1
  91.     End If
  92.     If SmallAngle > dtr(180) Then SmallAngle = dtr(360) - SmallAngle
  93. End Function
  94. Private Sub cmdGo_Click()
  95.     ' get the aluminum thickness and select the
  96.     ' modifier and the thickness
  97.     Select Case listType.ListIndex
  98.         Case 0
  99.             dblModifier = 0.076
  100.             dOffset = 0.05
  101.         Case 1
  102.             dblModifier = 0.095
  103.             dOffset = 0.0625
  104.         Case 2
  105.             dblModifier = 0.1425
  106.             dOffset = 0.09
  107.         Case 3
  108.             dblModifier = 0.19
  109.             dOffset = 0.125
  110.         Case 4
  111.             dblModifier = 0.285
  112.             dOffset = 0.1875
  113.         Case Else
  114.         ' this should never happen so inform the user and exit
  115.             MsgBox "Something is wrong, see the programmer: "
  116.             Exit Sub
  117.     End Select
  118.     Me.Hide
  119.     Call Go
  120.     Call MakeLayout
  121. End Sub
  122. Private Sub DoDims(varCoords As Variant, ObjEntity As AcadEntity)
  123.     Dim txtHeight As Double
  124.     Dim DimOffset As Double
  125.     ' the three points necessary to build an angular dimension
  126.     Dim pt1(0 To 2) As Double
  127.     Dim pt2(0 To 2) As Double
  128.     Dim pt3(0 To 2) As Double
  129.     ' running blank and total length
  130.     Dim dblLength As Double
  131.     Dim dblTotalLength As Double
  132.     ' included angle for calculations
  133.     Dim dblAngle As Double
  134.     ' distance between the 2 end points for calculating
  135.     ' the dimension text location
  136.     Dim dblDist As Double
  137.     ' use x for x and y for y, z for z if needed
  138.     Const x = 0: Const y = 1: Const z = 2
  139.     ' integer counter
  140.     Dim I As Integer
  141.     ' left and right points for the dimensions
  142.     Dim lpt As Variant
  143.     Dim rpt As Variant
  144.     ' get the drawing scale and set the text height and dimension var's
  145.     DwgScale = ThisDrawing.GetVariable("dimscale")
  146.     txtHeight = DwgScale * 0.125
  147.     DimOffset = DwgScale * 1
  148.     ' point for the angular text location (temporary)
  149.     Dim varPT As Variant
  150.     ' dimension object (temporary)
  151.     Dim objDim As AcadDimAngular
  152.     ' set the initial length to zero
  153.     dblLength = 0
  154.     dblTotalLength = 0
  155.         
  156.     ' loop thru the polyline, extract the vertexes
  157.     ' and calculate the angles, length and break distances
  158.     For I = 5 To UBound(varCoords) Step 2
  159.         ' points 1 thru 3
  160.         pt1(x) = varCoords(I - 5)
  161.         pt1(y) = varCoords(I - 4)
  162.         pt2(x) = varCoords(I - 3)
  163.         pt2(y) = varCoords(I - 2)
  164.         pt3(x) = varCoords(I - 1)
  165.         pt3(y) = varCoords(I)
  166.         ' add linear dimensions
  167.         lpt = pt1
  168.         rpt = pt2
  169.         ' get the angle of the first line so we can draw the dimension
  170.         dblAngle = ThisDrawing.Utility.AngleFromXAxis(pt1, pt2)
  171.         ' draw the dimension
  172.         Call DrawDim(lpt, rpt, DimOffset, dblAngle, "STD1")
  173.         ' test for the last line segment and if it is then draw the dimension
  174.         If I = UBound(varCoords) Then
  175.             lpt = pt2
  176.             rpt = pt3
  177.             dblAngle = ThisDrawing.Utility.AngleFromXAxis(pt2, pt3)
  178.             Call DrawDim(lpt, rpt, DimOffset, dblAngle, "STD1")
  179.         End If
  180.         ' add the length of point 1 and 2
  181.         dblLength = dblLength + Distance(pt1, pt2)
  182.         dblTotalLength = dblTotalLength + Distance(pt1, pt2)
  183.         ' get the distance of the 2 outer end points
  184.         dblDist = Distance(pt1, pt3)
  185.         ' get the angle so we can get the halfway point
  186.         dblAngle = ThisDrawing.Utility.AngleFromXAxis(pt1, pt3)
  187.         ' get the halfway point , we will use this to give us
  188.         ' a text location for the temporary dimension
  189.         varPT = ThisDrawing.Utility.PolarPoint _
  190.                     (pt1, dblAngle, 0.5 * dblDist)
  191.         ' draw the dimension
  192.         Set objDim = ThisDrawing.ModelSpace.AddDimAngular _
  193.                     (pt2, pt1, pt3, varPT)
  194.         ' get the angle between the two segments
  195.         dblAngle = rtd(objDim.Measurement)
  196.         ' if more than ninety then use the excluded angle
  197.         If dblAngle > 90 Then
  198.             dblAngle = 180 - dblAngle
  199.         End If
  200.         ' subtract the break length calculated
  201.         dblLength = dblLength - ((dblAngle / 90) * dblModifier)
  202.         ' if this is the last one then add the last chord
  203.         If I = UBound(varCoords) Then
  204.             dblLength = dblLength + Distance(pt2, pt3)
  205.             dblTotalLength = dblTotalLength + Distance(pt2, pt3)
  206.         End If
  207.     Next I
  208.     ' show the user what the length is
  209.     ' now it's time to get the text location
  210.     ' get the bounding box coordinates
  211.     Dim varMin As Variant
  212.     Dim varMax As Variant
  213.     ObjEntity.GetBoundingBox varMin, varMax
  214.    
  215.     ' set the center point to be used by the viewport code
  216.     Ipt(0) = ((varMax(0) - varMin(0)) / 2) + varMin(0)
  217.     Ipt(1) = ((varMax(1) - varMin(1)) / 2) + varMin(1)
  218.    
  219.     ' set the break length variable to be used in the title block
  220.     brkLength = dblLength
  221.     ' delete the original polyline because we don't need it anymore
  222.     ObjEntity.Delete
  223.     ' now, let's zoom extents so you can see it all, baby
  224.     ThisDrawing.Application.ZoomCenter Ipt, 1
  225.    
  226. End Sub

回复

使用道具 举报

0

主题

3

帖子

1

银币

初来乍到

Rank: 1

铜币
3
发表于 2005-9-28 08:08:32 | 显示全部楼层
我不得不把它分解,因为它太长了
frmMain 代码的第二部分
  1. Private Sub MakeLayout()
  2.     Dim strTitleBlock As String
  3.     Dim strFile
  4.     Dim I As Long
  5.     Dim objLayout As AcadLayout
  6.     Dim objViewPort As AcadPViewport
  7.     Dim objObject As AcadObject
  8.     Dim BlkRef As AcadBlockReference
  9.     Dim Ipt1(0 To 2) As Double
  10.     On Error GoTo err_Handler
  11.     strTitleBlock = "TitleBlock"
  12.     ' NOTE: The drawing 'BKML.dwg' must be in the support path
  13.     strFile = "BKMTL.dwg"
  14.     ' first, let's add the layout
  15.     Set objLayout = ThisDrawing.Layouts.Add(strTitleBlock)
  16.     ' zoom the drawint
  17.     Application.ZoomCenter Ipt, ViewScale
  18.     ' make the layout and go to paper space
  19.     ThisDrawing.ActiveLayout = ThisDrawing.Layouts(strTitleBlock)
  20.     ThisDrawing.ActiveSpace = acPaperSpace
  21.     ' set the insertion point to 0,0
  22.     Ipt1(0) = 0: Ipt1(1) = 0
  23.     ' insert the title block
  24.     Set BlkRef = ThisDrawing.PaperSpace.InsertBlock(Ipt1, strFile, 1, 1, 1, 0)
  25.     ThisDrawing.Application.ZoomCenter Ipt, ViewScale
  26.     ' set the middle of the viewport
  27.     Ipt1(0) = 4.9375: Ipt1(1) = 5#
  28.     Set objViewPort = ThisDrawing.PaperSpace.AddPViewport(Ipt1, 9.375, 6.625)
  29.     ThisDrawing.ActiveSpace = acModelSpace
  30.     ' zoom the viewport
  31.     ThisDrawing.Application.ZoomCenter Ipt, ViewScale
  32.     ' go back to paper space
  33.     ThisDrawing.ActiveSpace = acPaperSpace
  34.     objViewPort.Visible = True
  35.     objViewPort.Display True
  36.     objViewPort.StandardScale = acVpCustomScale
  37.     objViewPort.CustomScale = ViewScale
  38.     objViewPort.DisplayLocked = True
  39.     ThisDrawing.Regen acAllViewports
  40.     ThisDrawing.Application.ZoomExtents
  41.    
  42.     ' now, delete all of the layouts
  43.     Set objLayout = Nothing
  44.     For Each objLayout In ThisDrawing.Layouts
  45.         If objLayout.Name = "Layout1" Then
  46.             objLayout.Delete
  47.         ElseIf objLayout.Name = "Layout2" Then
  48.             objLayout.Delete
  49.         End If
  50.     Next objLayout
  51.     ' now let's insert the Title Info and fill in the data
  52.     Dim varAttrib As Variant
  53.     Dim attribObj As AcadAttributeReference
  54.     ' the block name
  55.     strFile = "BrkInfo"
  56.     ' set the insertion point
  57.     Ipt1(0) = 0.25: Ipt1(1) = 1.1875
  58.     ' round the blank length to 3 spaces
  59.     brkLength = RoundExt(brkLength, 3)
  60.     Set BlkRef = ThisDrawing.PaperSpace.InsertBlock(Ipt1, strFile, 1, 1, 1, 0)
  61.         varAttrib = BlkRef.GetAttributes
  62.     ' fix the attributes text strings
  63.     For I = LBound(varAttrib) To UBound(varAttrib)
  64.         Set attribObj = varAttrib(I)
  65.         Select Case attribObj.TagString
  66.             Case "QUANTITY"
  67.                 attribObj.TextString = "1"
  68.             Case "MARK"
  69.                 attribObj.TextString = "A"
  70.             Case "DESC"
  71.                 attribObj.TextString = "Description"
  72.             Case "LENGTH"
  73.                 attribObj.TextString = "1"
  74.             Case "BLANK"
  75.                 attribObj.TextString = CStr(brkLength)
  76.             Case "BREAKS"
  77.                 attribObj.TextString = CStr(Breaks)
  78.             Case "BAYMARK"
  79.                 attribObj.TextString = "Bay"
  80.             Case "REMARKS"
  81.                 attribObj.TextString = "Remarks"
  82.             Case Else
  83.         End Select
  84.     Next I
  85.     ' update the blkreference
  86.     BlkRef.Update
  87.     ' Finished - Yeah
  88.     Exit Sub
  89. err_Handler:
  90.     Select Case Err.Number
  91.         Case -2145386475 ' Title block layout already exists
  92.             Err.Clear
  93.             MsgBox "You already have a Title Block Layout " & vbCr & _
  94.                     "Make sure You aren't duplicating Title BLocks"
  95.             Resume Next
  96.         Case Else
  97.             MsgBox Err.Number & " " & Err.Description
  98.     End Select
  99. End Sub
  100. Private Sub UserForm_Initialize()
  101. ' fill the aluminum thickenss text box
  102.     listType.AddItem "0.05"
  103.     listType.AddItem "0.0625"
  104.     listType.AddItem "0.09"
  105.     listType.AddItem "0.125"
  106.     listType.AddItem "0.1875"
  107.     ' set the initial index to the first one
  108.     listType.ListIndex = 0
  109. End Sub

[code][/code]
回复

使用道具 举报

12

主题

150

帖子

3

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
198
发表于 2005-9-28 08:10:18 | 显示全部楼层
这是来自主模块的代码,其中包含一些帮助函数,我不能将其中的几个归功于它们:
希望这能有所帮助...
回复

使用道具 举报

0

主题

3

帖子

1

银币

初来乍到

Rank: 1

铜币
3
发表于 2005-10-3 08:36:43 | 显示全部楼层
Draftek,谢谢你发布代码!我会看看它,看看它是如何工作的 numBulge Then
            newbulge(numBulge - idx) = polyEnt.GetBulge(idx) * -1
            
            Else
            
            newbulge(0) = polyEnt.GetBulge(idx) * -1
            
          End If
        Next idx
        
'reverse the original pline
        polyEnt.Coordinates = newcoord
        
        For idx = 0 To numBulge
        
          If idx = 0 Then
            polyEnt.SetBulge (numBulge), newbulge(idx)
          Else
            polyEnt.SetBulge (idx - 1), newbulge(idx)
          End If
            
        Next idx
        
        polyEnt.Update
End Sub[/code]
这会将LWPolyline转换为2D多边形。非常适合旧的CNC程序,当您必须在代码的末尾使用2D poly a时。ACAD在LW多段线(sendCommand)上使用Pedit做得更好:
  1. Public Function polyentconvert(polyEnt As Object) As AcadPolyline
  2. Dim entity As AcadDocument
  3. Set entity = AutoCAD_Application.ActiveDocument
  4. Dim I As Integer, j As Integer, K As Integer
  5. If polyEnt.EntityName = "AcDbPolyline" Then
  6.   Dim Coords As Variant
  7.   Coords = polyEnt.Coordinates
  8.   I = Fix((UBound(Coords) + 1) * 1.5) - 1
  9.   ReDim Coords2(I) As Double
  10.   j = 0
  11.   Dim X As Double, y As Double, z As Double
  12.   For I = LBound(Coords) To UBound(Coords) Step 2
  13.     X = Coords(I): y = Coords(I + 1): z = 0#
  14.     Coords2(j) = X:
  15.     Coords2(j + 1) = y:
  16.     Coords2(j + 2) = z:
  17.     j = j + 3
  18.   Next I
  19.   Dim Coords2V As Variant
  20.   Coords2V = Coords2
  21.   Dim EN2 As AcadPolyline
  22.   Set EN2 = entity.ModelSpace.AddPolyline(Coords2V)
  23.   EN2.Closed = polyEnt.Closed
  24.   EN2.Color = polyEnt.Color
  25.   EN2.Linetype = polyEnt.Linetype
  26.   EN2.Thickness = polyEnt.Thickness
  27.     EN2.Layer = polyEnt.Layer
  28.   Dim b As Double, w As Double, W2 As Double
  29.   For I = 0 To UBound(Coords) Step 2
  30.     j = I / 2
  31.     b = polyEnt.GetBulge(j)
  32.     polyEnt.GetWidth j, w, W2
  33.     EN2.SetBulge j, b
  34.     EN2.SetWidth j, w, W2
  35.   Next I
  36.   Dim polyentx As AcadPolyline
  37.   Set polyentx = EN2
  38.   polyEnt.Delete
  39. End If
  40. End Function

大部分代码都可以贡献给Malcom Fernadaz。他的代码delt带有开放多段线。我修改了它以处理封闭的
回复

使用道具 举报

0

主题

3

帖子

1

银币

初来乍到

Rank: 1

铜币
3
发表于 2005-10-3 10:34:08 | 显示全部楼层
非常感谢你,戴维!
回复

使用道具 举报

发表回复

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

本版积分规则

  • 微信公众平台

  • 扫描访问手机版

  • 点击图片下载手机App

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

GMT+8, 2025-7-4 17:19 , Processed in 0.655239 second(s), 72 queries .

© 2020-2025 乐筑天下

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