QQ登录

只需一步,快速开始

登录 | 注册 | 找回密码

三维网

 找回密码
 注册

QQ登录

只需一步,快速开始

展开

通知     

全站
7天前
查看: 4756|回复: 4
收起左侧

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

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

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

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

x
本帖最后由 tataki 于 2011-7-30 07:13 编辑
# {5 k9 u, i! j% b5 I" v  D
9 n9 J# }, P+ k- [1 n% }8 w$ v( R2 t各位好,最近遇到一个问题,在cad中做了两个闭合的三维spline,我是想算一算他们两者最近的距离是多少,当然不用负责的公式就算,就想着用最直观,也是很简单的方法来计算。见附图。/ ~3 I: D# l0 T9 R; z
我的想法是在红色spline上将这条曲线上的每个点计算到蓝色曲线上的每个点距离,也就是一个二次循环,最后找出最小值就行。然而在操作中遇到了两个问题:
/ f7 U! R; ?* V5 N1.在spline的图元了保存的控制点坐标怎么提取出来?以前只提过其中的一项,现在面对这几百个数据不知道该怎么提取了。; V: _4 x& @. K; m% U- Q
2.提取的数据怎么存放呢?我以前是学c++的,在C里面肯定用个数组循环就行了,但是不怎么会lisp,在lisp里面没有数组的概念,因此怎么存大量数据,还有后期的怎么读取都让我很迷惑,请各位懂得朋友帮个忙。在网上也找到了几个提spline坐标的程序,可是里面使用vl那些命令,这个我不知道怎么用,也没法修改成我想要的,哪位高手能帮下我,非常感谢!
& O1 [0 A, ^$ a" y现附上 这两条曲线的dwg文件。
1 r: \9 H7 `3 X+ L5 i! f- K, s- B 2011-7-29 19-17-21.jpg
$ R; V8 d! y6 Y8 y
# E- k" `* [  V5 l, |7 j5 \今早一打开我的帖子,就看到斑竹的答复!很激动,没想到这么快就回复了!9 I# g$ {8 o- S) ?4 e0 {
非常感谢斑竹的帮助!不但给出了源代码,还有详细的注解,斑竹的认真热心和负责让我肃然起敬,以前的我提的几个问题也是斑竹给解决的。刚
看了一下发帖时间,半夜02:53....看到这个时间,明白人心理都懂得,再多赞美的词也显得苍白了....( K! A7 e- x$ o8 D. B# a) x
辛苦斑竹了,今天周末请多休息!

spline.dwg

172.45 KB, 下载次数: 8

发表于 2011-7-30 02:53:11 | 显示全部楼层 来自: 中国辽宁
本帖最后由 woaishuijia 于 2011-8-4 09:43 编辑
- h7 l& g/ W$ ~0 U) y
  1. % }5 t, W4 Z& Y4 U$ j, W
  2. (defun c:aaa (/ ss ft fd c1 c2 i j dmin d)
    ! Y; a% X- \" j9 e! O& X( P
  3.   (vl-load-com)    ;将 Visual LISP 扩展功能加载到 AutoLISP
    ( y1 ?4 b2 d6 I  Q8 a' p
  4.   (setq     ;将一个或多个符号的值设置为相应表达式的值# W) `; r" j4 h/ j- y/ k/ Z/ T
  5.     ss (vla-add    ;用 vla- 前缀函数调用 activeX 对象(下面的代码--该方法的第一个参数--指定的选择集集合对象)的 add 方法
    ) i9 ]" r$ W! ~. p- c
  6.   (vla-get-selectionsets  ;用 vla-get- 前缀函数获取 activeX 对象--当前文档对象--的属性:选择集集合子对象,即使用 add 方法的集合对象
    * s7 ~$ C- z% Z3 b! g
  7.     (vla-get-activedocument ;用 vla-get- 前缀函数获取 activeX 对象--当前 AutoCAD 应用程序对象--的属性:活动文档子对象- A, |' _9 r* W( ^0 D1 e
  8.       (vlax-get-acad-object) ;用 vlax-get-acad-object 函数检索当前 AutoCAD 任务中的顶层 AutoCAD 应用程序对象* T% \6 N3 H5 M
  9.     )  S1 F9 X% \+ F
  10.   )
      v1 M+ p8 i# y7 C9 r
  11.   "ss"    ;选择集名称
    * z4 f* N4 w$ j2 C- F7 h
  12.        )
    , e+ m+ G6 c* ]9 r" x+ U
  13.     ft (vlax-make-safearray vlax-vbinteger '(0 . 0))
    % S7 X( x: x2 k/ h1 k# m
  14.      ;定义选择集过滤器的过滤类型数组.用 vlax-make-safearray 函数创建安全数组,整形,一维,一个元素(0 to 0).% w/ e! L  B$ [- T
  15.     fd (vlax-make-safearray vlax-vbvariant '(0 . 0))/ {5 N- j9 ^6 n# e
  16.      ;定义选择集过滤器的过滤值数组.用 vlax-make-safearray 函数创建安全数组,变体,一维,一个元素(0 to 0).4 u& N7 l: R, e& {8 r* g
  17.   )
    $ T; i8 [, K( M) S, j
  18.   (vlax-safearray-put-element fd 0 "spline" )
    - v, `! D3 |" I7 A( ?/ e2 N
  19.      ;用 vlax-safearray-put-element 函数为数组 fd 的第一个元素(索引号 0)赋值"spline"+ D' A, |0 I) w. L4 p. N
  20.   (vla-selectonscreen ss ft fd)  ;用 vla- 前缀函数调用 ss 对象的 selectonscreen 方法,由用户在屏幕上选取样条曲线对象$ v3 j& x4 e! u' [
  21.   (if (= (vla-get-count ss) 2)  ;如果 ss 集合的 count 属性等于2(即用户选择了两条曲线)则执行下面的代码
    1 x" {7 q+ C' r/ u$ e; S# W8 r& n9 G
  22.     (progn
    0 U  P% e' O4 |% Q
  23.       (setq c1 (vla-get-controlpoints ;用 vla-get- 前缀函数获取样条曲线对象的控制点坐标数组并赋值给c1(变量类型为变体,值为双精度数组)
    8 R. A! I) r, d
  24.    (vla-item ss 0) ;用 vla- 前缀函数调用集合对象的 item 方法,获取选择集中的索引号为 0 的样条曲线对象
    4 B, I; Y, B8 S% s) o% x  q
  25.         )* ]0 Y% o# K2 x5 b/ n& E, f. P
  26.      c2 (vla-get-controlpoints ;用 vla-get- 前缀函数获取样条曲线对象的控制点坐标数组并赋值给c2(变量类型为变体,值为双精度数组)
    $ y4 G! i% K0 e6 m; v3 v) t
  27.    (vla-item ss 1) ;用 vla- 前缀函数调用集合对象的 item 方法,获取选择集中的索引号为 1 的样条曲线对象9 M( E' p  B  A( p" T$ h
  28.         )
    1 _6 R- r4 G; ~9 t
  29.      i  0   ;初始化外层循环变量
    6 U9 a! L8 p& U; S  Z  m( A
  30.       )7 ~3 Q7 D6 J- m' E6 n) X
  31.       (repeat    ;循环,外层8 P4 b9 [) O8 P
  32. (/ (1+ (vlax-safearray-get-u-bound
    : T$ w1 \, S& H% g
  33.      ;用 vlax-safearray-get-u-bound 函数获取数组最大下标.第一个参数是数组,第二个参数是维数* [! D: t: R5 m- K' W
  34.    (vlax-variant-value c1);用 vlax-variant-value 函数获取变体变量 c1 的值(双精度数组)# W! m/ o) o2 d% X
  35.    1# Q$ y( h+ T# o1 X7 |, R' l5 R; ^
  36.         )" `& x" _% y2 E# U! `1 u
  37.     )  R4 a5 t# @$ x2 h0 ]  l
  38.     3
    # c: I* x5 K; b' q5 p  Z6 o
  39. )    ;用数组最大下标加1再除以3,所得结果做为循环次数--数组中每三个元素为一组代表一个控制点
    2 J5 f; _' u: q# s
  40.   (setq j 0)   ;初始化内层循环变量
    . o+ ~) x4 s7 D  B1 I
  41.   (repeat
      |7 I1 t# O- d$ w/ ?
  42.     (/ (1+ (vlax-safearray-get-u-bound
    # T6 w7 l6 K, a' S5 m$ K
  43.      ;第二条样条曲线控制点坐标数组的最大下标加1再除以3,做为内层循环次数
    + \0 b5 s& K' M
  44.       (vlax-variant-value c2)" {0 S3 f6 N% ?: `  C- q
  45.       1
    2 P, A, ]; H! E8 o
  46.     )" P0 ~) C5 V/ l0 C9 P- H
  47.        )
    ( C: m/ e) ^3 ]: r7 W& l
  48.        3. x; v4 t3 A6 t2 a: o2 l+ w
  49.     )5 W0 f  y$ |! r! x
  50.      (setq d (distance  ;计算第一条曲线索引号为 i 的控制点到第二条曲线索引号为 j 的控制点之间的三维距离
    & I! S4 u5 w& L$ S9 A
  51.         (list  ;从 c1 数组中取出第一条曲线索引号为 i 的控制点的点表4 Y: x8 z. b# C4 G* w2 o% {* f
  52.    (vlax-safearray-get-element
    . c5 T# W1 W' L; I4 l% a
  53.      ;用 vlax-safearray-get-element 函数获取数组中的指定的元素( i$ m% Y" [5 h0 y, P; J0 K: l
  54.      (vlax-variant-value c1) ;数组
    $ |. t* x/ P6 A
  55.      (* i 3) ;数组元素下标
    - j2 k5 z* e8 P+ \0 \
  56.    )/ [* F$ i' o5 n1 @0 c( c# x* X
  57.    (vlax-safearray-get-element
    - X" c9 v! g+ K" z
  58.      (vlax-variant-value c1)
    ; B9 {) u  a9 L1 _" v
  59.      (+ (* i 3) 1)* J6 L  E" z& e' p. _3 L5 X
  60.    )7 S2 H$ L+ Q  j( [" Q- N! H
  61.    (vlax-safearray-get-element
    + D0 F/ |7 V. R0 ?3 d) c2 q9 t
  62.      (vlax-variant-value c1)
    ! L/ I2 ~9 q: T- w4 _! {* O$ U
  63.      (+ (* i 3) 2)+ w6 S3 R. [) _+ _2 S  ~
  64.    )$ |6 s- \& E+ l
  65.         )
    " J( l7 y! d- m# V1 p. g/ N
  66.         (list  ;从 c2 数组中取出第二条曲线索引号为 j 的控制点的点表4 [- S) h$ e8 Q- l
  67.    (vlax-safearray-get-element- W) f/ k/ L1 O1 P
  68.      (vlax-variant-value c2)* w$ }% u: ?( Q" b
  69.      (* j 3)
    9 t4 h, V& V1 j" x
  70.    )( n7 M* u- E1 S
  71.    (vlax-safearray-get-element
    % y6 T- N+ F) F/ J7 h0 z8 D3 O( L
  72.      (vlax-variant-value c2). L4 C0 R: }0 W% e* C( u
  73.      (+ (* j 3) 1)+ m6 b6 U+ f/ z" j
  74.    )
    : W; V& T- E8 |: C3 C
  75.    (vlax-safearray-get-element
    7 Q: U( V: }! ~/ P4 U( `
  76.      (vlax-variant-value c2)
    9 A0 H6 J  G2 c. }7 i- g
  77.      (+ (* j 3) 2)
    ' @% a" }* @$ |  O: G& L; w: {
  78.    )( Y0 h% j4 D4 S& c/ q
  79.         )7 m' f! J' j4 Y. K
  80.       )4 k$ w2 A5 v' B; {8 A: H
  81.      )/ g* v3 H  O" Z( P
  82.      (if dmin   ;检查最小距离是否为 nil (是否首次); e) g% @) F. C" H1 @6 e
  83.        (if (> dmin d)  ;不是首次,比较计算所得的距离与已保存的最小距离,如发现更小的距离则保存
    ( j3 e7 h/ S) Q( @6 l
  84.   (setq dmin d). Z( t7 y7 V* ~. a3 t
  85.        )
    2 Q/ T! R% x! [1 C  L
  86.        (setq dmin d)  ;首次,把首个距离记录为最小距离. J+ @% N: b9 d  C' n5 q. C
  87.      )
    ) [$ N5 _- n; M4 }( I; t
  88.      (setq j (1+ j))  ;内层循环变量递增5 d9 c/ b1 u1 Y
  89.   )
    ( J- l) n! j( e' g! I7 \- C
  90.   (setq i (1+ i))  ;外层循环变量递增
    0 c, o) g2 m# Z6 J" o! t/ A
  91.       )7 y. d0 [5 Z0 A  R
  92.     )
    $ b2 W' j  D% z$ |
  93.   )2 L9 m. L! _# e/ e& V
  94.   (vla-delete ss)   ;用 vla- 前缀函数调用 ss 集合的 delete 方法,删除用过的选择集2 x  q" Z# a4 l# M2 n- r+ p
  95.   (princ dmin)    ;命令行输出计算结果
    6 c& E- A( Q! y' T# d+ H
  96.   (princ)    ;静默退出$ Z2 K5 G+ {3 D- G+ b: o- c
  97. )) L# ~/ H! @+ R
复制代码
发表于 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 )

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