QQ登录

只需一步,快速开始

登录 | 注册 | 找回密码

三维网

 找回密码
 注册

QQ登录

只需一步,快速开始

展开

通知     

查看: 8030|回复: 14
收起左侧

[已答复] vba中如何嵌套块?

[复制链接]
发表于 2012-6-8 11:58:14 | 显示全部楼层 |阅读模式 来自: 中国广东珠海

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

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

x
本帖最后由 woaishuijia 于 2012-6-8 17:40 编辑
; G& s' A! x* M  r" j) b  T% G. C4 b
得到斑竹上次解答后,现在可以根据blockB的数量灵活插入需要的块了,(原帖http://www.3dportal.cn/discuz/viewthread.php?tid=1140006&;extra=page%3D3)但现在遇上一个新问题,不好意思又开了一个贴....
0 R, j6 C* v0 S3 A* w8 e问题是这样的,图纸上右侧是原始块,左侧是我想要做成的块。
7 [* k% K6 y1 c, u4 q1 ?5 [为简化问题,现在只要插入1个blockA,n个blockB,n的数量通过文本框来确定,blockC和blockD不用插入。
2 D& W" ]$ i0 `1 d* O# d当我完成插入1个blockA,n个blockB后,我要把左侧这n+1个块组成一个新块 blockE,这应该算是嵌套块吧?可是这个创建blockE的代码怎么写呢?+ w; L( z4 ~6 I/ L. D
特别的是:n是不确定的,比如某一次是1个A,3个B块,另外一次是1个A,5个B块,怎么来处理这种情况呢?
: ?: i  g. @; Y  `; u4 x, _* O我感觉不能通过块的名字嵌套吧,因为右侧的原始块有一样的名字,而且原始块是不能删除的。
; f5 h4 x  I7 s& F: w谢谢,附上图纸和代码
  1. Private Sub cmdInsert_Click()3 C; L4 x: @7 r' |8 d
  2. Dim ptInsert(2) As Double3 `2 j2 s3 f' l0 s4 V1 @  ]
  3. Dim lastBlock As Variant3 }9 i4 v3 ?- r' N# E! D. d: R! r
  4. ptInsert(0) = 0
    + c8 @. H( Q8 k) `
  5. ptInsert(1) = 0  u5 ]7 C1 |; v* O- l9 L
  6. ptInsert(2) = 0" b1 i- x% W% }8 b  Q
  7. 6 f: p; J) \' z) v0 \  m
  8. '----------插入块A 仅仅一个---------------------------------
    2 P+ g  i1 a  ?" R$ I: z' @5 r! k
  9. Dim B As AcadBlockReference '声明一个块参照变量7 r" Y5 P; z0 [5 O" J
  10. Dim P As Variant '声明一个变体变量用于接收三维点坐标
    5 E7 v. w& c: X6 e  i' L
  11. Set B = ThisDrawing.ModelSpace.InsertBlock(ptInsert, blkAName.Text, 1, 1, 1, 0)
    : d; f+ m/ O! p+ C
  12. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组" g) ?4 t: J0 x6 c- e- J
  13. '----------插入块A 完成---------------------------------3 `: {* M' x) C9 Y$ g

  14. % y6 d# M3 p7 u  G+ l
  15. '----------插入块B---------------------------------
    , ]1 x- D9 \. `0 W2 j8 L" w
  16. Dim pNew(2) As Double
    % m* J$ q1 @- {2 m( L& @) r2 ]
  17. pNew(0) = P(0) - 500
    + p/ L3 S: C" l) W- U! A/ ~! O
  18. pNew(1) = P(1) + 1405.08
    - q7 J) K  M$ T# h6 N" A7 q4 Y
  19. pNew(2) = P(2)& `  {& ]1 d/ Q, t- o
  20. Set B = ThisDrawing.ModelSpace.InsertBlock(pNew, blkBName.Text, 1, 1, 1, 0)5 i# P: R" `3 @- e: @: G8 y' g
  21. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    2 x. H) ]. s4 ?( z3 ^: r

  22. ) b+ J3 Q- Z. `2 O0 X" b$ K5 M
  23. . B& G! M; k" m* }- d  f
  24. For i = 2 To Val(blkBNum.Text) Step 1
    . n) L+ c- \+ w
  25. Dim pBNew(2) As Double
    # m$ ?1 H8 ~3 N
  26. pBNew(0) = P(0)
    ! {3 r, u. X  O5 {$ i/ t
  27. pBNew(1) = P(1) + 2000
    - x$ {3 v4 V6 m1 o% d, T5 I  n+ J% y
  28. pBNew(2) = P(2)
    3 Z$ v( ?' R* j/ g4 Z2 {
  29. Set B = ThisDrawing.ModelSpace.InsertBlock(pBNew, blkBName.Text, 1, 1, 1, 0)" D5 i# f1 G  X* X7 s
  30. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组" \5 F* g) w# o& _# |; }
  31. Next
    ! t. X7 M. m; z# m4 I  E
  32. '----------插入块B完成---------------------------------9 W! K' |/ K& k( ^- A! j
  33. '最后的效果是左侧的块A和B组成了一个最终的块BlockE
    ' _1 l* V% y9 ~. d  T2 b

  34. * E1 u) V% a& h4 J! C# j( r" ~
  35. . T* N0 k- a) r1 l' o' k/ o
  36. ThisDrawing.Regen acActiveViewport& O& B6 a6 I* U" G
  37. ) P  L+ a) l; y/ K& j
  38. End Sub
    . o; u2 B, \4 K) C9 b
复制代码
2012-6-8 11-50-45.jpg

cad vba嵌套块.rar

35.12 KB, 下载次数: 8

发表于 2012-6-8 17:41:32 | 显示全部楼层 来自: 中国辽宁
1# tataki ' d7 B2 H. Q( E0 z  |( ?
  1. Private Sub cmdInsert_Click(): [& ?( ^0 C9 N, v6 `, k" A
  2. Dim ptInsert(2) As Double
    & {: _$ r' Y, k% v  w) S- ]
  3. Dim lastBlock As Variant
    - n9 r3 @- _, H) G" `( `' A
  4. ptInsert(0) = 0
    4 B/ I0 j3 O% {3 z) Q/ t- ]
  5. ptInsert(1) = 0
    % m3 b8 ?: ~" J; C* r
  6. ptInsert(2) = 06 E  e3 S, F8 k) _9 i
  7. Dim BR As AcadBlock- F0 K7 v4 k$ D/ G5 u/ O
  8. Set BR = ThisDrawing.Blocks.Add(ptInsert, "blockE")# [$ `5 ?5 ?9 [" b# z& F
  9. 2 m. T0 `6 o" f7 \, V) e
  10. '----------插入块A 仅仅一个---------------------------------
    4 {( y( c( q( |. R) h- j
  11. Dim B As AcadBlockReference '声明一个块参照变量
    , T1 n$ Q4 N: r! [
  12. Dim P As Variant '声明一个变体变量用于接收三维点坐标- r  g4 |) M% j( q* O' w
  13. 'Set B = ThisDrawing.ModelSpace.InsertBlock(ptInsert, blkAName.Text, 1, 1, 1, 0)5 y% Y4 T& ?$ |9 N; G' Y
  14. Set B = BR.InsertBlock(ptInsert, blkAName.Text, 1, 1, 1, 0)
    # P! X7 V2 A2 {$ L; z$ J# u
  15. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组" J8 {7 \, L0 ^) k3 ^
  16. '----------插入块A 完成---------------------------------( {& _2 g5 O* p9 g& J
  17. 7 G' R7 @+ Q! `% R
  18. '----------插入块B---------------------------------# j* l, Q0 t/ h, M0 J3 E. ^
  19. Dim pNew(2) As Double
    4 g* _( |0 ^. T2 S" k, ~
  20. pNew(0) = P(0) - 5002 m: l3 e8 Q* q" I1 D
  21. pNew(1) = P(1) + 1405.08* d* ]* f2 `* l7 X% m7 ^
  22. pNew(2) = P(2)- N: s) z! |; k' R- m, u
  23. 'Set B = ThisDrawing.ModelSpace.InsertBlock(pNew, blkBName.Text, 1, 1, 1, 0)
    0 j3 h$ e0 S- g% Y% \
  24. Set B = BR.InsertBlock(pNew, blkBName.Text, 1, 1, 1, 0)
    % `! g- ?! L8 ]* l; u, ~3 W* ^
  25. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    # C3 o$ \/ l( g/ {; @4 h% ~- c2 n

  26. 4 R& }/ b4 X# {2 Q2 u
  27. 0 Z* @4 `1 J' y* q
  28. For i = 2 To Val(blkBNum.Text) Step 1; }) C+ E* e5 M9 i; G
  29. Dim pBNew(2) As Double
    / G  u2 n+ b. o& @; g- z
  30. pBNew(0) = P(0)9 ]4 C( i- X0 T
  31. pBNew(1) = P(1) + 2000; m/ f. O/ p  c6 U: h9 p# u- e
  32. pBNew(2) = P(2)
    5 y3 w' W& {2 f
  33. 'Set B = ThisDrawing.ModelSpace.InsertBlock(pBNew, blkBName.Text, 1, 1, 1, 0)& Q+ }3 n  W+ @6 M
  34. Set B = BR.InsertBlock(pBNew, blkBName.Text, 1, 1, 1, 0)" i$ }% |9 I8 S% Y# _) z8 y% g) O" z6 X
  35. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    * f' R2 L) D7 V
  36. Next
    ' n% k6 X  P7 F6 e# ]" P0 c1 ]
  37. '----------插入块B完成---------------------------------4 j' K4 N2 R6 y
  38. '最后的效果是左侧的块A和B组成了一个最终的块BlockE6 s5 k1 r% K/ {9 B: p- h9 e

  39. , u3 [1 E! p% b7 E2 d
  40. Set B = ThisDrawing.ModelSpace.InsertBlock(ptInsert, "blockE", 1, 1, 1, 0)
    + ~7 b. E) `6 k6 g$ a
  41. - e% M) S4 ?" m6 E& B
  42. ThisDrawing.Regen acActiveViewport
    3 o* N! P) `% M4 o# r
  43. , q+ [: F/ E# g- b
  44. End Sub
    7 H1 P& p+ J' _& r
复制代码
 楼主| 发表于 2012-6-10 11:33:54 | 显示全部楼层 来自: 中国广东珠海
本帖最后由 woaishuijia 于 2012-6-10 12:14 编辑 - O& c' u* T# R# Q  Q

8 R& s2 ~$ Z; b3 W: Q% u谢谢斑竹
- |! E, @* N2 q  @, _原来是要先创建blockE块,最后在模型空间中插入即可。我还局限在创建一个块然后和上一个块合并,依次进行呢。$ c; c* q' R4 ^' H& f& N
另外我有一个疑惑,为什么块中嵌套块不能像块中添加实体,比如一个圆或者直线一样进行呢?, ~% N$ S) ?) T  G+ n
在书上见过这样的例子,给已经定义的块添加直线:
  1. Dim BL As AcadBlock
    7 E( l0 u, N6 ^! S

  2. 9 D) }4 [* l' F4 _% Z
  3. Dim ptInsert(2) As Double6 S+ w4 T8 B5 j/ R# q
  4. ptInsert(0) = 09 K$ a1 n; k) S  x! p" B: J
  5. ptInsert(1) = 0
    ! L: h4 a7 Y3 _. d' o7 K  G% ]
  6. ptInsert(2) = 0! X: f- g/ M- s  f* O- y

  7. ) {3 U& W$ Z4 ]% |# n$ X3 Q) ~
  8. Dim pt1(2) As Double '直线起点pt1
    3 {$ J2 g/ l4 V
  9. pt1(0)=100:pt1(1)=100:pt1(2)=100
      ?4 Y5 l/ @- j) a5 b

  10. 2 w! d7 Q  {# h8 Y
  11. Dim pt2(2) As Double '直线终点pt2
    / X% H0 N1 {$ L0 C7 Z: u
  12. pt2(0)=500:pt2(1)=500:pt2(2)=5004 \* w* M) ]  a% @
  13. / \) c3 E7 I1 M  F9 V
  14. Set BL = ThisDrawing.Blocks.Add(ptInsertBase, "blockE" ) '先定义
    2 P$ w2 e' d8 ~, |6 t
  15. ThisDrawing.Blocks.Item("blockE" ).AddLine Pt1,Pt2
复制代码
'直接在块中添加直线了,这个里面  " ) .  这段代码怎么出现表情了啊???3 L8 u: J8 e) r- \: y) u& |" d
后面的就不写了。。。。
3 ?0 B  T& i  s  d5 j& \; u3 A
/ h& E) S, u" ?1 {! B+ `我就是有点纳闷块里有直接添加实体的方法,addline ,addcircle等等,就是没有添加块的方法,另外,我看到一个AddMInsertBlock方法,最开始还以为是添加块,结果发现不是,于是就不知道该怎么整了。恰好我看的那些VBA书中也没有提及怎么嵌套块...看了斑竹的思路才知道我的想法大方向都错了。哎,经验不足,见到的例子太少了
发表于 2012-6-10 12:09:18 | 显示全部楼层 来自: 中国辽宁
强调一下:是一个定义,文档中任何一个可见的"块"都是块参照,即该块定义实例,所谓"嵌套块"是指一个块定义中包含有其它参照.1 S* b) S( w8 r: d- r4 u0 J
无论在模型空间(ModelSpace对象),图纸空间(PaperSpace对象)还是块定义(Block对象)中添加块参照都是使用"InsertBlock"方法.& f+ T/ T" R) ]6 u2 m" A
PS:帖子代码中出现表情是因为代码中挨在一起的的双引号和右括号与论坛的表情代码吻合,被理解为表情了.以后发帖时在双引号和右括号之间添加一个半角空格就OK了.呵呵
 楼主| 发表于 2012-6-10 14:00:36 | 显示全部楼层 来自: 中国广东珠海
4# woaishuijia
0 W* C6 m( \; x% V4 q5 ~"嵌套块"是指一个块定义中包含有其它参照" C4 w) _3 j2 e
原来是这样的啊,需要在“块定义”中添加“块参照”,
就像在模型空间里添加块参照一样。就是说这样的嵌套块只是个定义好了块,下一步就是在模型空间里把这个块的 块参照给insertBlock出来。1 K% E9 [/ z, r
弄明白了问题的本质,呵呵,谢谢斑竹。
发表于 2012-6-10 21:02:53 | 显示全部楼层 来自: 中国辽宁
就像在模型空间里添加块参照一样。就是说这样的嵌套块只是个定义好了块,下一步就是在模型空间里把这个块的 块参照给insertBlock出来。
9 T3 x# o6 L0 V+ y; ]! Q& `
心有灵犀,甚好甚慰.
 楼主| 发表于 2012-6-11 19:29:36 | 显示全部楼层 来自: 中国广东珠海
6# woaishuijia 2 {+ n0 N" [$ ~/ ^* ?( P# e2 |+ ~4 {
呵呵,还有很多要向斑竹学习!
8 y; J4 d9 {/ K1 X. R, r  d) m9 c今天我有遇见了一个问题:我把blockC里面增加了两个圆,然后把BlockE插入后整体旋转,现在我想找出blockE中的 blockC里两个圆的圆心坐标,结果失败了...
3 L. A# y; j& ~' B. t9 C5 O我是这么想的,用两重循环,第一层遍历blockE,找到名字是 blockC的块后就进入第二层循环,然后遍历blockC中的各个图元:圆,直线,文字等等,找到圆就提取圆心坐标。可是就在第二层遍历的时候就出错了,不知道为什么...斑竹帮忙看看怎么解决,新的图纸和代码上传了。

遍历块.rar

36.72 KB, 下载次数: 6

发表于 2012-6-11 21:12:54 | 显示全部楼层 来自: 中国辽宁
本帖最后由 woaishuijia 于 2012-6-12 07:04 编辑 3 x, g. S) V7 y7 g: V- x

8 y7 o' @' M8 ^& ?/ j' d0 A你的目的是
找到名字是 blockC的块后就进入第二层循环,然后遍历blockC中的各个图元

) V9 @' H9 l8 j6 ^+ ~6 o但你代码中
  1. Dim temA As AcadBlockReference
复制代码
temA是blockC的块参照,不是blockC3 D" L( i' T/ P' O4 U0 x6 t
  1. Private Sub cmdInsert_Click()
    * D) ?, X6 W9 a$ B; m% g" m

  2. % d& p4 V  E+ \3 A. X5 C6 W' F% W
  3. Dim ptInsert(2) As Double '原点
    / V- A. G$ [2 K6 y9 I
  4. ptInsert(0) = 09 b4 j7 V" D7 _
  5. ptInsert(1) = 0
    0 A) e& z; G. v& `- n  {) Z
  6. ptInsert(2) = 09 B9 t. H9 W8 J  o' ?8 R9 w% E

  7. 6 O& h9 c$ E9 i  M8 x5 V% G1 q9 |
  8. Dim BR As AcadBlock '定义块* y2 r: o, e9 q; A- t+ N, n' a; J' x
  9. Set BR = ThisDrawing.Blocks.Add(ptInsert, "blockE")2 n* }4 w; y# O- B1 ~; ^% s+ a6 V$ s

  10. % d/ Z8 _( i# l1 S5 H/ W6 K$ q
  11. '清除块E中原有的图元,否则每运行一次程序,blockE中都会添加一些块参照,越来越大了
    1 x$ u" E8 j" Z5 Q
  12. Dim E As AcadEntity
    # [* F8 T& u% f9 g
  13. For Each E In BR6 ^0 }/ Q9 |0 `# w" u
  14. E.Delete; t& Q1 Y+ \) d5 u* G% p, l& }: F1 |
  15. Next1 K1 W) v3 q% g$ V. N0 A+ H9 J
  16. & O- M4 d% `3 E
  17. '----------插入块A 仅一个---------------------------------1 i9 Q: W  X/ a3 M
  18. Dim B As AcadBlockReference '声明一个块参照变量
    4 K! }- y. Q3 [% |! w4 @
  19. Dim P As Variant '声明一个变体变量用于接收三维点坐标
    ! P* y; R* Y! }; E# d* p
  20. Set B = BR.InsertBlock(ptInsert, blkAName.Text, 1, 1, 1, 0)9 w( D) b2 Z. [
  21. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    % }/ c& x1 X8 y4 H/ X& P7 n8 L% t

  22. 2 @& I; p3 i8 I4 W' q* u! f

  23. 4 _8 x% A) f7 o5 h: l9 F
  24. '----------插入块B---------------------------------" O/ Z# B. G2 p' N
  25.   y+ C; x* h% q9 [8 O# l, V. r
  26. Dim pNew(2) As Double
    ' V: F0 b5 B& C/ Q8 M( l% x
  27. pNew(0) = P(0) - 500
    % c5 W) A; G3 @5 t5 P' o, e. e
  28. pNew(1) = P(1) + 1405.08/ W1 y: U, x$ {! O9 m
  29. pNew(2) = P(2)
      }9 u3 I9 w+ ?) h, e+ C
  30. Set B = BR.InsertBlock(pNew, blkBName.Text, 1, 1, 1, 0)
    # Q! i; _1 _  K3 B: ]
  31. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组$ [7 x5 P; `( [2 W5 I8 s

  32. * f/ a) j9 S4 K. R

  33. % G+ n4 }) G* V; C5 Y+ J
  34. Dim I As Integer
    0 t) D. W1 S0 r- A& d, u" N4 t. |
  35. For I = 2 To Val(blkBNum.Text) Step 1
    ' h- x; |& N9 ~) x- t/ k
  36. Dim pBNew(2) As Double
    # A% v% e5 \# [2 F  B
  37. pBNew(0) = P(0)8 o2 z0 h$ }, f% K5 I) C+ |
  38. pBNew(1) = P(1) + 2000
    / z- A! t7 e# _+ d. j1 j. }2 W
  39. pBNew(2) = P(2)1 z. k; [! V  e/ x8 e" u

  40. 5 I+ f, g1 T, Y7 R0 ~4 F- E
  41. Set B = BR.InsertBlock(pBNew, blkBName.Text, 1, 1, 1, 0)- Q: ]' Y) ^4 B1 ~$ c* T) C8 J8 G9 n; R
  42. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    # |1 Y) l# ]# S& b
  43. Next
    # u  ~/ v' h/ H- Y" j
  44. " N4 N" l" M& i$ ~8 k

  45. ! Q2 H7 V) W2 U9 H3 x
  46. '----------插入块C 仅一个---------------------------------
    3 i- v3 t1 x: V* L9 @6 w
  47. Dim pCNew(2) As Double
    5 n9 m" c$ u) N7 U8 l8 n7 Y1 F' g7 G
  48. pCNew(0) = P(0)
    1 }! A* f! N" Y1 M% o
  49. pCNew(1) = P(1) + 2000$ q6 P- ?* y0 O
  50. pCNew(2) = P(2)
    ! f" G0 N; \( W6 Q' d/ |
  51. Set B = BR.InsertBlock(pCNew, blkCName.Text, 1, 1, 1, 0)0 @% F6 b5 L' k
  52. Set B = ThisDrawing.ModelSpace.InsertBlock(ptInsert, "blockE", 1, 1, 1, 0)
    1 ^7 h7 Q) v" W: H, M

  53. " |  ^! u. W4 t+ M3 Q, c$ s
  54. 2 z+ m) S) l' I  x( O
  55. '----------旋转块E---------------------------------
    ' ]0 f' [" K4 e) ~( a+ t
  56. B.Rotate ptInsert, 0.2
    3 g5 X+ h1 N6 m: U2 P$ k

  57. ; @* `, b3 j8 v# g1 X8 h' e
  58. '----------查找块E中的块C的两个圆的圆心坐标---------------------------------5 q) ~5 F5 B4 Z
  59. 7 N. q& l; T. m! S
  60. Dim temA As AcadBlockReference" ~6 _1 q3 l6 `$ ?/ J/ \
  61. Dim temB As AcadEntity. B6 Z6 f* M! {: u" }5 e2 R
  62. Dim ptCir1(2) As Double '第一个圆圆心坐标9 t3 k0 ^! N6 g$ B
  63. Dim ptCir2(2) As Double '第二个圆圆心坐标9 G! S; Y& a, [: n. ^  a5 }5 e% q
  64. Dim C As Variant, J As Integer
    / j( R1 I- h* Y5 s& _; i
  65. ) N! ^6 A( ^0 a) V/ t; d4 l
  66. For Each temA In BR '这个遍历就行
    $ {2 }) S6 h& U- A4 U
  67. If temA.Name = blkCName.Text Then
    9 S+ N- T3 X! S+ W
  68. P = temA.InsertionPoint '提取块C参照在块E中的插入点坐标
    ( D  ^4 m8 w' X% u
  69. J = 1
    : `# n; W2 `& K5 e) C9 \$ ~& w
  70. ' For Each temB In temA '在这里就开始出错了,因为这个temA是BlockReference,是块C的参照2 A: x: R& H/ g
  71. For Each temB In ThisDrawing.Blocks(temA.Name) '这个才是真正的块C,呵呵3 f+ J  Y8 C) z0 B# T
  72. '开始找圆,找到圆就提取坐标
    3 X- N5 P4 L0 \% [, N. I
  73. If temB.ObjectName = "AcDbCircle" Then6 W8 C! Y  ^& p0 C( q0 |% M& L
  74. C = temB.Center '提取圆心坐标
    6 b) W/ f& |) d9 F
  75. C(0) = ptInsert(0) + P(0) + C(0) '计算该圆心在模型空间的坐标--块E参照未旋转时+ H. z# a0 ~+ [6 r& O/ v2 r5 ?
  76. C(1) = ptInsert(1) + P(1) + C(1)
    1 R1 a4 D1 b; U% l
  77. C(2) = ptInsert(2) + P(2) + C(2)
    ) {! ~* O; }1 K
  78. If J = 1 Then
    , l5 B7 ?9 p% O- N8 h! @8 {0 x6 v
  79. ptCir1(0) = C(0) * Cos(0.2) - C(1) * Sin(0.2)4 C7 Y- v8 C. j9 A: [& V8 p- Q9 A
  80. ptCir1(1) = C(0) * Sin(0.2) + C(1) * Cos(0.2)
    + c$ {% ]* P4 Q" q$ `# \: l/ ^
  81. ptCir1(2) = C(2)/ e+ E, R3 d& A6 B5 Q4 X. Q$ [
  82. J = 2
    ( w9 T2 l9 g1 Y. U8 y, ]  N
  83. Else
    * Q# y1 p! a& d' i6 y; s8 s
  84. ptCir2(0) = C(0) * Cos(0.2) - C(1) * Sin(0.2)& W$ h1 R: L' T' A5 l+ j% B( k7 d' X! f
  85. ptCir2(1) = C(0) * Sin(0.2) + C(1) * Cos(0.2)9 w% F9 u" L1 F3 \- g
  86. ptCir2(2) = C(2), `( N% j& ]: G0 M. w+ u
  87. End If4 ?* ?* g" H' v7 E7 j9 `& c
  88. End If# F+ Y2 W3 J4 D% w
  89. Next
    / L0 {6 t+ i$ w1 T# R6 l9 Y
  90. End If
    , R* ^8 X' r9 m8 u
  91. Next
    * \4 A0 {( c* K5 v0 J( u9 p8 B
  92. ' o8 M. J' v$ _5 Z
  93. 5 P8 n/ o9 G% i* S, h
  94. ThisDrawing.Regen acActiveViewport
    ( h3 ^; N2 V  N
  95. * m1 h0 `3 [* d/ a+ A
  96. End Sub
复制代码
- r1 r  p& N  f/ A  a
计算圆心在块E参照旋转后在模型空间的坐标,除了上面用三角函数计算的方法外,还可以借助UCS变换或使用辅助线(点)的方法,下面是UCS变换# _' Z2 |. y0 q! o3 @: K1 z
  1. Private Sub cmdInsert_Click()
    1 l$ {# P4 t9 h) I  N  D% ~3 U6 m
  2. Dim ptInsert(2) As Double '原点$ ^( N* v( z9 ^- W, f- _
  3. ptInsert(0) = 0
    6 w6 N2 P1 n' T  r" l# m+ s
  4. ptInsert(1) = 0
    ) C: |6 t0 _  W# [
  5. ptInsert(2) = 0! `4 p% a* `( D2 e- s& o
  6. Dim BR As AcadBlock '定义块
    . G: z- v/ r' r! A- C3 _/ q
  7. Set BR = ThisDrawing.Blocks.Add(ptInsert, "blockE")
    6 F) E8 S) N- P6 D* z0 |1 ?. K
  8. '清除块E中原有的图元,否则每运行一次程序,blockE中都会添加一些块参照,越来越大了
    7 _' i, ]! z9 I3 K7 O
  9. Dim E As AcadEntity
    # X4 h: {/ S0 C- {, L' _6 B  F
  10. For Each E In BR
    , b7 I; B2 {( _8 ~8 c! B
  11.     E.Delete
    ' D& V7 g' c9 m# c7 D' V4 F7 n
  12. Next+ B' s& G& v2 r0 Q* e: I
  13. ' K8 t( o  i, Q$ V- n' r% G
  14. '----------插入块A 仅一个---------------------------------
    5 g% Z5 z6 f4 O1 l$ R8 l
  15. Dim B As AcadBlockReference '声明一个块参照变量1 O2 ~$ k1 b( r3 O$ F
  16. Dim P As Variant '声明一个变体变量用于接收三维点坐标) @9 g9 n, Y( F3 i: t2 s
  17. Set B = BR.InsertBlock(ptInsert, blkAName.Text, 1, 1, 1, 0)0 m3 R. q: w8 }" o: ^; P% ~& t
  18. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组+ w3 H0 {- G* J! b; i
  19. / h  h6 x/ _4 t, c
  20. '----------插入块B---------------------------------
    / ?& a. Q0 W8 E9 j
  21. Dim pNew(2) As Double
    " J/ p. C7 l6 O2 f
  22. pNew(0) = P(0) - 500+ Y" [6 K  l5 ]+ p4 c
  23. pNew(1) = P(1) + 1405.08% d$ k7 R1 i; w" {9 z& s4 h
  24. pNew(2) = P(2)
    ' P! D  ?" x5 B. d
  25. Set B = BR.InsertBlock(pNew, blkBName.Text, 1, 1, 1, 0)
    5 ~- D) v; R. Q2 X. q+ N. E4 ]
  26. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组& [2 R, V# ?  b
  27. Dim I As Integer
    ) }+ F- R/ m) q4 [/ ?" f- ^
  28. For I = 2 To Val(blkBNum.Text) Step 1) l* M. F5 z/ M! v/ [8 t6 h
  29.     Dim pBNew(2) As Double. k3 H+ Z( b0 m
  30.     pBNew(0) = P(0)
    7 F/ L  s! f; b; V
  31.     pBNew(1) = P(1) + 2000
    ) ^8 e  Z' ]! K; L0 [* B" J$ Q
  32.     pBNew(2) = P(2)1 K: p) E% K$ C9 M
  33.     6 ]9 a) _1 @! O
  34.     Set B = BR.InsertBlock(pBNew, blkBName.Text, 1, 1, 1, 0)
    - O# ?* w2 q3 C# _  k; q$ U1 ^; ?
  35.     P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组/ {/ v, `/ \- q& |) S/ V2 ^
  36. Next; l1 w& ~5 `1 h
  37. + d/ k% t3 |* I/ r  l' P& w6 v
  38. '----------插入块C 仅一个---------------------------------
    8 I" Q& N* X' ~- D
  39. Dim pCNew(2) As Double7 u9 w. @9 w, _. K7 u) p
  40. pCNew(0) = P(0)
    + G8 m/ Y# l# ]$ v: z5 k
  41. pCNew(1) = P(1) + 2000: b# W/ R. I2 Z, [  U/ `! c' {: f
  42. pCNew(2) = P(2)) y, w& N. x7 |( c7 w9 `9 H
  43. Set B = BR.InsertBlock(pCNew, blkCName.Text, 1, 1, 1, 0)6 @( w8 ~* M  k; A6 q, @! W
  44. Set B = ThisDrawing.ModelSpace.InsertBlock(ptInsert, "blockE", 1, 1, 1, 0)
    9 K" K  i) E( A
  45. 5 l) U6 \5 |6 |  s- X4 ~& f2 s) J( L$ X
  46. '----------旋转块E---------------------------------. N/ J& E* z- H# X$ C. s
  47. B.Rotate ptInsert, 0.2: k: @' [# v( A, A: x# G
  48. '创建两个UCS,用于下一步转换圆心在模型空间的坐标
      T  v4 u8 n. B+ z6 g
  49. '其中,MyUcs是绕原点右旋0.2弧度,对应块E左旋的0.2弧度
      G- r/ O* n3 z" v& |$ }' j2 k
  50. Dim MyUcs As AcadUCS, MyWcs As AcadUCS
    ) x4 G1 {3 b3 W* G9 N6 _* |) T3 A
  51. Dim XP As Variant, YP As Variant6 |+ `% }- a- D
  52. With ThisDrawing( B7 l4 w8 s, ?' [/ X
  53.     With .Utility
    6 u* k7 Q( o! `0 ?) M
  54.         XP = .PolarPoint(ptInsert, -0.2, 1)
    % E) [/ h* a( U, t
  55.         YP = .PolarPoint(ptInsert, -0.2 + .AngleToReal(90, acDegrees), 1)' O! C7 L# A4 K7 @7 V6 f
  56.     End With. W$ T( F2 D* f  Y+ [
  57.     Set MyUcs = .UserCoordinateSystems.Add(ptInsert, XP, YP, "MyUcs")6 O' t, y3 q( Q2 N( T$ z
  58.     XP(0) = 1: XP(1) = 03 Y4 L% F" B* K9 s& p( j
  59.     YP(0) = 0: YP(1) = 1
      l/ L' F7 D( S* G" W7 E: U
  60.     Set MyWcs = .UserCoordinateSystems.Add(ptInsert, XP, YP, "MyWcs")
    / l# u8 Q! j5 i# @
  61. End With
    ( l% c! [2 u. _7 C: ]

  62. 0 c5 O/ N; \/ S4 Z: o& q
  63. '----------查找块E中的块C的两个圆的圆心坐标---------------------------------& ?  @0 f. s8 C1 u
  64. Dim temA As AcadBlockReference
    , Q+ R* c3 B/ p! T  ~# {6 Q( R0 }
  65. Dim temB As AcadEntity" ^/ B1 `; y6 T; c# q- M
  66. Dim ptCir1(2) As Double '第一个圆圆心坐标
    + X4 @1 a+ W: ~% Y
  67. Dim ptCir2(2) As Double  '第二个圆圆心坐标2 _3 }0 q! ]! @2 h
  68. Dim C As Variant, J As Integer
    , r2 J, Y- [9 w
  69. For Each temA In BR '这个遍历就行3 B0 ^/ E( r. f, `) T0 s
  70. If temA.Name = blkCName.Text Then
    % s1 a& ]- ?( C, @
  71.    P = temA.InsertionPoint '提取块C参照在块E中的插入点坐标
    9 b! z+ Q- L/ n  R& I, N3 z( j
  72.    J = 1
    * g! J9 o4 ?$ T0 v9 Q# Q  f1 x. z
  73. '   For Each temB In temA   '在这里就开始出错了,因为这个temA是BlockReference,是块C的参照" t; X5 {: O% t5 _/ x2 q
  74.    For Each temB In ThisDrawing.Blocks(temA.Name) '这个才是真正的块C,呵呵
    0 E) s9 z* |3 W4 P2 x9 h- O
  75.    '开始找圆,找到圆就提取坐标
    3 l( Y! U0 L4 ?
  76.     If temB.ObjectName = "AcDbCircle" Then7 \! s; t% Z7 o/ u/ [* T
  77.         C = temB.Center '提取圆心坐标
    3 \9 F; Z$ D  Y8 N# `. z
  78.         C(0) = ptInsert(0) + P(0) + C(0) '计算该圆心在模型空间的坐标--块E参照未旋转时% \4 F  }6 l3 }& K8 U  P% d! T
  79.         C(1) = ptInsert(1) + P(1) + C(1)( k* M+ P' [( E, B# C
  80.         C(2) = ptInsert(2) + P(2) + C(2)" H1 C, E) o0 Q+ D
  81.         ThisDrawing.ActiveUCS = MyUcs '把当前坐标系改为MyUcs9 A+ e% N& K+ K! I* m) y
  82.         C = ThisDrawing.Utility.TranslateCoordinates(C, acWorld, acUCS, False) '得到该圆心在UCS中的坐标--块E参照旋转0.2弧度后该圆心在模型空间的真正位置0 i  l( o9 P7 X4 s4 f  t! B# i* B
  83.         ThisDrawing.ActiveUCS = MyWcs '把当前坐标系改回WCS, `0 w- P/ o; |
  84.         If J = 1 Then
    ) p8 g' q7 b  ?" h
  85.             ptCir1(0) = C(0)
    " S! j( k; |3 o, r4 i
  86.             ptCir1(1) = C(1)# E, s5 i1 V' n- c: X
  87.             ptCir1(2) = C(2)
    ; B* ~& V) K2 N: l: ~; c
  88.             J = 2! j; v1 @4 `- h
  89.         Else
    * H( c* S& j% `, A7 J
  90.             ptCir2(0) = C(0)% R" m$ X7 n! z1 J; s! N
  91.             ptCir2(1) = C(1)
    ) Q+ ^# C: z. p* w
  92.             ptCir2(2) = C(2): x. N+ ~% d6 a  A
  93.         End If
      h2 l( y1 t% i) L; [+ E
  94.     End If- n5 |' a" _% h& ~
  95.    Next
    + e7 O$ H8 m* B3 c6 |; W! n; X, W- a
  96. End If6 V/ ]1 o- ~: p4 L. q
  97. Next
    3 C0 a. o0 ^' D: Q8 Z

  98. 1 R- t& U/ a4 C6 Y
  99. # ^) N: t/ T7 G: _4 X, U( o
  100. ThisDrawing.Regen acActiveViewport
    $ o9 s) r: G. n& k( [
  101. End Sub
复制代码

8 ^; Q; t8 ~; z3 H1 X3 D7 l下面是使用辅助点  w% t6 r" Q( o) Z
  1. Private Sub cmdInsert_Click()& E4 P  T* ?7 Q* P) @$ g2 E
  2. Dim ptInsert(2) As Double '原点/ [, v3 G! g( F* c7 K7 `* k
  3. ptInsert(0) = 0. B" N. a* k# X1 _
  4. ptInsert(1) = 0. u; Z7 ~& [* v; y$ D7 e1 j/ o* Y
  5. ptInsert(2) = 0
    - D) ^, H  F! A
  6. Dim BR As AcadBlock '定义块
    " c) V3 I% \. J" N4 r( _
  7. Set BR = ThisDrawing.Blocks.Add(ptInsert, "blockE")
    " I3 d7 [2 o5 Z) N
  8. '清除块E中原有的图元,否则每运行一次程序,blockE中都会添加一些块参照,越来越大了
    ( K* [1 l: @7 D8 }5 E, n
  9. Dim E As AcadEntity& P" C9 ?3 _3 b1 ]% f3 g
  10. For Each E In BR7 }' X3 E6 r; J# Q: D. E
  11.     E.Delete
    - P& J" o" \% `. F
  12. Next
      D# K( z. I6 Q9 i, e
  13. '----------插入块A 仅一个---------------------------------
    : i% l9 Y# j7 a8 ]5 Z8 W
  14. Dim B As AcadBlockReference '声明一个块参照变量3 C/ ^) h: v& j. }0 C# h) I' E
  15. Dim P As Variant '声明一个变体变量用于接收三维点坐标, r7 W( V; d2 D  ?, @0 \
  16. Set B = BR.InsertBlock(ptInsert, blkAName.Text, 1, 1, 1, 0)+ S( m: e: \5 {5 J( U" D
  17. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    ' z2 F7 G) s  R3 @/ c! r5 P, t
  18. ) M: E" i# P) J2 V- C1 u5 q
  19. '----------插入块B---------------------------------' V$ ]; |$ x' M* ^: @1 @
  20. Dim pNew(2) As Double, w% U$ x- N: i8 D9 C
  21. pNew(0) = P(0) - 500
    ! t; V2 _0 A2 @( u& `
  22. pNew(1) = P(1) + 1405.084 c. z$ a' }. P, w; T* r3 O' ^
  23. pNew(2) = P(2)
    : p# P7 J- X4 e# _. Y" ]
  24. Set B = BR.InsertBlock(pNew, blkBName.Text, 1, 1, 1, 0)
    % m/ D) l# N- `: ^. G/ a
  25. P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    ) a& R% z! M3 ?) l* B) N6 A
  26. 8 Z8 K- ^+ b% [
  27. Dim I As Integer/ s, n2 Z: \" }$ {2 G
  28. For I = 2 To Val(blkBNum.Text) Step 1( v3 K$ i& }% z8 Y
  29.     Dim pBNew(2) As Double; G1 g9 N3 r  D0 [$ P
  30.     pBNew(0) = P(0)4 d  w, ~; p) c) n7 j4 i$ x& z5 E
  31.     pBNew(1) = P(1) + 2000% i  H7 d9 i4 d
  32.     pBNew(2) = P(2)1 P3 f4 z. `' ?3 ]& |( ?0 `
  33.    
    2 J; [& u0 l* r/ Q
  34.     Set B = BR.InsertBlock(pBNew, blkBName.Text, 1, 1, 1, 0)% ~4 `" C# H. ~: z, o$ c: ]; Y- K
  35.     P = B.InsertionPoint '提取上一步插入的块参照的插入点坐标,返回值是三元素双精度数组
    % `! R. r8 Q1 Z
  36. Next% |$ Z) J$ x2 z2 \; V

  37. " {2 ]) V5 L6 L; x
  38. '----------插入块C 仅一个---------------------------------+ ]) e* R. u& e- c& }
  39. Dim pCNew(2) As Double
    . R* H. h2 N2 M  e8 A
  40. pCNew(0) = P(0)
    ) F! W4 o8 V$ d! T) [
  41. pCNew(1) = P(1) + 20001 ~* g; v7 m( N. f. U. C
  42. pCNew(2) = P(2)
    # S. P+ g& i+ e- D
  43. Set B = BR.InsertBlock(pCNew, blkCName.Text, 1, 1, 1, 0)
    5 ~2 e/ n9 o1 m" M
  44. Set B = ThisDrawing.ModelSpace.InsertBlock(ptInsert, "blockE", 1, 1, 1, 0)
    + k" t& I7 P' U) Z3 _% Q% ?  [3 R
  45. 9 v' l, |9 E1 x( Q1 O  T( f
  46. '----------旋转块E---------------------------------) p, c, _: z6 l6 O7 O" L0 t0 L) w
  47. B.Rotate ptInsert, 0.2
    9 }$ [, b3 S2 P% T& R, Y& m
  48. '----------查找块E中的块C的两个圆的圆心坐标---------------------------------
    1 X* {+ I" Q7 `
  49. Dim temA As AcadBlockReference
    5 J+ ~% S# l1 o! ~- M, g! W6 A" f
  50. Dim temB As AcadEntity& X8 h- o( ~- O$ |) E
  51. Dim ptCir1(2) As Double '第一个圆圆心坐标
    2 v3 {, U3 R/ D, l2 J7 I
  52. Dim ptCir2(2) As Double  '第二个圆圆心坐标
    , p9 f# I' J8 x5 n" |1 f8 g
  53. Dim C As Variant, J As Integer9 }$ p! m$ B8 g4 w. Z
  54. Dim ObjP As AcadPoint '点对象,用于下一步计算圆心坐标
    ) W0 g4 h8 Q3 K( }0 a6 l, m  J8 J
  55. For Each temA In BR '这个遍历就行
    6 K! r3 z! q; B6 Q+ i3 M) {0 d7 T
  56. If temA.Name = blkCName.Text Then) F. @" w  g0 f3 }8 A/ P
  57.    P = temA.InsertionPoint '提取块C参照在块E中的插入点坐标
    ( Z7 C2 Y* `+ B: |- J
  58.    J = 1/ W6 V9 `% t. s
  59. '   For Each temB In temA   '在这里就开始出错了,因为这个temA是BlockReference,是块C的参照: y( ]/ ?3 u) Q  D
  60.    For Each temB In ThisDrawing.Blocks(temA.Name) '这个才是真正的块C,呵呵5 T, F( a/ |) T3 O
  61.    '开始找圆,找到圆就提取坐标
    ) Y: I9 H$ ^5 N* E
  62.     If temB.ObjectName = "AcDbCircle" Then
    ' a* o5 E0 n& {" h( {
  63.         C = temB.Center '提取圆心坐标; Y" O0 r$ B; H2 i  p
  64.         C(0) = ptInsert(0) + P(0) + C(0) '计算该圆心在模型空间的坐标--块E参照未旋转时( W2 o# L5 ?& n+ p+ c8 L9 h" c0 M
  65.         C(1) = ptInsert(1) + P(1) + C(1)
    % d8 Q0 z$ y1 _4 m
  66.         C(2) = ptInsert(2) + P(2) + C(2)2 H+ r7 [1 y( p! {2 U* L
  67.         Set ObjP = ThisDrawing.ModelSpace.AddPoint(C) '在块E参照未旋转时的该圆圆心画一个辅助点
    4 r1 {' G, ^$ c. {+ x8 _. `
  68.         ObjP.Rotate ptInsert, 0.2 '和块E一样,让该点以原点为基点旋转0.2弧度6 s  j" ]6 N% ]$ v( D
  69.         C = ObjP.Coordinates '提取点坐标,即该圆心在模型空间真正的位置
    ; V7 h1 o/ n& c' g
  70.         ObjP.Delete '删除用过的辅助点; p) v) [1 C& J5 V6 H, R8 f% c" o2 S
  71.         If J = 1 Then1 b! G& c+ k( s% V5 D3 j0 v, i( d
  72.             ptCir1(0) = C(0)
    5 X: `( i9 }" l. ]0 C* i9 W1 c% {$ ?  B
  73.             ptCir1(1) = C(1)# }- Z" {. u* }- O6 n! L
  74.             ptCir1(2) = C(2)8 Q' N* S1 c5 @9 F/ Z! E+ r
  75.             J = 2
    3 O$ P7 h+ ]' D% \1 p
  76.         Else7 k) l) \- }8 X- J7 d$ T
  77.             ptCir2(0) = C(0)
    0 \% p3 [- n3 o) W
  78.             ptCir2(1) = C(1)8 K: ^* v. g# r* [# {$ @* Z
  79.             ptCir2(2) = C(2)
    " L/ ~7 F, e- |3 x: C
  80.         End If
    5 X% u0 x, g! L
  81.     End If5 Y6 ]. P7 c( i0 ^. N  U; |- o! h
  82.    Next0 k# G: D6 B) P  i# o* |" f
  83. End If
    , {/ {  B. M% ~8 V3 K
  84. Next
    ( x, S# I) g+ y% [7 E4 }

  85. ' T7 u' \  P. m: C+ I' F9 Y
  86. ThisDrawing.Regen acActiveViewport
    . c+ ?0 _/ j  D4 f2 b4 {
  87. End Sub
复制代码
 楼主| 发表于 2012-6-12 09:49:48 | 显示全部楼层 来自: 中国广东珠海
本帖最后由 tataki 于 2012-6-12 10:01 编辑 ( f; l; C0 r0 Y" _% r1 l( H* a

' q9 [: u7 k( E& o1 C, U 8# woaishuijia ; J. ?9 Z7 m; [9 s, L  |
昨晚看到斑竹的回复,今天早上正准备给回复呢,没想到你一大早就重新编辑了帖子,还把圆心坐标的算法都用了三种方法给求解,让我这个7点还在睡觉的无地自容....% ]$ f5 d6 u9 ~$ e% |0 W5 W/ j: s# i
你以前说过“所谓"嵌套块"是指一个块定义中包含有其它参照.3 G* n9 B1 ?% L) K( U4 \+ Q”,所以我temA定义的是AcadBlockReference,呵呵,这个我觉得没问题。. w$ ]$ f# R! Y% \+ s8 ]" J$ P( G6 \
当然我也想过定义 temA为 AcadEntity 或者 Object,不过遇到了错误,这里一并询问(稍后我问,呵呵,先说block)2 [- U' w" m/ N1 P. a& m0 Q. i

6 X: h0 o: e9 @0 }4 s/ |* J斑竹的意思是不是说不论给“块”添加图元或者要遍历,都是以“块”为对象的,而不是块参照。
# J+ Y4 ?: E; Z* _+ k) ]% X3 k我第一层遍历 For Each temA In BR 没有错,因为BR就是我定义的“块”,属于blocks集合里面,
3 Z  g) @" l5 H  C4 W% B而到了第二层 ,我原来写的是 For Each temB In temA  ‘temA定义的是“块参照”,当然也就错了...应该从blocks这个集合里面找到原始的"块" blockC 来遍历,所以你用了.Blocks(temA.Name)这个写法找到了“块”,嘿嘿 ,understand!4 a. e: R! N. d0 M6 i
; a1 j$ V9 m/ g$ ~/ O) g
另外,斑竹写的这一段让我发现自己考虑不周到,呵呵,确实是没运行一次,blockE里面的东西越来越多...
6 S: V; k3 |6 q' f7 f; d$ @8 S, n'清除块E中原有的图元,否则每运行一次程序,blockE中都会添加一些块参照,越来越大了
5 B+ V) _1 ~1 h! p9 _( F! v1 Q1 {Dim E As AcadEntity
- i* d1 G: H2 U3 C4 K; w- lFor Each E In BR
7 K2 }( B& H- J, y9 q% fE.Delete
7 r7 `1 E- P$ M2 ONext$ {! E5 A; `: r
5 w, {/ ]% S9 A% y

# k( P1 {! x0 M! j& S7 M/ \: d2 R! {7 A2 V6 s
第二个就是圆心坐标,我昨晚这么写了一下:& R1 j' Q  Q! s$ |2 g; ?
Dim temA As AcadBlockReference
7 p4 x& U; `( U8 ]3 ]4 nDim temB As AcadEntity& A3 m/ m; w6 F; u4 o8 O7 V3 p1 _
Dim ptCir(1) As Variant  '圆心坐标9 d5 l4 A& {; M9 X6 r, T. Z

  ?6 \* N  |& \For Each temA In BR '这个遍历就行
) z; b" a5 E# K0 P* l3 z# o! w If temA.Name = blkCName.Text Then1 z7 @. P3 H7 ~2 F
i = 0* `7 Y' H/ d% k7 u& ~' ?
   For Each temB In ThisDrawing.Blocks(temA.Name)
" n- T- m0 r( G* ?5 I& m+ c    '开始找圆,找到圆就提取坐标% e  B4 K2 A! z; V4 O, h- P+ w
    If temB.ObjectName = "AcDbCircle" Then5 Z! h  }3 s/ b# i8 o- U. S
       ptCir(i) = temB.Center: i = i + 19 O* _9 a( J/ |5 w
    End If
/ q1 c( j" s, T7 }3 n! M  Next$ G8 q& A% _* P4 E
End If
6 A- f9 Y) E% i8 u5 XNext
, `- S, l+ c( z) O
3 X4 U7 y- J# B6 N6 ]这样找到的圆心坐标并不是我要求的,我调试了一下发现,这样求的坐标实际上是“块” blockC里两个圆的圆心坐标,而这两个坐标应该是从blockC 的“坐标系”开始算的吧,我的blockC刚好是矩形,所以计算坐标原点恰好是矩形左下角点,我推测,如果blockC不规则,那么坐标原点应该是对blockC使用getboundary后确定的那个边框的左下角点,呵呵,猜测的,还没验证。# k  H+ ^# [, p4 r/ _4 h
所以斑竹用了三种方法算需要的坐标,当然,用三角函数这个确实最合理,呵呵。我能看懂。, B, p/ d- _, ^3 a; [
另外使用UCS,这个方法好~上周发过贴恰好问过lisp中trans的用法,这次在vba中见到你那篇帖子里提到的对应的TranslateCoordinates的用法了,我得学习消化下" L' [! ]& \" v. W6 k
辅助点这个方法,说实话,我都不敢用,我怕的就是往图纸上添加一个点容易,删除一个点麻烦了,呵呵,水平不够,要努力!
8 T- r: W* o# C3 P) i5 J, v: C/ r4 h4 P
说完了这个,我再问问定义temA的问题,我是这么想的:
) s- j/ v/ r+ T4 b  y因为blockE里面只有块参照,所以temA自然而然的定义成了AcadBlockReference,对应的使用temA.Name就行9 r* M0 r4 {% p# z" b4 g, B
后来我想过为什么不定义temA为AcadEntity(我也试过了定义AcadObject)呢,因为这样的用法很常见啊,但是发现错了,因为就没有temA.Name属性了,只有temA.ObjectName属性,但是后者返回的是“AcdbBlockReference”,并不是块的名字...我再想是不是因为“块”比较特殊,有特定的名字,所以只能定义temA为AcadBlockReference后才能找到块的名字,其他的都不行。
; o' E" K/ F- {9 c- Y. @* J进一步讲,定义temA为AcadBlockReference,我觉得局限性挺大的,因为我这里的blockE确实只含有“块参照”,没有其他图元,比如直线,文字等,如果我给blockE里面再添加一点直线或者文字(块里面添加文字应该很常用),这样我遍历BlockE的时候,就会出错,因为文字里面没有temA.Name属性...所以要想完整的遍历包含块参照和各种图元的块且不出错该怎么做好呢?
发表于 2012-6-12 13:52:23 | 显示全部楼层 来自: 中国辽宁
本帖最后由 woaishuijia 于 2012-6-12 14:01 编辑
. R$ K# w% z& `5 O1 a/ x# i. e# `6 u% k1 E1 R
9# tataki
2 {7 ^2 R8 M7 O: V9 D
斑竹的意思是不是说不论给“块”添加图元或者要遍历,都是以“块”为对象的,而不是块参照。
0 l5 h! O: f) @4 u  l: Q
正确.  H8 j% U' w5 H0 H6 o/ d& ?5 W. |
多说几句:能够"遍历"的前提是对象是一个集合,而集合是有"Item"方法的.比如Documents,ModelSpace,PaperSpace,SelectionSets,SelectionSet,Groups,Group,Blocks,Block,TextStyles,Layers,LineTypes等等,都是集合,都可以遍历.但BlockReference不行,它不是集合,而是一个块定义的实例.文档中同一个块的每个参照包含的子对象都是一样的(除其中的属性值外),它包含的图元种类数量位置都完全相同,因为这取决于其定义,所以想提取任何一个块参照内部子对象的特性,只能到其定义中去找.除了块参照对象的属性值是用BlockReference的GetAttributes方法,获取其属性参照对象数组.而属性定义对象本身的添加和编辑也是要在Block对象中进行; {+ m: e' y* l: ~; \
我调试了一下发现,这样求的坐标实际上是“块” blockC里两个圆的圆心坐标,而这两个坐标应该是从blockC 的“坐标系”开始算的吧

7 R/ {& b. S( n: Y& `正确
# {% T  m4 b: t; x$ w& E- s
我的blockC刚好是矩形,所以计算坐标原点恰好是矩形左下角点,我推测,如果blockC不规则,那么坐标原点应该是对blockC使用getboundary后确定的那个边框的左下角点,呵呵,猜测的,还没验证。

4 e' B" R9 y+ j3 t/ o1 v( C错了.+ h5 v- C! C! |$ \8 n2 o+ F
我们在使用Blocks集合对象的Add方法新建Block对象时有两个参数,第二个是块名称字符串,你懂的;而第一个InsertionPoint,就是块基点.我们在图形界面选择一个块参照对象时,块参照会有一个蓝色亮显的夹持点,这就是块基点.正像你前面说是那样,块定义是有自己的坐标系的.我们往块定义中添加图元是使用块定义的坐标系,同样,创建块定义时给定的块基点也是使用这个坐标系.通常我们在创建块时把块基点放在块定义的坐标系的原点,就是InsertionPoint参数使用(0,0,0).这样可以减少坐标换算的麻烦.  s6 F5 Y* _6 a1 z; B, P
在我们向模型空间或图纸空间或其它块定义中添加块参照时,块参照是以块基点为准放到插入点(就是InsertBlock方法的InsertionPoint参数)上的.
8 _2 X' A, _9 g1 A1 V" k就是说,当我们把块定义的块基点设为(0,0,0)时,块参照的子对象的位置坐标就等于其在块中的坐标与块参照的插入点坐标之和.
& z( L0 {7 l; ]+ n7 r当块定义的块基点不是(0,0,0)时,块参照的子对象的位置坐标等于其在块中的坐标与块基点坐标之差再与块参照的插入点坐标之和.
$ f- a% D' @$ B+ F' W( ]GetBoundingBox方法可以得到的矩形框的左下角点,在本例中与块C参照的块基点坐标重合,只是巧合而已.如果块C的块基点不在左下角,或块C参照被旋转了一个角度,就不重合了.
$ O; K& W3 ?. r
要想完整的遍历包含块参照和各种图元的块且不出错该怎么做好呢?

0 P- O5 p. G' F/ H增加一个条件语句就可以了
  1. Dim temA As AcadEntity8 y4 {) Y# K: F4 W+ u
  2. Dim temB As AcadEntity  c" P: C( s( x/ `
  3. Dim ptCir(1) As Variant  '圆心坐标' r* [+ Q6 w/ C3 h' y
  4. For Each temA In BR '这个遍历针对块中的Entity6 W- _7 X3 F+ i4 D8 C( C" |$ U
  5.     If temA.ObjectName = "AcDbBlockReference" Then'先检查temA是否块参照8 n6 d% y% c+ ~0 [5 F1 e
  6.         If temA.Name = blkCName.Text Then'确定是块参照后再检查其名称" u( N  E: N+ e4 i/ v
  7.             i = 0$ A7 Z! l9 V: d; m7 N
  8.             For Each temB In ThisDrawing.Blocks(temA.Name)
    . Y( @. f& ?- x
  9.                 '开始找圆,找到圆就提取坐标
    * [5 k, Z5 G" j: ~- D* ^0 D7 X
  10.                 If temB.ObjectName = "AcDbCircle" Then
    ' f" U8 \! d% A* T2 a
  11.                    ptCir(i) = temB.Center: i = i + 1
    " p9 u0 m1 u' T5 }
  12.                 End If
    ) h1 s- x* W9 Y" y( _
  13.             Next" b! r7 m' Q7 A4 a: H
  14.         End If8 m) A3 |' w2 `4 Y; X
  15.     End If- z  M6 u8 l+ a; n2 F( [
  16. Next
复制代码
 楼主| 发表于 2012-6-12 20:50:03 | 显示全部楼层 来自: 中国广东珠海
本帖最后由 tataki 于 2012-6-12 20:51 编辑
$ N6 m3 ]' M, [: X
/ N! ?0 w* ?2 P. H“通常我们在创建块时把块基点放在块定义的坐标系的原点,就是InsertionPoint参数使用(0,0,0).这样可以减少坐标换算的麻烦.”8 \, K6 Y: I! m6 ]/ T  E1 ?" x8 e
你这一句一下让我想到了一件事:  \1 v! ]" Q& `- ]
我的blockE是我在代码中指定的基点 0,0,0$ z$ [  B3 L" k! A* C$ c; Z+ t
但是其他几个块A B C D是我用GUI方式定义在图纸里面的,当时我觉得方便就把C块基点设置在了左下角(cad提示我选择基点)  `: ~- D) i; D4 I/ J
对于GUI方式设置的基点,cad会默认把块坐标系的原点设置在这个基点上!而且基点的坐标就是0,0,0,感觉很诡异,这个在cad2011里面很明显,打开块编辑器后,明显的看到块坐标系的原点就是默认设置到我选择的基点上,图里左边是模型空间的坐标显示,右边就是块编辑的坐标显示!!!!这个我一直没注意!而我当初给blockE设置基点的时候只是图了方便设置到原点上,看来真是碰巧!也就是说,如果通过GUI方式,默认的就是基点和原点重合且是0,0,0,这样确实方便了以后的编辑!而用代码方式就是要指定基点了。
) X8 H- S' n9 W; U$ \我这样理解的对吗?; T: y6 p. Y+ N, A5 W( s5 w

6 v4 G7 D! i) x, @1 R* }% L" f3 ]0 I$ j呵呵,还有后面那个完整的遍历包含块参照和各种图元的块且不出错的代码真好,先用objectName找出是块参照的,然后再查询块参照的name进行对比,满足后再进入块的子项
块基点和坐标系原点.png

评分

参与人数 1三维币 +10 收起 理由
woaishuijia + 10 进步明显

查看全部评分

发表于 2012-6-12 20:56:02 | 显示全部楼层 来自: 中国辽宁
11# tataki 完全正确
发表于 2014-5-14 16:41:20 | 显示全部楼层 来自: 中国北京
“就像在模型空间里添加块参照一样。就是说这样的嵌套块只是个定义好了块,下一步就是在模型空间里把这个块的 块参照给insertBlock出来”- L4 l5 r6 o. F' c  V
这话还是有点不明白
% ?# V7 w* x2 u. t子函数1 我定义块A  里面放个梯形
% ?) O$ M. Z% C9 y子函数2 再定义块B 里面放个矩形 再插入块A
; \, s3 @- A3 A' P) e3 |8 u3 k图形空间中我会反复调用A B# n. U. z# |/ u$ d
画图能画 VBA B插入A 不明白  9 X, I0 i1 I% [
新手 望指导下
发表于 2017-4-21 22:12:40 | 显示全部楼层 来自: 中国黑龙江佳木斯
插入块好像挺难的
发表回复
您需要登录后才可以回帖 登录 | 注册

本版积分规则


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

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

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