乐筑天下

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

两点之间沿多段线的距离

[复制链接]

24

主题

1265

帖子

1028

银币

后起之秀

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

铜币
362
发表于 2007-10-31 15:59:45 | 显示全部楼层 |阅读模式
当然,在lisp中,可以使用vlax curve getDistAtPoint
关于如何在VBA中实现这一点,最近有什么进展吗&nbsp&nbsp
TIA
回复

使用道具 举报

24

主题

1265

帖子

1028

银币

后起之秀

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

铜币
362
发表于 2007-10-31 16:48:57 | 显示全部楼层
如果你还记得Frank Oquendo….他为那些仍在VBA中的人写了一个名为VLAX Curve class的东西,这里有一条捷径可以抓住它:[更多提示,这是一个zip文件][和….hth]http://discussion.autodesk.com/thread.jspa?threadID=502098
回复

使用道具 举报

170

主题

1424

帖子

8

银币

顶梁支柱

Rank: 50Rank: 50

铜币
2119
发表于 2007-11-1 10:28:14 | 显示全部楼层
谢谢李。效果很好
回复

使用道具 举报

170

主题

1424

帖子

8

银币

顶梁支柱

Rank: 50Rank: 50

铜币
2119
发表于 2007-11-4 11:31:27 | 显示全部楼层
这里是#039;这是一种Vba方式,它比我想象的要难一些,因为我已经有了它#039;s mate,在距离处获取点。
  1. Option Explicit
  2. Const PI As Double = 3.14159265358979
  3. Sub TestPt()
  4.     Dim oPline As AcadLWPolyline
  5.     Dim Util As AcadUtility
  6.     Dim Varpick As Variant
  7.    
  8.     Set Util = ThisDrawing.Utility
  9.     Util.GetEntity oPline, Varpick, "Pick a poly:"
  10.     Varpick = ThisDrawing.Utility.GetPoint(, "Point on poly")
  11.     Debug.Print LengthAtPointOnPoly(oPline, Varpick)
  12.    
  13. End Sub
  14. Function LengthAtPointOnPoly(oPline As AcadLWPolyline, Varpick As Variant) As Double
  15.     Dim Dist As Double, TotalDist As Double
  16.     Dim dBulge As Double, seg As Double
  17.     Dim Pt(1) As Double
  18.     Dim C1, C2
  19.     Dim Ct As Integer, i As Long
  20.     Dim Util As AcadUtility
  21.    
  22.     Set Util = ThisDrawing.Utility
  23.     Varpick = Util.TranslateCoordinates(Varpick, acWorld, acOCS, False, oPline.Normal)
  24.     If Not Rd(Varpick(2), oPline.Elevation) Then Exit Function
  25.     Pt(0) = Varpick(0): Pt(1) = Varpick(1)
  26.     Ct = (UBound(oPline.Coordinates) - 1) / 2
  27.     If oPline.Closed = True Then Ct = Ct + 1
  28.     ReDim Coords(Ct) As Variant
  29.     For i = 0 To Ct - 1
  30.         Coords(i) = oPline.Coordinate(i)
  31.     Next
  32.     If oPline.Closed = True Then
  33.         Coords(Ct) = oPline.Coordinate(0)
  34.     Else
  35.         Coords(Ct) = oPline.Coordinate(Ct)
  36.     End If
  37.         
  38.     For i = 0 To Ct - 1
  39.         C1 = Coords(i)
  40.         C2 = Coords(i + 1)
  41.         dBulge = oPline.GetBulge(i)
  42.         seg = Length(C1, C2)
  43.         If dBulge = 0 Then
  44.             If isOnLine(C1, C2, Pt) Then
  45.                 TotalDist = TotalDist + Length(C1, Pt)
  46.                 Exit For
  47.             Else
  48.                 TotalDist = TotalDist + seg
  49.                 If i = Ct - 1 Then TotalDist = 0
  50.             End If
  51.          Else
  52.             If isPtonArc(C1, C2, Pt, dBulge, seg, Dist) Then
  53.                 TotalDist = TotalDist + Dist
  54.                 Exit For
  55.             Else
  56.                 TotalDist = TotalDist + polyarclength(dBulge, seg)
  57.                 If i = Ct - 1 Then TotalDist = 0
  58.             End If
  59.       
  60.         End If
  61.     Next i
  62.     LengthAtPointOnPoly = TotalDist
  63.    
  64. End Function
  65. Private Function isPtonArc(C1 As Variant, C2 As Variant, Pt As Variant, _
  66.                 dBulge As Double, seg As Double, Dist As Double) As Boolean
  67.     Dim Rad As Double
  68.     Dim X As Double, Y As Double
  69.     Dim deltaX As Double, deltaY As Double
  70.     Dim Slope As Double, Invertslope As Double
  71.     Dim dLength As Double, AngX As Double
  72.     Dim CenPt(1) As Double
  73.     Dim bOnArc As Boolean
  74.     Dim iLeft As Integer
  75.    
  76.     'IncludedAng = Atn(dBulge) * 4 'converting bulge to angle in radians
  77.     Rad = seg / (2 * Sin(2 * Atn(dBulge)))
  78.     'find the midpoint
  79.     X = (C1(0) + C2(0)) / 2
  80.     Y = (C1(1) + C2(1)) / 2
  81.     deltaX = C2(0) - C1(0)
  82.     deltaY = C2(1) - C1(1)
  83.     'Convert floating point to zero
  84.     If Rd(deltaX, 0) Then deltaX = 0
  85.     If Rd(deltaY, 0) Then deltaY = 0
  86.    
  87.     'The height of the curve is dBulge * 0.5 * seg
  88.     'dist is the length from the midpoint to the center
  89.     Dist = Rad - dBulge * 0.5 * seg
  90.    
  91.     'If Abs(dBulge) > 1 Then Dist = -Dist
  92.    
  93.     If deltaY >= 0 Then
  94.         If deltaX  0 Then
  95.             Dist = -Dist
  96.         End If
  97.     Else
  98.         If deltaX = 0 Then
  99.             Dist = -Dist
  100.         End If
  101.     End If
  102.                   
  103.     If deltaY = 0 Then  'Line p1,p2 is horizontal
  104.         CenPt(0) = X
  105.         CenPt(1) = Y - Dist
  106.     ElseIf deltaX = 0 Then 'Line p1,p2 is vertical
  107.         CenPt(0) = X - Dist
  108.         CenPt(1) = Y
  109.     Else
  110.         Slope = deltaY / deltaX
  111.         Invertslope = -1 / Slope
  112.         'Invert slope for perpendicular bisector
  113.         'X = X1 + distance / dLength * DX
  114.         'proving for   DeltaX=1 in slope direction
  115.         'slope=DeltaY / 1 =>  DeltaY=slope
  116.         dLength = Sqr(Invertslope ^ 2 + 1)
  117.         CenPt(0) = X + (Dist / dLength) '* 1
  118.         CenPt(1) = Y + ((Dist / dLength) * Invertslope)
  119.     End If
  120.     AddPt CenPt, , 1
  121.     If Not Rd(Abs(Rad), Length(CenPt, Pt)) Then
  122.         Exit Function
  123.         'Point must be on a different segment
  124.     End If
  125.    
  126.     iLeft = isLeft(C1, C2, Pt)
  127.    
  128.     If dBulge > 0 Then
  129.         If iLeft  -1 Then 'On line (0) or cw
  130.             bOnArc = True
  131.         End If
  132.     End If
  133.    
  134.     If bOnArc = True Then
  135.         Dim C1pt As Double, incAng As Double
  136.         C1pt = 0.5 * Length(C1, Pt)
  137.         incAng = Abs(2 * ArcSin(C1pt / Rad))
  138.         If Sgn(isLeft(C1, CenPt, Pt)) = Sgn(dBulge) Then
  139.             incAng = 2 * PI - incAng
  140.         End If
  141.         Dist = Abs(incAng * Rad)
  142.         isPtonArc = True
  143.     End If
  144.    
  145. End Function
  146. Private Function isOnLine(C1, C2, Pt) As Boolean
  147.     Dim deltaX As Double, deltaY As Double
  148.     Dim dLength As Double
  149.     Dim XY As Integer
  150.     Dim X As Double, Y As Double
  151.    
  152.     If isLeft(C1, C2, Pt)  0 Then Exit Function
  153.     deltaX = C2(0) - C1(0)
  154.     deltaY = C2(1) - C1(1)
  155.     If Rd(deltaX, 0) Then deltaX = 0
  156.     If Rd(deltaY, 0) Then deltaY = 0
  157.       
  158.     If deltaX = 0 Then XY = 0 'Line p1,p2 is vertical
  159.     If deltaY = 0 Then XY = 1 'Line p1,p2 is horizontal
  160.    
  161.     If deltaX = 0 Or deltaY = 0 Then
  162.         If C2(XY) > C1(XY) Then
  163.             If Pt(XY) >= C1(XY) And Pt(XY) = C2(XY) And Pt(XY) = -0.0000001 Then
  164.             If X = -0.0000001 And Y  0 Then
  165.             Stx = StartPoint(0): Sty = StartPoint(1)
  166.             Enx = EndPoint(0): Eny = EndPoint(1)
  167.             dX = Stx - Enx
  168.             dY = Sty - Eny
  169.             If i = 1 Then
  170.                 Length = Sqr(dX * dX + dY * dY)
  171.             Else
  172.                 Stz = StartPoint(2): Enz = EndPoint(2)
  173.                 dZ = Stz - Enz
  174.                 Length = Sqr((dX * dX) + (dY * dY) + (dZ * dZ))
  175.             End If
  176.         Else
  177.             Exit Function
  178.         End If
  179.     Else
  180.         Exit Function
  181.     End If
  182. End Function
  183. Public Function polyarclength(Bulge As Double, LengthBetweenPts As Double) As Double
  184.     'Bulge is the getbulge & LengthBetweenPts is the straight dist. between 2 verticies
  185.     Dim dAng As Double, Dist As Double
  186.     dAng = Atn(Bulge) * 4 'converting bulge to angle in radians
  187.     Dist = 0.5 * LengthBetweenPts
  188.     polyarclength = dAng * Dist / Sin(0.5 * dAng)
  189. End Function
  190. Public Function ArcSin(X) As Double
  191.     If Abs(X > 1) Then
  192.         MsgBox "Oops"
  193.     End If
  194.     If X = 1 Then
  195.         ArcSin = PI * 0.5
  196.     ElseIf X = -1 Then
  197.         ArcSin = -PI * 0.5
  198.     Else
  199.         ArcSin = Atn(X / Sqr(-X * X + 1))
  200.     End If
  201. End Function
  202. Function isLeft(LineStart, LineEnd, Pt) As Integer
  203.     Dim Ans As Double
  204.     Ans = ((LineEnd(0) - LineStart(0)) * (Pt(1) - LineStart(1)) _
  205.             - (Pt(0) - LineStart(0)) * (LineEnd(1) - LineStart(1)))
  206.     Ans = Round(Ans, 12)
  207.     If Ans > 0 Then isLeft = 1: Exit Function  'Pt is left of the line  (CW)
  208.     If Ans < 0 Then isLeft = -1: Exit Function  'Pt is right of the line (CCW)
  209.     If Ans = 0 Then isLeft = 0
  210.    
  211. End Function
回复

使用道具 举报

发表回复

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

本版积分规则

  • 微信公众平台

  • 扫描访问手机版

  • 点击图片下载手机App

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

GMT+8, 2025-7-5 17:41 , Processed in 1.119340 second(s), 60 queries .

© 2020-2025 乐筑天下

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