明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 3415|回复: 11

[VBA]AutoCAD VBA开发精彩实例教程的错误

  [复制链接]
发表于 2005-9-16 15:31:00 | 显示全部楼层 |阅读模式
最近看同事的《AutoCAD VBA开发精彩实例教程》,是你们网站张帆等编著的书。发现在53页,三点法画弧中所示例的程序代码是错误的!!!当用Set objArc=AddArcCSEP(ptCen,ptSt,ptEn)画弧时,所画的圆弧永远都是逆时针方向的。很可能不通过第二点!!请高手示例正确的代码以解我的疑惑!!!
发表于 2005-9-16 15:36:00 | 显示全部楼层

你在那里买的这书,有电子版吗?能把书中附带的东西发上来吗?

 楼主| 发表于 2005-9-17 10:01:00 | 显示全部楼层
估计斑竹不会同意的
发表于 2005-9-18 07:51:00 | 显示全部楼层
圆弧只有一个方向,没有正反之分。
需要你给出三个点的数据来证明这个程序有问题。注意:三个点的中间那个点不代表就是圆弧的中点,所以你用圆弧的中点来与中间那个点比较肯定是不同的。
 楼主| 发表于 2005-9-18 16:17:00 | 显示全部楼层

其实只要是顺时针方向画的三个点,画出来的圆弧都有问题!!!我编一个小函数来验证:

Sub ttest()
Dim aPoint(2) As Double
Dim bPoint(2) As Double
Dim cPoint(2) As Double
aPoint(0) = 1340
aPoint(1) = 610
bPoint(0) = 1434
bPoint(1) = 505
cPoint(0) = 1369
cPoint(1) = 335
Dim t As Variant
'''创建三点所画的弧
Set t = f_AddArc3Pt(aPoint, bPoint, cPoint)
Dim lwPLine As AcadLWPolyline
Dim pp(0 To 5) As Double
pp(0) = 1340
pp(1) = 610
pp(2) = 1434
pp(3) = 505
pp(4) = 1369
pp(5) = 335
'''创建三点所画的直线
Set lwPLine = ThisDrawing.ModelSpace.AddLightWeightPolyline(pp)
End Sub
比较弧和线就会发现问题!不通过的二点

 楼主| 发表于 2005-9-18 16:19:00 | 显示全部楼层

同时附上你们的程序代码:

Private Function GetCenOf3Pt(pt1 As Variant, pt2 As Variant, pt3 As Variant, ByRef radius As Double) As Variant
''''根据三点计算出圆心和半径
Dim xysm, xyse, xy As Double
Dim ptCen(2) As Double
xy = pt1(0) ^ 2 + pt1(1) ^ 2
xyse = xy - pt3(0) ^ 2 - pt3(1) ^ 2
xysm = xy - pt2(0) ^ 2 - pt2(1) ^ 2
xy = (pt1(0) - pt2(0)) * (pt1(1) - pt3(1)) - (pt1(0) - pt3(0)) * (pt1(1) - pt2(1))
'''判断参数有效性
If Abs(xy) < 0.000001 Then
   MsgBox "所输入的参数无法创建圆形!"
   Exit Function
End If
'获得圆心和半径
ptCen(0) = (xysm * (pt1(1) - pt3(1)) - xyse * (pt1(1) - pt2(1))) / (2 * xy)
ptCen(1) = (xyse * (pt1(0) - pt2(0)) - xysm * (pt1(0) - pt3(0))) / (2 * xy)
ptCen(2) = 0
radius = Sqr((pt1(0) - ptCen(0)) * (pt1(0) - ptCen(0)) + (pt1(1) - ptCen(1)) * (pt1(1) - ptCen(1)))
If radius < 0.000001 Then
   MsgBox "半径过小!"
   Exit Function
End If
''函数返回圆心的位置,而半径则在参数中通过引用方式返回
GetCenOf3Pt = ptCen
End Function
Public Function AddArc3Pt(ByVal ptSt As Variant, ByVal ptSc As Variant, ByVal ptEn As Variant) As AcadArc
''''三点法创建圆弧
Dim objArc As AcadArc
Dim ptCen As Variant
Dim radius As Double
ptCen = GetCenOf3Pt(ptSt, ptSc, ptEn, radius)
Set objArc = AddArcCSEP(ptCen, ptSt, ptEn)

objArc.Update
Set AddArc3Pt = objArc
End Function
Private Function AddArcCSEP(ByVal ptCen As Variant, ByVal ptSt As Variant, ByVal ptEn As Variant) As AcadArc
Dim objArc As AcadArc
Dim radius As Double
Dim stAng, enAng As Double
''计算半径
radius = GetDistance(ptCen, ptSt)
''计算起点角度和终点角度
stAng = ThisDrawing.Utility.AngleFromXAxis(ptCen, ptSt)
enAng = ThisDrawing.Utility.AngleFromXAxis(ptCen, ptEn)

Set objArc = ThisDrawing.ModelSpace.AddArc(ptCen, radius, stAng, enAng)
objArc.Update
Set AddArcCSEP = objArc
End Function

发表于 2005-9-18 17:59:00 | 显示全部楼层
  1. Public Function AddArc3Pt(ByVal ptSt As Variant, ByVal ptSc As Variant, ByVal ptEn As Variant) As AcadArc
  2. ''''三点法创建圆弧
  3. Dim objArc As AcadArc
  4. Dim ptCen As Variant
  5. Dim radius As Double
  6. ptCen = GetCenOf3Pt(ptSt, ptSc, ptEn, radius)
  7. [b]If isClockWise(ptSt, ptSc, ptEn) Then
  8.     Set objArc = AddArcCSEP(ptCen, ptSt, ptEn)
  9. Else
  10.     Set objArc = AddArcCSEP(ptCen, ptEn, ptSt)
  11. End If[/b]objArc.Update
  12. Set AddArc3Pt = objArc
  13. End Function
  14. [b]'判断三点的方向
  15. Function isClockWise(ptSt, ptSc, ptEn) As Boolean
  16.     If (ThisDrawing.Utility.AngleFromXAxis(ptSt, ptSc) - ThisDrawing.Utility.AngleFromXAxis(ptSc, ptEn) < 0 _
  17.     And ThisDrawing.Utility.AngleFromXAxis(ptSt, ptSc) - ThisDrawing.Utility.AngleFromXAxis(ptSc, ptEn) > -3.14159265) _
  18.     Then isClockWise = True
  19. End Function[/b]
 楼主| 发表于 2005-9-19 14:20:00 | 显示全部楼层

