QQ登录

只需一步,快速开始

登录 | 注册 | 找回密码

三维网

 找回密码
 注册

QQ登录

只需一步,快速开始

展开

通知     

查看: 4605|回复: 4
收起左侧

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

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

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

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

x
本帖最后由 tataki 于 2011-7-30 07:13 编辑
2 k7 m9 B; n6 j2 p. B( r
$ @8 R) j9 L+ d  X各位好,最近遇到一个问题,在cad中做了两个闭合的三维spline,我是想算一算他们两者最近的距离是多少,当然不用负责的公式就算,就想着用最直观,也是很简单的方法来计算。见附图。
. G& |9 U1 O- O- G$ z: N我的想法是在红色spline上将这条曲线上的每个点计算到蓝色曲线上的每个点距离,也就是一个二次循环,最后找出最小值就行。然而在操作中遇到了两个问题:
" Q; y% v0 C8 P1.在spline的图元了保存的控制点坐标怎么提取出来?以前只提过其中的一项,现在面对这几百个数据不知道该怎么提取了。% _0 b/ @  G: b2 B8 D7 C* [1 a. Y+ [
2.提取的数据怎么存放呢?我以前是学c++的,在C里面肯定用个数组循环就行了,但是不怎么会lisp,在lisp里面没有数组的概念,因此怎么存大量数据,还有后期的怎么读取都让我很迷惑,请各位懂得朋友帮个忙。在网上也找到了几个提spline坐标的程序,可是里面使用vl那些命令,这个我不知道怎么用,也没法修改成我想要的,哪位高手能帮下我,非常感谢!
0 c3 I  P2 g! {5 t; \0 l现附上 这两条曲线的dwg文件。
7 x8 o$ P& o' q8 o' ] 2011-7-29 19-17-21.jpg ; O) E, a8 v6 n. d  o3 W; X2 k

