QQ登录

只需一步,快速开始

登录 | 注册 | 找回密码

三维网

 找回密码
 注册

QQ登录

只需一步,快速开始

展开

通知     

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

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

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

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

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

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

spline.dwg

172.45 KB, 下载次数: 8

发表于 2011-7-30 02:53:11 | 显示全部楼层 来自: 中国辽宁
本帖最后由 woaishuijia 于 2011-8-4 09:43 编辑
/ K- n9 S9 o8 x3 \6 G& J
  1. ' z! l9 |  m$ C0 [
  2. (defun c:aaa (/ ss ft fd c1 c2 i j dmin d)
    2 F1 I, m& {4 G' \& [  x
  3.   (vl-load-com)    ;将 Visual LISP 扩展功能加载到 AutoLISP
    - {0 k# W4 R# d) v. `' H3 \
  4.   (setq     ;将一个或多个符号的值设置为相应表达式的值8 L2 R- w2 u/ k. n# |. S
  5.     ss (vla-add    ;用 vla- 前缀函数调用 activeX 对象(下面的代码--该方法的第一个参数--指定的选择集集合对象)的 add 方法
    4 U, b$ |  B# {" K! Y
  6.   (vla-get-selectionsets  ;用 vla-get- 前缀函数获取 activeX 对象--当前文档对象--的属性:选择集集合子对象,即使用 add 方法的集合对象7 P' u* m4 r# f
  7.     (vla-get-activedocument ;用 vla-get- 前缀函数获取 activeX 对象--当前 AutoCAD 应用程序对象--的属性:活动文档子对象% ^4 s# J; E2 |7 u
  8.       (vlax-get-acad-object) ;用 vlax-get-acad-object 函数检索当前 AutoCAD 任务中的顶层 AutoCAD 应用程序对象- P, j/ g9 ~# x3 H2 |, E. \
  9.     )
    . Z" `- O  t! J. P
  10.   )
    . q$ M( X9 f" \! ?* E$ x* ]( G
  11.   "ss"    ;选择集名称! ^' o0 \0 _6 u; u( N
  12.        )) g1 ?* P- ^% f% [8 q, ]* v6 @
  13.     ft (vlax-make-safearray vlax-vbinteger '(0 . 0))
    2 o" W& c1 h2 M+ a# T0 P
  14.      ;定义选择集过滤器的过滤类型数组.用 vlax-make-safearray 函数创建安全数组,整形,一维,一个元素(0 to 0).1 W6 [, ~" `+ }6 w( X2 Y
  15.     fd (vlax-make-safearray vlax-vbvariant '(0 . 0))& I% e: _4 w! }/ ^: ~
  16.      ;定义选择集过滤器的过滤值数组.用 vlax-make-safearray 函数创建安全数组,变体,一维,一个元素(0 to 0).
    7 x' G6 b3 U/ Y% @. c/ d* b1 _
  17.   )
    ' I8 k+ q+ R0 J7 I
  18.   (vlax-safearray-put-element fd 0 "spline" )
    0 |. P  M. _  P2 A0 v7 F! E: b
  19.      ;用 vlax-safearray-put-element 函数为数组 fd 的第一个元素(索引号 0)赋值"spline"
    : K$ a$ g: C1 L: g  b  s2 e/ a% \
  20.   (vla-selectonscreen ss ft fd)  ;用 vla- 前缀函数调用 ss 对象的 selectonscreen 方法,由用户在屏幕上选取样条曲线对象) H0 M5 @, u# G' L- f
  21.   (if (= (vla-get-count ss) 2)  ;如果 ss 集合的 count 属性等于2(即用户选择了两条曲线)则执行下面的代码
    # E. a& z5 N; q- z+ v
  22.     (progn
    4 J8 |7 \. b/ g: w; S7 t
  23.       (setq c1 (vla-get-controlpoints ;用 vla-get- 前缀函数获取样条曲线对象的控制点坐标数组并赋值给c1(变量类型为变体,值为双精度数组)
    " o6 L) |" l( {( f5 U3 W
  24.    (vla-item ss 0) ;用 vla- 前缀函数调用集合对象的 item 方法,获取选择集中的索引号为 0 的样条曲线对象
    0 [% O3 u5 M! k
  25.         )8 a. }+ \$ i6 s" a
  26.      c2 (vla-get-controlpoints ;用 vla-get- 前缀函数获取样条曲线对象的控制点坐标数组并赋值给c2(变量类型为变体,值为双精度数组)6 J3 j3 h' A9 o; S! z9 D
  27.    (vla-item ss 1) ;用 vla- 前缀函数调用集合对象的 item 方法,获取选择集中的索引号为 1 的样条曲线对象9 w1 I1 T' U7 B- p1 g6 i7 K
  28.         )
    ! S' z  u% k# B$ \2 a4 Q
  29.      i  0   ;初始化外层循环变量6 G( R, ]) T$ p& n: H7 Q- G0 a
  30.       )
    : c" m% M. _& Y! z/ `* t) |! J
  31.       (repeat    ;循环,外层
    # [& ~  U2 h/ D0 t3 z4 t/ d. J% W. |
  32. (/ (1+ (vlax-safearray-get-u-bound
    2 {+ X" c* [; w/ l# N& N
  33.      ;用 vlax-safearray-get-u-bound 函数获取数组最大下标.第一个参数是数组,第二个参数是维数, R/ m' _0 V; w) q0 l
  34.    (vlax-variant-value c1);用 vlax-variant-value 函数获取变体变量 c1 的值(双精度数组)
    5 m  k/ T6 y. Q' s8 P
  35.    1
    $ o" X" h/ C' ]  s% l
  36.         )
    4 d2 Z2 \2 H7 ~) m& X
  37.     ). W  f# t, D" ^2 W) F$ ]
  38.     3
    % z: @5 |/ `+ d) P2 @+ V
  39. )    ;用数组最大下标加1再除以3,所得结果做为循环次数--数组中每三个元素为一组代表一个控制点8 u* I6 g4 A2 C) \
  40.   (setq j 0)   ;初始化内层循环变量
    ! l0 Y+ B$ K+ {8 E3 }5 W
  41.   (repeat. A$ B& t+ l/ M' w
  42.     (/ (1+ (vlax-safearray-get-u-bound
    - A% i, D2 {. U
  43.      ;第二条样条曲线控制点坐标数组的最大下标加1再除以3,做为内层循环次数
    # T! @7 r; S5 V( B1 {
  44.       (vlax-variant-value c2)3 F8 K: t, l9 C' ~+ R% \5 P3 K; @/ b
  45.       17 w2 f0 |$ _# H3 H8 p! F
  46.     )4 P7 R9 P1 S, v
  47.        )
      T0 b5 A; M7 _8 }9 Q" y
  48.        3' c+ D5 e; i7 k% E/ u
  49.     )" L$ B. y$ r' A
  50.      (setq d (distance  ;计算第一条曲线索引号为 i 的控制点到第二条曲线索引号为 j 的控制点之间的三维距离$ j1 O' M0 q% ]
  51.         (list  ;从 c1 数组中取出第一条曲线索引号为 i 的控制点的点表
      \5 s+ o9 h* G+ U
  52.    (vlax-safearray-get-element
    0 i! K# H8 w6 W6 m3 I
  53.      ;用 vlax-safearray-get-element 函数获取数组中的指定的元素
    # x% V5 q4 O6 X/ ]- b
  54.      (vlax-variant-value c1) ;数组# b0 R; O" _9 I6 `+ R1 j( z# G
  55.      (* i 3) ;数组元素下标
    * r% G4 m3 ~. y/ K/ u
  56.    )% c( M+ x& ]; Q- j' C
  57.    (vlax-safearray-get-element
    ( p" C# U7 ?* S% g: {
  58.      (vlax-variant-value c1)
    7 |. ?% e( S$ N3 i! N
  59.      (+ (* i 3) 1)* S- N* Z  N) S/ r
  60.    )8 i2 Y6 ~  c$ Q/ I1 m; d' D) R/ R
  61.    (vlax-safearray-get-element' `( V" G& K. }9 c) f2 r, o6 W
  62.      (vlax-variant-value c1)% ^- @+ a  y  X/ s+ h( x. M
  63.      (+ (* i 3) 2)7 N+ K# @5 K5 x
  64.    )3 F. H* g( Q) X! m
  65.         )# `: P8 A8 {$ Y: c
  66.         (list  ;从 c2 数组中取出第二条曲线索引号为 j 的控制点的点表
    $ W/ u  s3 ~& A& C# G# w
  67.    (vlax-safearray-get-element5 M( Z9 k9 ^& ?4 B+ G  o
  68.      (vlax-variant-value c2)
    # [, r; W4 D5 Q  i, u
  69.      (* j 3)
    & R! W1 i5 d& f3 Y) t7 l  c
  70.    )
    # V/ |1 P" F% O0 `5 E
  71.    (vlax-safearray-get-element
    ) Z+ Q* S' b- I0 e
  72.      (vlax-variant-value c2)
    # j0 u2 I/ x. S1 [6 x4 `* T
  73.      (+ (* j 3) 1)
    " F6 K/ D) x8 Y; q% Z$ v$ ]: ?
  74.    )0 ~; H8 g- Y+ i4 S
  75.    (vlax-safearray-get-element
    . k9 _" T. n/ Q3 {0 O: B
  76.      (vlax-variant-value c2)$ n. {7 x. H! P
  77.      (+ (* j 3) 2)5 Y) T: K5 q+ x7 d
  78.    )6 [' |+ n/ L; N
  79.         )* U3 r. q5 y3 x) C
  80.       )! p% r% R; G# o1 Y0 Z5 I
  81.      )2 ~4 G# l" n7 ]+ w1 i" ]3 _* Q
  82.      (if dmin   ;检查最小距离是否为 nil (是否首次)
    $ B/ B$ R. ], h- b% X9 A" t
  83.        (if (> dmin d)  ;不是首次,比较计算所得的距离与已保存的最小距离,如发现更小的距离则保存( z- b  G6 r7 L5 W% d' k( _
  84.   (setq dmin d): v% O5 J: g" @; {, `9 _# H  I
  85.        )
      k1 {3 M/ _. S0 a8 g1 V% M
  86.        (setq dmin d)  ;首次,把首个距离记录为最小距离0 ?+ i8 `6 R: \4 j: k) U) q  Y
  87.      )8 `5 C7 a* a2 \( _
  88.      (setq j (1+ j))  ;内层循环变量递增# z% A% i# e/ Q" L3 T1 m5 d9 \( V
  89.   )1 C( B2 U: Q5 ~
  90.   (setq i (1+ i))  ;外层循环变量递增$ a% G  F6 A$ V( K+ N: C8 d% Z
  91.       ): E4 \9 B1 I2 |0 g
  92.     )
    ' n) f6 f/ }, g, q/ @# w
  93.   )& m6 d  J) t5 a
  94.   (vla-delete ss)   ;用 vla- 前缀函数调用 ss 集合的 delete 方法,删除用过的选择集8 h* g+ R5 G/ Z# q
  95.   (princ dmin)    ;命令行输出计算结果6 |2 \* P9 X6 Z9 c7 s
  96.   (princ)    ;静默退出
    5 W" f! ]) z5 i
  97. )3 q8 j8 ^8 n/ B1 X
复制代码
发表于 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 )

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