QQ登录

只需一步,快速开始

登录 | 注册 | 找回密码

三维网

 找回密码
 注册

QQ登录

只需一步,快速开始

展开

通知     

全站
10天前
查看: 4631|回复: 4
收起左侧

[已解决] 三维spline如何提取坐标?

[复制链接]
发表于 2011-7-29 20:17:21 | 显示全部楼层 |阅读模式 来自: 中国山东青岛

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

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

x
本帖最后由 tataki 于 2011-7-30 07:13 编辑
+ S* Y: W, i/ n# o& H: a: T
0 E) m. `+ Y0 W! P+ N8 B, n- V各位好,最近遇到一个问题,在cad中做了两个闭合的三维spline,我是想算一算他们两者最近的距离是多少,当然不用负责的公式就算,就想着用最直观,也是很简单的方法来计算。见附图。+ w. G& m4 V3 {0 f
我的想法是在红色spline上将这条曲线上的每个点计算到蓝色曲线上的每个点距离,也就是一个二次循环,最后找出最小值就行。然而在操作中遇到了两个问题:
" N- f) g# J0 Q% K! q  V1.在spline的图元了保存的控制点坐标怎么提取出来?以前只提过其中的一项,现在面对这几百个数据不知道该怎么提取了。
+ b* x, l: @; X( T" w2.提取的数据怎么存放呢?我以前是学c++的,在C里面肯定用个数组循环就行了,但是不怎么会lisp,在lisp里面没有数组的概念,因此怎么存大量数据,还有后期的怎么读取都让我很迷惑,请各位懂得朋友帮个忙。在网上也找到了几个提spline坐标的程序,可是里面使用vl那些命令,这个我不知道怎么用,也没法修改成我想要的,哪位高手能帮下我,非常感谢!$ A1 H4 G) p+ \
现附上 这两条曲线的dwg文件。6 g- G2 F/ N0 A9 Y  w# E1 V: }
2011-7-29 19-17-21.jpg 2 l9 O- k% r; p0 N4 {0 l

7 W) l4 `" ~+ V, @9 C今早一打开我的帖子,就看到斑竹的答复!很激动,没想到这么快就回复了!" p: x% S8 Y& t+ Y+ `$ f+ p8 P9 h
非常感谢斑竹的帮助!不但给出了源代码,还有详细的注解,斑竹的认真热心和负责让我肃然起敬,以前的我提的几个问题也是斑竹给解决的。刚
看了一下发帖时间,半夜02:53....看到这个时间,明白人心理都懂得,再多赞美的词也显得苍白了....
5 p% Y1 h9 t) v' f: r0 l# N辛苦斑竹了,今天周末请多休息!

spline.dwg

172.45 KB, 下载次数: 8

发表于 2011-7-30 02:53:11 | 显示全部楼层 来自: 中国辽宁
本帖最后由 woaishuijia 于 2011-8-4 09:43 编辑 8 x+ E$ H0 U0 R7 D& T

  1. " b! P3 _  ~9 g
  2. (defun c:aaa (/ ss ft fd c1 c2 i j dmin d)
    ( T4 W# V4 Z  d$ M, q: N8 R
  3.   (vl-load-com)    ;将 Visual LISP 扩展功能加载到 AutoLISP ' N, Q8 R5 h/ u5 u# J
  4.   (setq     ;将一个或多个符号的值设置为相应表达式的值4 O- j; A7 H6 ?2 D2 T: P; ~0 _
  5.     ss (vla-add    ;用 vla- 前缀函数调用 activeX 对象(下面的代码--该方法的第一个参数--指定的选择集集合对象)的 add 方法
    ! o- p! E% _, [9 X) A- s
  6.   (vla-get-selectionsets  ;用 vla-get- 前缀函数获取 activeX 对象--当前文档对象--的属性:选择集集合子对象,即使用 add 方法的集合对象
    0 [' U  `: k9 j  h5 [+ d
  7.     (vla-get-activedocument ;用 vla-get- 前缀函数获取 activeX 对象--当前 AutoCAD 应用程序对象--的属性:活动文档子对象
    ! b' W7 c' _6 l/ d
  8.       (vlax-get-acad-object) ;用 vlax-get-acad-object 函数检索当前 AutoCAD 任务中的顶层 AutoCAD 应用程序对象. L& a" G0 x1 }6 S- t
  9.     )5 n: y7 ^; a# {' q& \
  10.   )
    $ j! G/ P9 p9 ^5 q) ?
  11.   "ss"    ;选择集名称
    3 ]6 p& U# s& i& C9 D9 Y! J
  12.        )7 `7 |+ Q  s, v; h: N8 R+ m) b
  13.     ft (vlax-make-safearray vlax-vbinteger '(0 . 0))7 W& `( \$ u# l: M
  14.      ;定义选择集过滤器的过滤类型数组.用 vlax-make-safearray 函数创建安全数组,整形,一维,一个元素(0 to 0).
    . z. L* w' [' j* o7 ]7 E/ w9 i3 A: `0 Q
  15.     fd (vlax-make-safearray vlax-vbvariant '(0 . 0))2 S# @2 |1 ?4 c
  16.      ;定义选择集过滤器的过滤值数组.用 vlax-make-safearray 函数创建安全数组,变体,一维,一个元素(0 to 0).
    % Q( v" [/ l5 ^/ i3 j6 X" ^% u& t/ I
  17.   )' G) L6 R: L# b, g- ]
  18.   (vlax-safearray-put-element fd 0 "spline" )) V6 u3 i, L. H3 i* z" J; I
  19.      ;用 vlax-safearray-put-element 函数为数组 fd 的第一个元素(索引号 0)赋值"spline"
    4 H0 k2 J- c0 W8 l# s3 c% _
  20.   (vla-selectonscreen ss ft fd)  ;用 vla- 前缀函数调用 ss 对象的 selectonscreen 方法,由用户在屏幕上选取样条曲线对象
    . Q( G+ m: s, f* d  h) a; u
  21.   (if (= (vla-get-count ss) 2)  ;如果 ss 集合的 count 属性等于2(即用户选择了两条曲线)则执行下面的代码0 f) |0 W5 f# f) i" T
  22.     (progn
    3 r3 y& x2 S5 T/ o8 l; n
  23.       (setq c1 (vla-get-controlpoints ;用 vla-get- 前缀函数获取样条曲线对象的控制点坐标数组并赋值给c1(变量类型为变体,值为双精度数组)
    " d  L/ I: \  P. P
  24.    (vla-item ss 0) ;用 vla- 前缀函数调用集合对象的 item 方法,获取选择集中的索引号为 0 的样条曲线对象( D. _) H5 B+ L8 P
  25.         )3 J6 ^/ V+ U* u1 Z0 @; R
  26.      c2 (vla-get-controlpoints ;用 vla-get- 前缀函数获取样条曲线对象的控制点坐标数组并赋值给c2(变量类型为变体,值为双精度数组)3 v9 T! F6 Y: V' R: z
  27.    (vla-item ss 1) ;用 vla- 前缀函数调用集合对象的 item 方法,获取选择集中的索引号为 1 的样条曲线对象: z; O+ ]7 J: ^! \
  28.         )3 P  s1 a; a" T) g+ k4 W' L
  29.      i  0   ;初始化外层循环变量
    1 j$ c* H/ P) ^8 C2 d5 k' b+ i
  30.       )! f$ ~) h, d6 h8 E9 A- S8 A
  31.       (repeat    ;循环,外层9 R) ]6 g$ D, B: Z3 y/ n
  32. (/ (1+ (vlax-safearray-get-u-bound
    2 H: @3 f9 h, x4 F' [3 [& w' n$ E
  33.      ;用 vlax-safearray-get-u-bound 函数获取数组最大下标.第一个参数是数组,第二个参数是维数
    % x6 M  \8 f2 {0 s# X! s
  34.    (vlax-variant-value c1);用 vlax-variant-value 函数获取变体变量 c1 的值(双精度数组)' s- ^1 A2 W% P. q
  35.    1  g. k, ^0 ]1 q* R" d
  36.         )
    7 u0 I3 ^5 D# g6 {3 J
  37.     )
    : a5 A1 q  _3 }$ [$ Z
  38.     3
    1 }2 \6 G5 u$ m" a8 M8 o
  39. )    ;用数组最大下标加1再除以3,所得结果做为循环次数--数组中每三个元素为一组代表一个控制点
      S  c4 S& e9 y( V4 P# T7 q1 t- q4 G
  40.   (setq j 0)   ;初始化内层循环变量
    " O9 g$ Z! H" s3 F. o% ^, g; ~
  41.   (repeat. E: W' |" b8 m" k% @5 }
  42.     (/ (1+ (vlax-safearray-get-u-bound
    6 K+ \6 {1 J( j9 S. O* ?) l7 @
  43.      ;第二条样条曲线控制点坐标数组的最大下标加1再除以3,做为内层循环次数
    8 B% s/ x  I- r2 w6 O, p
  44.       (vlax-variant-value c2)8 y8 ]+ Q5 c3 r& ]# J) {/ o8 W
  45.       1
    & U8 a; i* n. _1 x4 C* s
  46.     )
    7 Y% j! z3 Z' w- |
  47.        )* V- H) y( k% j
  48.        3
    0 G' m1 @% r9 M3 J
  49.     )
    ; ^9 M; J8 e# ^7 R' U, i3 e# o: m
  50.      (setq d (distance  ;计算第一条曲线索引号为 i 的控制点到第二条曲线索引号为 j 的控制点之间的三维距离5 y7 m6 v+ b, A# B- b6 F4 \3 ?
  51.         (list  ;从 c1 数组中取出第一条曲线索引号为 i 的控制点的点表4 h3 }6 d; @2 p3 H
  52.    (vlax-safearray-get-element+ P6 u6 E6 m/ S$ n; h* e! D
  53.      ;用 vlax-safearray-get-element 函数获取数组中的指定的元素
    + H/ `  G; l& n* u) n3 m# q! v
  54.      (vlax-variant-value c1) ;数组' C& t2 y  V* ~4 b, Q4 D+ E
  55.      (* i 3) ;数组元素下标
    " [, S& n' i0 _7 k
  56.    )% W! D  n  i6 n3 p) T2 k
  57.    (vlax-safearray-get-element
      s! ~; d' b4 o8 j& Q/ Y" L
  58.      (vlax-variant-value c1)9 \& j* j  T! ^- d8 f: G" }
  59.      (+ (* i 3) 1)
    4 c# h, x0 v7 X4 Q6 I, ^
  60.    )
    + @9 ^, ^( E; n/ _
  61.    (vlax-safearray-get-element, G( I0 K9 y) l8 L: Q; m
  62.      (vlax-variant-value c1)
    % _8 q# E& i) u" [7 C  w3 i
  63.      (+ (* i 3) 2)
    , _. M5 X7 f, J) l, l
  64.    )
    ) b* y7 b; n6 |3 K& `
  65.         )9 a7 a+ a4 W( W& p- K: W
  66.         (list  ;从 c2 数组中取出第二条曲线索引号为 j 的控制点的点表, {2 a( X' W5 t: |
  67.    (vlax-safearray-get-element: w; r( X0 H/ Y  `! K9 [% y4 x3 @' f
  68.      (vlax-variant-value c2)3 e! w) j2 \# e0 ?5 O( t
  69.      (* j 3)) n' m5 u3 i6 ]2 l
  70.    )
    ( E: C# d7 J0 x# E0 i. m: u" P9 L
  71.    (vlax-safearray-get-element
    0 ~+ Z6 a7 w, S+ \
  72.      (vlax-variant-value c2)
    0 p) H3 p5 F8 a
  73.      (+ (* j 3) 1)
    1 a3 x; a' e7 T; N. I7 ?
  74.    ): {  `; F# A5 X$ t( f
  75.    (vlax-safearray-get-element# |0 V* ]2 Y4 m5 a" z& r0 \% V
  76.      (vlax-variant-value c2)# i! p8 j6 W! O. s$ S
  77.      (+ (* j 3) 2)
    / n. T8 H* |) N7 D! B) P1 c( l
  78.    )8 U: ~, U8 Z  x6 D0 k
  79.         )
    ) C) N" q) Y2 d( @) [% V6 ~
  80.       )) h( U5 a; G3 W) O# d. w9 d; u- }
  81.      )
    2 h4 k7 ^" w4 d+ \( j
  82.      (if dmin   ;检查最小距离是否为 nil (是否首次)
    & F3 L( i" w# P% z
  83.        (if (> dmin d)  ;不是首次,比较计算所得的距离与已保存的最小距离,如发现更小的距离则保存
    ; m2 _( ]* ~; J% v
  84.   (setq dmin d)
    * W( Y& E$ M: i+ G
  85.        )% K' g% Z; r) L1 Z0 E
  86.        (setq dmin d)  ;首次,把首个距离记录为最小距离9 Y& }; X0 \9 ]
  87.      )& C5 Z* M& d# ?  G9 ~0 ~
  88.      (setq j (1+ j))  ;内层循环变量递增
    1 `! u: r! f! D/ G1 F
  89.   )
    6 D' F9 \* p% u! k& l3 B
  90.   (setq i (1+ i))  ;外层循环变量递增
    . b  N9 D$ @2 d3 |8 m2 a* }
  91.       )2 e) s! C5 J5 p! z) p9 T) y3 Y
  92.     )- N9 y2 P% O" w
  93.   )- u0 e" S7 {# P0 L
  94.   (vla-delete ss)   ;用 vla- 前缀函数调用 ss 集合的 delete 方法,删除用过的选择集
    % m0 i& r8 M4 j' c
  95.   (princ dmin)    ;命令行输出计算结果
    5 s: |1 d3 W  z# P6 _8 R8 O
  96.   (princ)    ;静默退出, ]/ a0 m4 ~; a# G
  97. )" A' K; _% @8 |3 L, F
复制代码
发表于 2011-8-2 10:14:15 | 显示全部楼层 来自: 中国天津
好资料,收藏了
发表于 2011-8-30 16:58:52 | 显示全部楼层 来自: 中国台湾
感谢版主分享程序,收藏学习了!
发表于 2011-9-17 08:38:59 | 显示全部楼层 来自: 中国四川雅安
楼上好强!不过,如果自已动手,去用VBA吧,应该比LISP好用
发表回复
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

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