QQ登录

只需一步,快速开始

登录 | 注册 | 找回密码

三维网

 找回密码
 注册

QQ登录

只需一步,快速开始

展开

通知     

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

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

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

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

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

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

spline.dwg

172.45 KB, 下载次数: 8

发表于 2011-7-30 02:53:11 | 显示全部楼层 来自: 中国辽宁
本帖最后由 woaishuijia 于 2011-8-4 09:43 编辑 4 ^! }- q  b+ {

  1. - r4 q5 @! M$ t& a: i' V
  2. (defun c:aaa (/ ss ft fd c1 c2 i j dmin d)
    + u" b" g; ~4 n* e* X9 o
  3.   (vl-load-com)    ;将 Visual LISP 扩展功能加载到 AutoLISP
    - c/ u, e# j/ a
  4.   (setq     ;将一个或多个符号的值设置为相应表达式的值
    * i# M- Y7 m1 A  i4 N) q
  5.     ss (vla-add    ;用 vla- 前缀函数调用 activeX 对象(下面的代码--该方法的第一个参数--指定的选择集集合对象)的 add 方法+ l$ T$ T& J# A! Q+ Y
  6.   (vla-get-selectionsets  ;用 vla-get- 前缀函数获取 activeX 对象--当前文档对象--的属性:选择集集合子对象,即使用 add 方法的集合对象- L, G5 l- h) K% G: J# N% z( {! w
  7.     (vla-get-activedocument ;用 vla-get- 前缀函数获取 activeX 对象--当前 AutoCAD 应用程序对象--的属性:活动文档子对象9 ]5 f1 X) _8 j7 }' K
  8.       (vlax-get-acad-object) ;用 vlax-get-acad-object 函数检索当前 AutoCAD 任务中的顶层 AutoCAD 应用程序对象
    $ ?' _- R0 x- Y+ I3 J
  9.     )
    8 i7 I( c& C0 ~! l+ T
  10.   )3 P0 g1 I0 k( a+ Y! M
  11.   "ss"    ;选择集名称: f$ S9 E7 c  j# }5 R: c3 |
  12.        )  H! q0 b7 V5 z5 n! d5 S+ z
  13.     ft (vlax-make-safearray vlax-vbinteger '(0 . 0))5 l7 k& c% Y0 J8 X+ e$ P
  14.      ;定义选择集过滤器的过滤类型数组.用 vlax-make-safearray 函数创建安全数组,整形,一维,一个元素(0 to 0).3 }$ A" A1 M- ?. q) ?6 i) C0 U
  15.     fd (vlax-make-safearray vlax-vbvariant '(0 . 0)); m9 d7 z# f7 z, i" ?+ Z
  16.      ;定义选择集过滤器的过滤值数组.用 vlax-make-safearray 函数创建安全数组,变体,一维,一个元素(0 to 0).
    1 V4 N6 i  t' V1 t  }# @3 b- `
  17.   )
    5 e* b. O; z4 B- U8 @
  18.   (vlax-safearray-put-element fd 0 "spline" )  f4 T* \4 G5 ^# J
  19.      ;用 vlax-safearray-put-element 函数为数组 fd 的第一个元素(索引号 0)赋值"spline". D1 P( p) v5 u, i! u- Y3 L7 [
  20.   (vla-selectonscreen ss ft fd)  ;用 vla- 前缀函数调用 ss 对象的 selectonscreen 方法,由用户在屏幕上选取样条曲线对象% D5 k  K+ q3 z2 c) ~
  21.   (if (= (vla-get-count ss) 2)  ;如果 ss 集合的 count 属性等于2(即用户选择了两条曲线)则执行下面的代码. }0 b: X- e. A' W; `
  22.     (progn" d2 h# [! _0 _( s; q; D, M, L
  23.       (setq c1 (vla-get-controlpoints ;用 vla-get- 前缀函数获取样条曲线对象的控制点坐标数组并赋值给c1(变量类型为变体,值为双精度数组)! X/ }% K4 v$ k  n
  24.    (vla-item ss 0) ;用 vla- 前缀函数调用集合对象的 item 方法,获取选择集中的索引号为 0 的样条曲线对象
    : B" S, o) Z( C
  25.         )
      b8 c( |* B( K% U
  26.      c2 (vla-get-controlpoints ;用 vla-get- 前缀函数获取样条曲线对象的控制点坐标数组并赋值给c2(变量类型为变体,值为双精度数组)9 d4 D. u! t3 c1 p- p/ C8 X9 E
  27.    (vla-item ss 1) ;用 vla- 前缀函数调用集合对象的 item 方法,获取选择集中的索引号为 1 的样条曲线对象, t  L% S2 u9 \- J
  28.         )6 `$ O) D+ E0 ], T( j$ l4 t) x
  29.      i  0   ;初始化外层循环变量9 Z8 S6 Z5 ^' q4 |' X$ f
  30.       )
    ! x  M) W0 _( B, V! \
  31.       (repeat    ;循环,外层
    + F8 B) V& ^% \+ y" Z& {/ E
  32. (/ (1+ (vlax-safearray-get-u-bound
    & v4 T, x+ l+ Q
  33.      ;用 vlax-safearray-get-u-bound 函数获取数组最大下标.第一个参数是数组,第二个参数是维数
    5 a- u3 i& Q6 A) h8 Y& X' Q
  34.    (vlax-variant-value c1);用 vlax-variant-value 函数获取变体变量 c1 的值(双精度数组)
    + F  F* _- l1 S7 Q
  35.    1
    & \4 @2 i' j" B5 f  j
  36.         )
      Z* b& z" ?9 I+ [* |( m; x3 g: f
  37.     )
    + E5 b/ e, c# n5 Z! F3 \
  38.     34 }; E/ L- r2 w  ?  Z
  39. )    ;用数组最大下标加1再除以3,所得结果做为循环次数--数组中每三个元素为一组代表一个控制点5 E2 q5 u3 z, I# w: g5 \
  40.   (setq j 0)   ;初始化内层循环变量
    - P5 m) h5 S% P8 \2 y3 X9 d
  41.   (repeat
    5 L/ I, Y4 i! h: Z$ C
  42.     (/ (1+ (vlax-safearray-get-u-bound0 z; C) |% M, W  V
  43.      ;第二条样条曲线控制点坐标数组的最大下标加1再除以3,做为内层循环次数: ]8 I) I9 S- L( P: [0 C
  44.       (vlax-variant-value c2)* F4 S8 J) j5 }( ~1 P2 s* u
  45.       1
    4 t0 V( r# h* u  x$ \7 Q: p. e
  46.     )- K5 f/ D: a- B- `
  47.        ). ~6 c# U+ a0 c  k: j2 |( w6 W
  48.        3% Q# ]& o% M$ D2 i0 H" y
  49.     )$ L4 ^' f; V: a! D$ f9 w* q
  50.      (setq d (distance  ;计算第一条曲线索引号为 i 的控制点到第二条曲线索引号为 j 的控制点之间的三维距离
      x0 Q" N7 W, s9 z( S& h3 ^* ~
  51.         (list  ;从 c1 数组中取出第一条曲线索引号为 i 的控制点的点表. [. ~4 O8 E$ N
  52.    (vlax-safearray-get-element
    . M* l: P6 e; R8 W
  53.      ;用 vlax-safearray-get-element 函数获取数组中的指定的元素
    $ j" g1 n! W2 I
  54.      (vlax-variant-value c1) ;数组9 [0 n6 _# w5 [# m9 M4 n/ O3 W
  55.      (* i 3) ;数组元素下标
    6 a6 B/ y3 D7 V4 @" P' q* x
  56.    )' P& A/ F- A5 @) e; B6 X
  57.    (vlax-safearray-get-element
    + x! G- S4 Z$ Y4 g. J: G5 ~- F" D
  58.      (vlax-variant-value c1)' E+ T* q+ M4 X& B0 p
  59.      (+ (* i 3) 1)! A! n& K2 P3 d3 b* E8 Q1 l
  60.    )
    $ [& L& o0 \0 |* P
  61.    (vlax-safearray-get-element9 K4 D4 [* O$ \4 Z
  62.      (vlax-variant-value c1)
    ! s. `/ M2 M+ u) `
  63.      (+ (* i 3) 2)
      c* e6 n8 B; b- ], E5 a. z
  64.    )
    1 r: r: R- `# X4 d& j4 R+ x
  65.         )
    0 }3 @0 z8 U2 O
  66.         (list  ;从 c2 数组中取出第二条曲线索引号为 j 的控制点的点表7 d% E& L$ H$ G0 `; x* y
  67.    (vlax-safearray-get-element
    $ \! Y4 i" y7 a- E# |
  68.      (vlax-variant-value c2)- j9 v# A. ?( j
  69.      (* j 3)! y9 _8 O, K* H" {
  70.    )$ Q$ z# p) P( E
  71.    (vlax-safearray-get-element- q' S7 `4 W& \  F% [
  72.      (vlax-variant-value c2)
    2 t+ s  P$ f  l* m
  73.      (+ (* j 3) 1)
    0 j+ Q' V3 M3 A2 X6 X
  74.    ): A( J) ?. E$ J. f. J! g
  75.    (vlax-safearray-get-element
    6 ]: d' b7 f% u& p, l
  76.      (vlax-variant-value c2)) W2 R. D) h  s' y
  77.      (+ (* j 3) 2)' r4 o1 O* d. G: L! t
  78.    )6 c: |9 w" w0 R
  79.         )
    7 a* j/ j6 Q9 x% n
  80.       )
    8 M2 N4 G, Y: X: T7 X* W- u4 t$ Q
  81.      )1 y5 g2 U: C. T% @1 m* y
  82.      (if dmin   ;检查最小距离是否为 nil (是否首次)
    # N; p0 d4 Z; D7 ?3 e9 I) C+ C
  83.        (if (> dmin d)  ;不是首次,比较计算所得的距离与已保存的最小距离,如发现更小的距离则保存- x4 P$ I) {0 ^7 s  {$ x
  84.   (setq dmin d)
    , S2 l/ i1 Z- W. P6 _- G+ F4 @
  85.        )
      z" Z5 C: e1 e2 h& Y) S# H
  86.        (setq dmin d)  ;首次,把首个距离记录为最小距离, M' \- U+ f% @* I5 S- K; {
  87.      )
    # _4 }! F; P3 \! S; ^) `+ s
  88.      (setq j (1+ j))  ;内层循环变量递增
    : X5 [& W" Q" V- S! F( Q
  89.   )- x& e) E' F" D
  90.   (setq i (1+ i))  ;外层循环变量递增4 O- Y0 d6 h# P3 ^1 H! b
  91.       )
    8 N0 h7 _$ g- W
  92.     )
    & o( B! y" z8 H7 o; i! J
  93.   )8 n& ^7 d4 O/ ?' t" m3 v8 e
  94.   (vla-delete ss)   ;用 vla- 前缀函数调用 ss 集合的 delete 方法,删除用过的选择集7 h8 {; {. K" a) _  X  w" Y2 O
  95.   (princ dmin)    ;命令行输出计算结果
    - W1 _6 `/ V9 R4 ]
  96.   (princ)    ;静默退出
    9 L! ~+ ^" k  F0 o* [: T# i. K- `2 Y
  97. )
    ! q3 ?: V5 d  e$ S9 t# o
复制代码
发表于 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 )

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