' w) p. s3 q3 H6 I( J7 w今早一打开我的帖子,就看到斑竹的答复!很激动,没想到这么快就回复了!  I* Z! i" A& }6 g- X
非常感谢斑竹的帮助!不但给出了源代码,还有详细的注解,斑竹的认真热心和负责让我肃然起敬,以前的我提的几个问题也是斑竹给解决的。刚
看了一下发帖时间,半夜02:53....看到这个时间,明白人心理都懂得,再多赞美的词也显得苍白了....
  Q1 t2 }$ L) Y9 k% `辛苦斑竹了,今天周末请多休息!

spline.dwg

172.45 KB, 下载次数: 8

发表于 2011-7-30 02:53:11 | 显示全部楼层 来自: 中国辽宁
本帖最后由 woaishuijia 于 2011-8-4 09:43 编辑 9 ]) e" D8 ~3 k+ t2 H- X
  1. - @" O. d# V1 F* @1 @4 j* a
  2. (defun c:aaa (/ ss ft fd c1 c2 i j dmin d)
    $ p0 _4 H' |) h
  3.   (vl-load-com)    ;将 Visual LISP 扩展功能加载到 AutoLISP
    1 ]+ |8 F" n. i6 T' R- C
  4.   (setq     ;将一个或多个符号的值设置为相应表达式的值% o% H9 |) v$ d5 n3 T
  5.     ss (vla-add    ;用 vla- 前缀函数调用 activeX 对象(下面的代码--该方法的第一个参数--指定的选择集集合对象)的 add 方法, K& u; x! G+ |9 j
  6.   (vla-get-selectionsets  ;用 vla-get- 前缀函数获取 activeX 对象--当前文档对象--的属性:选择集集合子对象,即使用 add 方法的集合对象% r% \  ^; l) a
  7.     (vla-get-activedocument ;用 vla-get- 前缀函数获取 activeX 对象--当前 AutoCAD 应用程序对象--的属性:活动文档子对象
      d. ?2 U% u) F+ f" n) Q) {
  8.       (vlax-get-acad-object) ;用 vlax-get-acad-object 函数检索当前 AutoCAD 任务中的顶层 AutoCAD 应用程序对象
    0 D' \* c4 q" s# L9 s# m
  9.     )
    : {3 f  q: R, E, o' ?4 u
  10.   )7 f* f* m2 {9 W" P
  11.   "ss"    ;选择集名称% }/ g/ Y2 k7 S: W, p4 [& ^2 u5 `& s
  12.        )
      f/ h( q8 _3 k. _9 i$ o* f
  13.     ft (vlax-make-safearray vlax-vbinteger '(0 . 0))
    7 E# R4 ]9 R- n+ s
  14.      ;定义选择集过滤器的过滤类型数组.用 vlax-make-safearray 函数创建安全数组,整形,一维,一个元素(0 to 0).$ I. I, ^8 y& r. T
  15.     fd (vlax-make-safearray vlax-vbvariant '(0 . 0))5 z- M0 Z9 K5 e$ W& G$ t+ p+ ~
  16.      ;定义选择集过滤器的过滤值数组.用 vlax-make-safearray 函数创建安全数组,变体,一维,一个元素(0 to 0).5 y6 m( m8 u- e, w0 j" s9 \
  17.   )
    ; E' i; a. S6 K0 G% N( w& t
  18.   (vlax-safearray-put-element fd 0 "spline" )# B! ?* S) h% o" b" e
  19.      ;用 vlax-safearray-put-element 函数为数组 fd 的第一个元素(索引号 0)赋值"spline"1 |: l+ [) z' M+ \$ a% }
  20.   (vla-selectonscreen ss ft fd)  ;用 vla- 前缀函数调用 ss 对象的 selectonscreen 方法,由用户在屏幕上选取样条曲线对象
      w, Q7 ^1 v4 h9 Q+ ~/ M8 [3 ^" J% U
  21.   (if (= (vla-get-count ss) 2)  ;如果 ss 集合的 count 属性等于2(即用户选择了两条曲线)则执行下面的代码3 }4 b2 J5 x$ A' {$ n1 D
  22.     (progn$ H- N6 G0 M  E; f2 d2 m/ p
  23.       (setq c1 (vla-get-controlpoints ;用 vla-get- 前缀函数获取样条曲线对象的控制点坐标数组并赋值给c1(变量类型为变体,值为双精度数组)
    ; _* N' W7 @+ n3 v% @& {
  24.    (vla-item ss 0) ;用 vla- 前缀函数调用集合对象的 item 方法,获取选择集中的索引号为 0 的样条曲线对象' Q1 F2 X! B4 k- }7 E- m
  25.         )
    * ~% T  D+ v/ v  A6 i
  26.      c2 (vla-get-controlpoints ;用 vla-get- 前缀函数获取样条曲线对象的控制点坐标数组并赋值给c2(变量类型为变体,值为双精度数组)3 h" }/ b9 X/ {) _5 V1 v1 W! P
  27.    (vla-item ss 1) ;用 vla- 前缀函数调用集合对象的 item 方法,获取选择集中的索引号为 1 的样条曲线对象& A7 L9 i) H  |- [/ M* x' _7 W
  28.         )
    ' v2 h) `3 ^$ z" |' I2 w8 ~: C  ]
  29.      i  0   ;初始化外层循环变量0 I4 }1 l9 g: ^$ S; B+ P! M( S
  30.       )
    4 X0 E) E  L9 \( K( |+ J1 V2 @
  31.       (repeat    ;循环,外层
    / J  ^7 L) W9 i" ^& a5 I. q
  32. (/ (1+ (vlax-safearray-get-u-bound& h3 ~( S$ [/ |: C1 _/ a" e* E
  33.      ;用 vlax-safearray-get-u-bound 函数获取数组最大下标.第一个参数是数组,第二个参数是维数
    - a2 q" H* O2 P" F! @, U7 R6 g
  34.    (vlax-variant-value c1);用 vlax-variant-value 函数获取变体变量 c1 的值(双精度数组): I0 f  V2 k0 M) P5 ?
  35.    1
    ! D. G# O( N% k& X  b
  36.         )0 n! x# A9 [8 b8 Q0 `
  37.     )% f/ s  h* J8 u9 G8 r
  38.     35 u  ^8 D# U7 I* o# ?# U5 N% ?3 U7 X
  39. )    ;用数组最大下标加1再除以3,所得结果做为循环次数--数组中每三个元素为一组代表一个控制点
    9 I# _8 r# [* T
  40.   (setq j 0)   ;初始化内层循环变量$ f' n1 }' T/ a' ?% V& E+ H4 D+ I5 ^
  41.   (repeat: l& a1 I) M; D; c  G* L+ z. x
  42.     (/ (1+ (vlax-safearray-get-u-bound2 G( s  v# i& [' {1 [3 R2 [3 g
  43.      ;第二条样条曲线控制点坐标数组的最大下标加1再除以3,做为内层循环次数
    # t# U' I  o- ?& W* Q8 p- ?% N: ?
  44.       (vlax-variant-value c2)
    7 D" R) Q/ C$ a& U1 j2 R
  45.       16 Z- v6 H5 g6 p6 V1 S4 o! B
  46.     )/ |; g0 h4 y3 ]/ u7 I1 {; g
  47.        )
    5 @2 ]9 m% O$ O$ w# ?
  48.        3
    & @7 `! _; a& R1 x5 k/ c* L$ y0 t
  49.     )
    " n. D6 ]% D# U& B4 w5 [7 j
  50.      (setq d (distance  ;计算第一条曲线索引号为 i 的控制点到第二条曲线索引号为 j 的控制点之间的三维距离
    ( U6 \1 p4 ]: ?3 l+ C  `( K
  51.         (list  ;从 c1 数组中取出第一条曲线索引号为 i 的控制点的点表1 Q. L& V, ^8 |6 e" S0 D
  52.    (vlax-safearray-get-element+ i. o4 e* U1 ]& r
  53.      ;用 vlax-safearray-get-element 函数获取数组中的指定的元素
    * v' F1 K8 v9 M/ \; D9 p
  54.      (vlax-variant-value c1) ;数组( x3 N9 R! h! }' _, S
  55.      (* i 3) ;数组元素下标$ B3 b, S) n) V/ q- F
  56.    )" _' G  g" d4 [& _
  57.    (vlax-safearray-get-element
    $ f2 [/ ^$ T& a! n
  58.      (vlax-variant-value c1)
    ! s3 [3 X4 |2 ^7 i6 [( V# L' b
  59.      (+ (* i 3) 1)" e8 _- E: @! j4 Q$ @0 P
  60.    )
    8 R  P+ p. ^3 |+ n
  61.    (vlax-safearray-get-element
      L8 o: K' t5 M" Z9 ~! ~# C
  62.      (vlax-variant-value c1)
    , K! R: d+ v7 G/ q4 h3 x* l
  63.      (+ (* i 3) 2)
    # m9 |2 H7 l0 {" v' i" U% i! f
  64.    )+ J& ]' [* `3 G* }0 _0 C4 L% [
  65.         ). c! B+ \5 C( _
  66.         (list  ;从 c2 数组中取出第二条曲线索引号为 j 的控制点的点表7 M% H8 `9 h' r, N* b; U7 K2 A
  67.    (vlax-safearray-get-element# C: T* l. R5 v& s+ q
  68.      (vlax-variant-value c2)
    % V2 i( t8 X( D) e
  69.      (* j 3)
    % ], o, B+ N% J
  70.    )
    8 f( e: n& K5 I. s# Y
  71.    (vlax-safearray-get-element
    + e3 \6 l: o) Z) T1 G/ G( {
  72.      (vlax-variant-value c2)
      g0 a. t7 O8 @" t% D" Z! e
  73.      (+ (* j 3) 1)
    " ^  q, c$ h% z
  74.    )/ T! I7 b/ N3 s
  75.    (vlax-safearray-get-element+ l( ^# o* {- Z% U0 T
  76.      (vlax-variant-value c2)
    , E2 P; u9 P; @9 B3 {3 V; z7 N
  77.      (+ (* j 3) 2)
    " ^6 L8 p% H$ y( A6 x# l
  78.    )
    9 ]$ T; o5 H% Y- W. D5 u+ L5 T5 o
  79.         )
    & ?* a" n  [% n9 Q
  80.       )
    ) \* f+ \6 g  u% r
  81.      )/ ?; o$ V6 d" I) r2 N; L! Q
  82.      (if dmin   ;检查最小距离是否为 nil (是否首次)' M3 l) y; N, z" D/ S. Y  o
  83.        (if (> dmin d)  ;不是首次,比较计算所得的距离与已保存的最小距离,如发现更小的距离则保存2 \% Y  e) B) E2 v) A( }5 O
  84.   (setq dmin d)
    + J8 v* R, X: q- M# ~2 u
  85.        ). D3 c- ~% Q% W8 d
  86.        (setq dmin d)  ;首次,把首个距离记录为最小距离
    & ?7 U8 x$ u* w; y
  87.      )
    + R4 c" Y1 x" o
  88.      (setq j (1+ j))  ;内层循环变量递增7 V& E" _& G- K. v% {
  89.   )
    ; H; }& N9 w' a! ~" v( U" O
  90.   (setq i (1+ i))  ;外层循环变量递增
    & v. _( D: s2 Y
  91.       )
    : i# {) {- d7 Y# y9 G4 I
  92.     )6 w6 V* n* x$ j( R) d% N7 f
  93.   )' B  r0 B6 F! {: A# J5 Q5 W
  94.   (vla-delete ss)   ;用 vla- 前缀函数调用 ss 集合的 delete 方法,删除用过的选择集1 ], d4 G  e6 W3 c0 l+ @4 }8 P- j4 Z
  95.   (princ dmin)    ;命令行输出计算结果9 u' t/ V; K; p- ~# T5 m$ d
  96.   (princ)    ;静默退出) F! K( A" v! U
  97. )8 w& n' f$ a' s  m) ~' U
复制代码
发表于 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 )

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