- 积分
- 1047
- 明经币
- 个
- 注册时间
- 2005-1-7
- 在线时间
- 小时
- 威望
-
- 金钱
- 个
- 贡献
-
- 激情
-
|
楼主 |
发表于 2005-3-24 09:58:00
|
显示全部楼层
sorry!我的代码发现有问题了,主要是判断点在不在线段中间,和判断点在不在圆弧的扇形区域有问题,现改正了,测试没问题了!把它做成了函数,后面附了测试的代码:
Option Explicit
Public Function disPtLw(p1() As Double, aa As AcadEntity) As Double '先将直线、圆弧、圆都转化为多段线 Dim mEntzhuan As AcadEntity Set mEntzhuan = aa Dim mLwlines As AcadLWPolyline '辅助的多段线,将所有的线都变成多段线 If TypeOf mEntzhuan Is AcadLWPolyline Then Dim mfuzhuLw() As Object mfuzhuLw() = mEntzhuan.Offset(zero1) If TypeOf mfuzhuLw(0) Is AcadLWPolyline Then Set mLwlines = mfuzhuLw(0) End If ElseIf TypeOf mEntzhuan Is AcadArc Then Dim x As Double Dim hu2 As AcadArc Set hu2 = mEntzhuan x = Tan(hu2.TotalAngle / 4) ep(0) = hu2.StartPoint(0) ep(1) = hu2.StartPoint(1) ep(2) = hu2.EndPoint(0) ep(3) = hu2.EndPoint(1) Set mLwlines = ThisDrawing.ModelSpace.AddLightWeightPolyline(ep) mLwlines.SetBulge 0, x ElseIf TypeOf mEntzhuan Is AcadLine Then Dim zhi2 As AcadLine Set zhi2 = mEntzhuan ap(0) = zhi2.StartPoint(0) ap(1) = zhi2.StartPoint(1) ap(2) = zhi2.EndPoint(0) ap(3) = zhi2.EndPoint(1) Set mLwlines = ThisDrawing.ModelSpace.AddLightWeightPolyline(ap) ElseIf TypeOf mEntzhuan Is AcadCircle Then '对圆的处理 Dim yp(0 To 5) As Double Dim yuan1 As AcadCircle Set yuan1 = mEntzhuan yp(0) = yuan1.Center(0) - yuan1.Radius yp(1) = yuan1.Center(1) yp(2) = yuan1.Center(0) + yuan1.Radius yp(3) = yuan1.Center(1) yp(4) = yuan1.Center(0) - yuan1.Radius yp(5) = yuan1.Center(1) Set mLwlines = ThisDrawing.ModelSpace.AddLightWeightPolyline(yp) mLwlines.SetBulge 0, 1 mLwlines.SetBulge 1, 1 Else MsgBox Err.Description Exit Function End If
'对多段线来算最短距离 Dim disPtline As Double Dim mindisPtline As Double Dim p2(0 To 2) As Double p2(0) = p1(0): p2(1) = p1(1): p2(2) = 0 Dim objPline As AcadLWPolyline Set objPline = mLwlines
Dim intVCnt As Integer Dim varCords As Variant Dim varVert As Variant Dim varCord As Variant Dim varNext As Variant Dim intCrdCnt As Integer Dim dblXSl As Double Dim dblYSl As Double Dim dblZSl As Double Dim dblTemp As Double Dim dblTemp1 As Double Dim dblTemp2 As Double Dim dblAng As Double Dim dblChord As Double Dim dblInclAng As Double Dim dblRad As Double Dim intDiv As Integer Dim houdian As Variant Dim houdian1(0 To 1) As Double Dim qiandian As Variant Dim qiandian1(0 To 1) As Double intDiv = 2 varCords = objPline.Coordinates For Each varVert In varCords intVCnt = intVCnt + 1 Next
For intCrdCnt = 0 To intVCnt / intDiv - 1 If intCrdCnt < intVCnt / intDiv - 1 Then varCord = objPline.Coordinate(intCrdCnt) varNext = objPline.Coordinate(intCrdCnt + 1) ElseIf objPline.Closed Then varCord = objPline.Coordinate(intCrdCnt) varNext = objPline.Coordinate(0) Else Exit For End If dblXSl = (varCord(0) - varNext(0)) ^ 2 dblYSl = (varCord(1) - varNext(1)) ^ 2 houdian = objPline.Coordinate(intCrdCnt + 1) houdian1(0) = houdian(0): houdian1(1) = houdian(1) qiandian = objPline.Coordinate(intCrdCnt) qiandian1(0) = qiandian(0): qiandian1(1) = qiandian(1)
If objPline.GetBulge(intCrdCnt) = 0 Then '当这段线是直线的时候 Dim testdata As Double Dim testdata1 As Double dblTemp = Sqr(dblXSl + dblYSl) dblTemp1 = disliangdian(p2(0), p2(1), qiandian1(0), qiandian1(1)) dblTemp2 = disliangdian(p2(0), p2(1), houdian1(0), houdian1(1)) disPtline = Sqr(dblTemp1 ^ 2 - ((dblTemp ^ 2 + dblTemp1 ^ 2 - dblTemp2 ^ 2) ^ 2) / (4 * dblTemp ^ 2)) testdata = Abs(dblTemp ^ 2 + dblTemp1 ^ 2 - dblTemp2 ^ 2) / (2 * dblTemp) '判断点与直线的关系,是不是在直线两个端点之间。 testdata1 = Abs(dblTemp ^ 2 - dblTemp1 ^ 2 + dblTemp2 ^ 2) / (2 * dblTemp) If intCrdCnt = 0 Then '给最短距离一个初始化的值 mindisPtline = dblTemp1 End If
If testdata > dblTemp Or testdata1 > dblTemp Then '如果点在两个端点之外,距离为到端点距离的最小值 disPtline = dblTemp1 If dblTemp2 < dblTemp1 Then disPtline = dblTemp2 End If End If 'MsgBox "这段直线中最短距离为: " & disPtline If disPtline < mindisPtline Then mindisPtline = disPtline End If 'MsgBox "目前最短距离为: " & mindisPtline Else '不是直线 'if there is a bulge we need to get an arc length dblChord = Sqr(dblXSl + dblYSl) dblInclAng = Atn(Abs(objPline.GetBulge(intCrdCnt))) * 4 dblAng = (dblInclAng / 2) - ((Atn(1) * 4) / 2) dblRad = (dblChord / 2) / (Cos(dblAng)) 'dblArc = dblInclAng * dblRad dblTemp1 = disliangdian(p2(0), p2(1), qiandian1(0), qiandian1(1)) dblTemp2 = disliangdian(p2(0), p2(1), houdian1(0), houdian1(1))
Dim fuzhuhu As AcadLWPolyline Dim fuzhuhu1(0 To 3) As Double Dim fuzhuhu2 As AcadArc Dim fuzhuhu3 As Variant Dim fuzhuhu4(0 To 2) As Double Dim fuzhuhu5 As Variant Dim qianangle As Double Dim houangle As Double fuzhuhu1(0) = qiandian(0) fuzhuhu1(1) = qiandian(1) fuzhuhu1(2) = houdian(0) fuzhuhu1(3) = houdian(1) Set fuzhuhu = ThisDrawing.ModelSpace.AddLightWeightPolyline(fuzhuhu1) fuzhuhu.SetBulge 0, objPline.GetBulge(intCrdCnt) fuzhuhu5 = fuzhuhu.Explode If TypeOf fuzhuhu5(0) Is AcadArc Then Set fuzhuhu2 = fuzhuhu5(0) End If '确定弧的圆心 fuzhuhu3 = fuzhuhu2.Center fuzhuhu4(0) = fuzhuhu3(0): fuzhuhu4(1) = fuzhuhu3(1): fuzhuhu4(2) = 0 '确定弧的起始角度 qianangle = fuzhuhu2.StartAngle houangle = fuzhuhu2.EndAngle '删除辅助的圆弧 fuzhuhu2.Delete fuzhuhu.Delete '判断点是不是在圆弧所在扇形区域内 Dim fuzhuline As AcadLine Dim dblAngledian As Double Set fuzhuline = ThisDrawing.ModelSpace.AddLine(fuzhuhu4, p2) dblAngledian = fuzhuline.Angle
disPtline = Abs(dblRad - fuzhuline.Length) If intCrdCnt = 0 Then '给最短距离一个初始化的值 mindisPtline = dblTemp1 End If fuzhuline.Delete '不在圆弧的扇形区域时的最短距离 If (dblAngledian - qianangle) * (dblAngledian - houangle) * (qianangle - houangle) < zero1 Then disPtline = dblTemp1 If dblTemp2 < dblTemp1 Then disPtline = dblTemp2 End If End If 'MsgBox "圆弧中最短长度是: " & disPtline '最短距离 If disPtline < mindisPtline Then mindisPtline = disPtline End If 'MsgBox "目前最短距离为: " & mindisPtline End If
Next objPline.Delete
disPtLw = mindisPtline 'MsgBox "最终最短距离为: " & mindisPtline End Function
下面的是测试代码: Sub ztest() '点到多段线的最短距离 Dim disPtline As Double Dim mindisPtline As Double Dim p1 As Variant Dim p2(0 To 1) As Double p1 = ThisDrawing.Utility.GetPoint(, " 请输入点:") p2(0) = p1(0): p2(1) = p1(1) Dim objPline As AcadLWPolyline Dim mlwlineqidian1 As AcadEntity ThisDrawing.Utility.GetEntity mlwlineqidian1, mlwlineqidian2, "请选择多段线" Dim x As Double x = disPtLw(p2, mlwlineqidian1) MsgBox "特斯他的长度为:" & x End Sub
|
|