QQ登录

只需一步,快速开始

登录 | 注册 | 找回密码

三维网

 找回密码
 注册

QQ登录

只需一步,快速开始

展开

通知     

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

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

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

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

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

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

spline.dwg

172.45 KB, 下载次数: 8

发表于 2011-7-30 02:53:11 | 显示全部楼层 来自: 中国辽宁
本帖最后由 woaishuijia 于 2011-8-4 09:43 编辑
6 y! ~% `2 a3 W, U  n- ]" X

  1. ) p& X' W# R' s% U
  2. (defun c:aaa (/ ss ft fd c1 c2 i j dmin d)
    9 _) [$ z. U; U! N8 r! S" b/ `( u
  3.   (vl-load-com)    ;将 Visual LISP 扩展功能加载到 AutoLISP 8 n, `+ ?8 Y0 ]$ r" D5 L! [4 H
  4.   (setq     ;将一个或多个符号的值设置为相应表达式的值$ |& o* b; {$ y, m* b( B
  5.     ss (vla-add    ;用 vla- 前缀函数调用 activeX 对象(下面的代码--该方法的第一个参数--指定的选择集集合对象)的 add 方法) y% x5 n) R' d2 V; H
  6.   (vla-get-selectionsets  ;用 vla-get- 前缀函数获取 activeX 对象--当前文档对象--的属性:选择集集合子对象,即使用 add 方法的集合对象
    $ a8 z  C6 ^* D7 y" r7 g
  7.     (vla-get-activedocument ;用 vla-get- 前缀函数获取 activeX 对象--当前 AutoCAD 应用程序对象--的属性:活动文档子对象1 ^  q1 n% ?4 e8 R
  8.       (vlax-get-acad-object) ;用 vlax-get-acad-object 函数检索当前 AutoCAD 任务中的顶层 AutoCAD 应用程序对象5 l0 L# v" g: T" R1 ^
  9.     )3 k7 @% G  c. I! x
  10.   )
    " c- I- w7 P1 F
  11.   "ss"    ;选择集名称" E7 z7 x+ p9 z! _+ T
  12.        )
    3 z, K& Y8 k! d1 o7 [2 u2 N0 ~
  13.     ft (vlax-make-safearray vlax-vbinteger '(0 . 0))! ]' J" ?  F; J  Q
  14.      ;定义选择集过滤器的过滤类型数组.用 vlax-make-safearray 函数创建安全数组,整形,一维,一个元素(0 to 0).
    3 K& i8 T1 L# J6 I$ I2 N
  15.     fd (vlax-make-safearray vlax-vbvariant '(0 . 0))
    / ?* H% c$ }: h
  16.      ;定义选择集过滤器的过滤值数组.用 vlax-make-safearray 函数创建安全数组,变体,一维,一个元素(0 to 0).
    ( X& @: r- u; E- G; q( j
  17.   )2 L, C5 v! T; J4 _0 ~$ v% K
  18.   (vlax-safearray-put-element fd 0 "spline" )" O4 J* x, \+ k  `( f( ]0 {8 l
  19.      ;用 vlax-safearray-put-element 函数为数组 fd 的第一个元素(索引号 0)赋值"spline"
    . y4 }/ s. n9 y9 _' v
  20.   (vla-selectonscreen ss ft fd)  ;用 vla- 前缀函数调用 ss 对象的 selectonscreen 方法,由用户在屏幕上选取样条曲线对象2 M6 ^5 ?3 E" _, h, y1 J* n6 q
  21.   (if (= (vla-get-count ss) 2)  ;如果 ss 集合的 count 属性等于2(即用户选择了两条曲线)则执行下面的代码
    ' U5 j  n6 U5 S: u0 D% d
  22.     (progn" C4 n+ f! @+ J
  23.       (setq c1 (vla-get-controlpoints ;用 vla-get- 前缀函数获取样条曲线对象的控制点坐标数组并赋值给c1(变量类型为变体,值为双精度数组)
    " c' x! t6 l2 t2 j) {0 R) F/ G
  24.    (vla-item ss 0) ;用 vla- 前缀函数调用集合对象的 item 方法,获取选择集中的索引号为 0 的样条曲线对象
    % B/ l0 \8 V! E$ y2 D  D' P
  25.         )7 v! u8 q, f  [1 l' P: F9 a
  26.      c2 (vla-get-controlpoints ;用 vla-get- 前缀函数获取样条曲线对象的控制点坐标数组并赋值给c2(变量类型为变体,值为双精度数组)# {- T0 ~) b/ M' e. L, J
  27.    (vla-item ss 1) ;用 vla- 前缀函数调用集合对象的 item 方法,获取选择集中的索引号为 1 的样条曲线对象
    1 P7 C  S3 R" c$ H. [: W( H0 c) t
  28.         )
    ; W/ |9 {. Z- J; @! K9 H
  29.      i  0   ;初始化外层循环变量
    ; C8 [% d, D0 K+ A- _, v
  30.       )
    $ ^1 I3 x. i3 x- b9 y
  31.       (repeat    ;循环,外层
    % o5 t! m7 B7 [/ k8 f
  32. (/ (1+ (vlax-safearray-get-u-bound
    3 F3 x8 }. [3 e* O' T# V2 r
  33.      ;用 vlax-safearray-get-u-bound 函数获取数组最大下标.第一个参数是数组,第二个参数是维数
    3 V% p" s$ p$ n; [
  34.    (vlax-variant-value c1);用 vlax-variant-value 函数获取变体变量 c1 的值(双精度数组)
    8 Q# `- ?5 a3 O- q
  35.    1, D/ I, A. F8 ~
  36.         )! @; p. d* y/ o4 X) q( Z2 }
  37.     )
    ! h! n4 A* s! _$ F. e
  38.     3' L" t" I( F9 f+ o" P- C
  39. )    ;用数组最大下标加1再除以3,所得结果做为循环次数--数组中每三个元素为一组代表一个控制点  k6 F+ P, M0 g3 F- K5 L8 C* c
  40.   (setq j 0)   ;初始化内层循环变量5 R  w- X# [8 L, i2 j# g
  41.   (repeat0 }9 x) u6 k! c% H; v$ I0 G$ g# U
  42.     (/ (1+ (vlax-safearray-get-u-bound6 R- Z, j" y8 e5 s  C9 L
  43.      ;第二条样条曲线控制点坐标数组的最大下标加1再除以3,做为内层循环次数4 ]% h; Y2 Y1 [# T( F1 z/ p& c( k
  44.       (vlax-variant-value c2)
    . J$ w- E/ G1 n0 E6 j6 B7 ]9 ]
  45.       11 }+ `+ x, A9 O5 {( @& x* h) A
  46.     )
    # h' ?/ ^7 L; i( J
  47.        )& t  _" n7 T, V. ?$ j1 a5 H
  48.        3# c7 `# G1 H9 |7 h& q& o  S! c3 i
  49.     )
    0 [+ Y& f; m2 E4 ^% ~/ X# w. C
  50.      (setq d (distance  ;计算第一条曲线索引号为 i 的控制点到第二条曲线索引号为 j 的控制点之间的三维距离$ |" |0 {2 i9 E1 a- V
  51.         (list  ;从 c1 数组中取出第一条曲线索引号为 i 的控制点的点表
    : P& N$ ^/ J, ~% P+ G* k
  52.    (vlax-safearray-get-element, W4 m3 E6 W# y: g) _) M8 e
  53.      ;用 vlax-safearray-get-element 函数获取数组中的指定的元素
    * W: e% P! T2 j. V! P7 r
  54.      (vlax-variant-value c1) ;数组. N' [" `0 ?1 D, ?) c8 \6 N9 p' T
  55.      (* i 3) ;数组元素下标
      K4 l* m! f' C2 }% \
  56.    )
    * x5 X" \- p1 ?5 [/ q- y
  57.    (vlax-safearray-get-element
    7 f: T9 Y& N& g* \
  58.      (vlax-variant-value c1)' {7 X4 F8 N/ p# J  G+ z
  59.      (+ (* i 3) 1)
      C6 P  i5 c* m" T. O3 o# Q7 g
  60.    )/ U! B' p5 ?+ Z7 C2 `
  61.    (vlax-safearray-get-element
    : I# Q* h, W; I  m* |
  62.      (vlax-variant-value c1)
    ( Q, u5 V" ^1 V, G9 z9 P
  63.      (+ (* i 3) 2)1 {6 {+ c  `- x( y5 h: }  {
  64.    )  l) f1 |% K+ D' N
  65.         )" S) \; {2 B$ ]3 _0 i3 ?
  66.         (list  ;从 c2 数组中取出第二条曲线索引号为 j 的控制点的点表3 Z% u' G! i$ q3 W
  67.    (vlax-safearray-get-element
    * J( y! p0 L& o1 i" U  v, n% Z9 e- ?
  68.      (vlax-variant-value c2)
    2 D. q+ r( O# a
  69.      (* j 3)
    : |) Y3 E6 `( n, j9 D0 S4 e" T
  70.    )
    1 q' ^! H) N; Y
  71.    (vlax-safearray-get-element
    ) K6 C, o% Y8 B8 K5 Z9 L6 O7 E' M
  72.      (vlax-variant-value c2)1 ^% p8 W2 Q7 l
  73.      (+ (* j 3) 1)
    ) J9 t6 ~4 i5 e' Q, Q" D( S" D3 q
  74.    )
    4 x. f5 K5 H/ D0 F2 X& T
  75.    (vlax-safearray-get-element
    : _+ O0 b* l2 b( i- K
  76.      (vlax-variant-value c2)* |4 e$ I7 ^8 u+ k# p
  77.      (+ (* j 3) 2)% _  E4 {8 y! @6 R4 L
  78.    )
    # A" U) g  d( N" h
  79.         ). P3 q" f. Y& U: g( ?8 e' J! z
  80.       )
    / E  E% ?; F+ g0 L% z3 C
  81.      )
    # Y# c$ K* r/ u2 E! q. h
  82.      (if dmin   ;检查最小距离是否为 nil (是否首次)7 y* b! O- `) R! E
  83.        (if (> dmin d)  ;不是首次,比较计算所得的距离与已保存的最小距离,如发现更小的距离则保存2 ?0 T' V: d# M5 L5 G  C
  84.   (setq dmin d)- u# n) s2 {4 w* T5 X' l
  85.        )
    ! n1 P' C2 D8 Y2 z! |% e$ {
  86.        (setq dmin d)  ;首次,把首个距离记录为最小距离
    + x6 _' y$ L, _! ^5 T$ r
  87.      )
    ' U+ r  E7 ?3 ?% e
  88.      (setq j (1+ j))  ;内层循环变量递增3 E" v' p& T& X$ s) G4 G
  89.   )
    2 W# |1 w9 `  B
  90.   (setq i (1+ i))  ;外层循环变量递增) P6 {! L7 k7 u* [+ c0 z4 m
  91.       )
    6 Z7 w  U/ b- d2 _
  92.     )3 F' o  U: W3 x% z+ i
  93.   )
    1 J6 c& Z/ G& F) Q
  94.   (vla-delete ss)   ;用 vla- 前缀函数调用 ss 集合的 delete 方法,删除用过的选择集: X/ f* ~7 l" G5 r1 h0 ?' M( H
  95.   (princ dmin)    ;命令行输出计算结果
    6 o4 s6 m- ?( X) o
  96.   (princ)    ;静默退出. D+ ?9 O) Z3 d6 _: M, A
  97. )
    ' T4 l! i' P7 K
复制代码
发表于 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 )

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