QQ登录

只需一步,快速开始

登录 | 注册 | 找回密码

三维网

 找回密码
 注册

QQ登录

只需一步,快速开始

展开

通知     

查看: 3781|回复: 2
收起左侧

[已解决] VBA怎样选择一个大圆或者矩形里的所有对象

[复制链接]
发表于 2009-11-9 20:06:52 | 显示全部楼层 |阅读模式 来自: 中国江苏无锡

马上注册,结识高手,享用更多资源,轻松玩转三维网社区。

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

x
请教大家,我现在在写一个小程序时碰到要选择一个大圆里的所有小圆,还有一个大矩形里的小圆,请问好实现吗?我百思不得其解,请大家帮忙,谢谢了!  M: w* j6 k* i* @7 G2 X, O
功能描述:1.比如我想选一个大圆里所有小圆,当我点按钮“选择所有”,提示我先选择一个大圆,然后我点选大圆之后,所有的小圆被选中。0 s+ B3 k# P, N. N- i
                   2.我想选择一个斜方向的矩形里的所有小圆,点按钮“选择所有”,提示先选择一个矩形,点矩形后,矩形里所有的小圆被选中。
发表于 2009-11-9 23:34:53 | 显示全部楼层 来自: 中国
ACAD并不支持根据对象选择,只能用"圈围"方法近似地做.当边界为圆时,可以尽可能多地在圆周上取点,用一个近似圆的多边形做边界;对多段线(矩形就是闭合的二维多段线),可以使用多段线的顶点,但不允许自交,如果是开发准备发布的通用工具,就要对可能的自交做检查,以区别对待.而且当二维多段线有凸起(圆弧段)时,也要区别对待.下面的代码仅供参考.3 O4 F3 a+ T0 G" n! d6 [
  1. ! q5 A% v. U! G% [7 H: B
  2. Private Const N As Long = 100 '声明一个常数,指定从圆周上拾取"圈围"的点数
    ' g7 x5 m3 \6 W3 p  X5 @) _% V
  3. ) b9 `: u- S+ c5 J" Z
  4. Sub A(), n% W5 U/ q( K2 I& K$ P
  5.     Dim S1 As AcadSelectionSet '声明第一个选择集,用于从屏幕上选取做为下一步选择集边界的对象
    - b1 ^- P! f" k& Q0 i, B( c- C
  6.     Dim S2 As AcadSelectionSet '声明第二个选择集,用于选取边界内部对象. U( c' Z% q( J; \" C* y
  7.     Dim FT(3) As Integer, FD(3) As Variant '声明选择集过滤器. E/ V# d) K- U. J4 H/ G
  8.     Dim OldPICKADD As Long '声明一个长整形变量,用于存放原"pickadd"系统变量
    , w+ v. t* k$ t8 ?! o1 D5 T/ u0 a( N
  9.     Dim P() As Double '声明一个动态数组,用于存放"圈围"点集的三维坐标' |# c" ]( d- K1 |
  10.     Dim I As Long '循环变量. K# Z$ H9 ^- x# C
  11.     Dim V As Variant '边界圆的圆心或矩形的顶点坐标
    - W" ]. Y+ D( B, k: l6 @
  12.    
    2 R! G3 w5 A! V- n: ]
  13.     On Error Resume Next
    & L9 m  n" H# A0 d
  14.    
    * p2 J; Z  @( g) }3 K
  15.     FT(0) = -4: FD(0) = "<or" '设置选择集过滤器为选择圆或二维多段线
    0 S3 d+ v4 M  F7 s
  16.     FT(1) = 0: FD(1) = "Circle"0 x3 j, J! [& x( g% w( W+ \
  17.     FT(2) = 0: FD(2) = "LWPolyLine"
    1 h3 @/ ]. o2 K4 d0 b
  18.     FT(3) = -4: FD(3) = "or>"
    4 g" x5 H; S+ |5 J* E! @
  19.     With ThisDrawing
    , t2 `5 k1 ]6 L
  20.         OldPICKADD = .GetVariable("pickadd" ) '记录原"pickadd"系统变量2 {4 _" a2 z! U3 b+ ~- y
  21.         .SetVariable "pickadd", 0 '把"pickadd"系统变量临时改为0(用 SHIFT 键添加到选择集),只为方便,不是必要的( Z" o9 ~4 K% ]9 H! q8 ~2 i
  22.         Set S1 = .SelectionSets.Add("S1" ) '新建选择集,用于从屏幕上选取边界对象' z8 l) W( b; D: ]
  23.         S1.SelectOnScreen FT, FD '在屏幕上选取圆或二维多段线
    ' j7 y2 F0 S) N' G& L3 k, J4 P2 Z* G0 q
  24.         .SetVariable "pickadd", OldPICKADD '把"pickadd"系统变量改回原值
    % T! b" [! f8 j$ U
  25.         If S1.Count > 0 Then '如果在屏幕上有效选取了边界对象/ X0 P! R7 B0 K! {5 S% L
  26.             If S1.Item(S1.Count - 1).ObjectName = "AcDbCircle" Then '如果选取的最后一个对象是"圆"& a/ Y3 E3 }0 M1 }8 G! }
  27.                 ReDim P(N * 3 - 1) '按"圈围"点集数量重定义三维坐标数组
    * ]8 z+ r7 v9 _: \  f, e' u
  28.                 V = S1.Item(S1.Count - 1).Center '提取圆心坐标
    6 F0 P# z$ c& f6 K7 d9 f5 S( g
  29.                 For I = 0 To N - 1 '在圆周上按点集数量均匀取点计算圈围点集坐标
    $ X% |7 G9 Y1 d1 n" b/ j
  30.                     P(I * 3) = V(0) + S1.Item(S1.Count - 1).Radius * Cos(CDbl(I) / CDbl(N) * 2 * .Utility.AngleToReal(180, acDegrees))
    / e% o: P5 p& X' n
  31.                     P(I * 3 + 1) = V(1) + S1.Item(S1.Count - 1).Radius * Sin(CDbl(I) / CDbl(N) * 2 * .Utility.AngleToReal(180, acDegrees))
    ; q( N1 B4 J$ e9 O+ B3 W
  32.                 Next( T# ?5 m8 h4 K
  33.             Else '如果选取的最后一个对象是二维多段线
    , K% R/ W% i: U
  34.                 V = S1.Item(S1.Count - 1).Coordinates '提取二维多段线顶点坐标(二维)
    ( W# ?$ ]4 D9 g8 l. t
  35.                 ReDim P((UBound(V) \ 2) * 3 + 2) '按多段线顶点数量重定义圈围点集三维坐标数组$ L7 a+ l" k2 b4 J& f- v
  36.                 For I = 0 To UBound(V) \ 2 '把多段线二维坐标写入三维坐标数组& F! D$ Q2 _: }, I4 ~2 o
  37.                     P(I * 3) = V(I * 2)
    ) t: o6 }( l; H
  38.                     P(I * 3 + 1) = V(I * 2 + 1)
    * z( _: ^& r5 {0 v  u4 e7 P
  39.                 Next: [1 T1 U: R& E! }; E  N( g
  40.             End If
    : w9 B( Q9 R% n' M7 B. l
  41.             Set S2 = .SelectionSets.Add("S2" ) '新建选择集,用于选取边界内部对象
    % @8 r5 E" l- {7 G, Y" \
  42.             S2.SelectByPolygon acSelectionSetWindowPolygon, P '根据点集圈选; G9 Y* q- s4 D8 F
  43.             '自行处理边界内部被选择的对象
    ( ?, ]7 m) m2 g! ^7 J5 I5 `
  44.             S2.Delete '删除用过的选择集( X7 A! o3 X0 r) I
  45.         End If
    . Y0 ?. J5 A" D0 d8 S) ^/ i
  46.         S1.Delete '删除用过的选择集
    - ]1 W! ^0 L: X' y( Q. O8 c+ c6 ^
  47.     End With
    ( v7 |3 J! i' v7 K$ b& O4 C0 a# y
  48. End Sub
    3 Z5 ~+ I' ?/ E, v
复制代码

评分

参与人数 1三维币 +8 收起 理由
wang2003 + 8 应助

查看全部评分

 楼主| 发表于 2009-11-10 18:11:41 | 显示全部楼层 来自: 中国江苏无锡

回复 2# woaishuijia 的帖子

我当初的想法是先选择所有的小圆,再判断小圆的圆心坐标在不在大圆的范围内,还有删除与大圆想交的,这样效率不高,还是老师你的高明。谢谢了!
发表回复
您需要登录后才可以回帖 登录 | 注册

本版积分规则


Licensed Copyright © 2016-2020 http://www.3dportal.cn/ All Rights Reserved 京 ICP备13008828号

小黑屋|手机版|Archiver|三维网 ( 京ICP备2023026364号-1 )

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