帅哥,你的算法还是有问题!!比如:

Sub ttest()
Dim aPoint(2) As Double
Dim bPoint(2) As Double
Dim cPoint(2) As Double
aPoint(0) = 19358
aPoint(1) = -3402
bPoint(0) = 20779
bPoint(1) = -4141
cPoint(0) = 22649
cPoint(1) = -1360
Dim t As Variant
'''创建三点所画的弧
Set t = f_AddArc3Pt(aPoint, bPoint, cPoint)
Dim lwPLine As AcadLWPolyline
Dim pp(0 To 5) As Double
pp(0) = 19358
pp(1) = -3402
pp(2) = 20779
pp(3) = -4141
pp(4) = 22649
pp(5) = -1360
'''创建三点所画的直线
Set lwPLine = ThisDrawing.ModelSpace.AddLightWeightPolyline(pp)
End Sub

 楼主| 发表于 2005-9-19 22:20:00 | 显示全部楼层
'判断三点的方向(自己改了一下,供大家测试)
Function isClockWise(ptSt, ptSc, ptEn) As Boolean
'''顺时针为false,逆时针为true
Dim y As Double
If ptSc(0) > ptSt(0) Then   '在右半边
   y = ((ptSc(1) - ptSt(1)) * ptEn(0) + ptSt(1) * ptSc(0) - ptSt(0) * ptSc(1)) / (ptSc(0) - ptSt(0))
   If y > ptEn(1) Then '如果在线下面
      isClockWise = false
      Else
        isClockWise = true
   End If
   Exit Function
End If
If ptSc(0) < ptSt(0) Then    '在左半边
   y = ((ptSc(1) - ptSt(1)) * ptEn(0) + ptSt(1) * ptSc(0) - ptSt(0) * ptSc(1)) / (ptSc(0) - ptSt(0))
   If y > ptEn(1) Then '如果在线下面
      isClockWise =true
      Else
        isClockWise = false
   End If
   Exit Function
End If
If (ptSc(0) = ptSt(0)) And (ptSc(1) > ptSt(1)) Then       '90度
   If ptEn(0) > ptSc(0) Then   '右顺
      isClockWise = false
      Else
      isClockWise = true
   End If
   Exit Function
End If
If (ptSc(0) = ptSt(0)) And (ptSc(1) < ptSt(1)) Then    '270度
   If ptEn(0) > ptSc(0) Then   '左顺
      isClockWise =true
      Else
      isClockWise = false
   End If
   Exit Function
End If
End Function
发表于 2005-9-19 23:27:00 | 显示全部楼层
本帖最后由 作者 于 2006-3-23 13:18:30 编辑

Public Function AddArc3Pt(ByVal ptSt As Variant, ByVal ptSc As Variant, ByVal ptEn As Variant) As AcadArc
''''三点法创建圆弧
Dim objArc As AcadArc
Dim ptCen As Variant
Dim radius As Double
ptCen = GetCenOf3Pt(ptSt, ptSc, ptEn, radius)
If isClockWise(ptCen, ptSt, ptSc, ptEn) Then
    Set objArc = AddArcCSEP(ptCen, ptSt, ptEn)
Else
    Set objArc = AddArcCSEP(ptCen, ptEn, ptSt)
End If
objArc.Update
Set AddArc3Pt = objArc
End Function

Private Function AddArcCSEP(ByVal ptCen As Variant, ByVal ptSt As Variant, ByVal ptEn As Variant) As AcadArc
Dim objArc As AcadArc
Dim radius As Double
Dim stAng, enAng As Double
''计算半径
radius = GetDistance(ptCen, ptSt)
''计算起点角度和终点角度
stAng = ThisDrawing.Utility.AngleFromXAxis(ptCen, ptSt)
enAng = ThisDrawing.Utility.AngleFromXAxis(ptCen, ptEn)

Set objArc = ThisDrawing.ModelSpace.AddArc(ptCen, radius, stAng, enAng)
objArc.Update
Set AddArcCSEP = objArc
End Function

'判断三点的方向
Function isClockWise(ptCen, ptSt, ptSc, ptEn) As Boolean
    a1 = ThisDrawing.Utility.AngleFromXAxis(ptCen, ptSt)
    a2 = ThisDrawing.Utility.AngleFromXAxis(ptCen, ptSc)
    a3 = ThisDrawing.Utility.AngleFromXAxis(ptCen, ptEn)
    
    isClockWise = (a1 < a2) Xor (a2 < a3) Xor (a1 < a3)
   
End Function

'说明,逆时针的三种情况如下,其余为顺时针

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

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

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-11-27 12:43 , Processed in 0.190597 second(s), 25 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表