QQ登录

只需一步,快速开始

登录 | 注册 | 找回密码

三维网

 找回密码
 注册

QQ登录

只需一步,快速开始

展开

通知     

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

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

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

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

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

x
本帖最后由 tataki 于 2011-7-30 07:13 编辑 # \1 c7 r+ D) f0 r) \
+ W5 D4 t' ?  x2 `: X) r) P
各位好,最近遇到一个问题,在cad中做了两个闭合的三维spline,我是想算一算他们两者最近的距离是多少,当然不用负责的公式就算,就想着用最直观,也是很简单的方法来计算。见附图。
) G; _7 a. r: r# A5 q! Q我的想法是在红色spline上将这条曲线上的每个点计算到蓝色曲线上的每个点距离,也就是一个二次循环,最后找出最小值就行。然而在操作中遇到了两个问题:4 g! z- u! T. E( t( R
1.在spline的图元了保存的控制点坐标怎么提取出来?以前只提过其中的一项,现在面对这几百个数据不知道该怎么提取了。
8 o! u4 d  G* Q$ _5 |2.提取的数据怎么存放呢?我以前是学c++的,在C里面肯定用个数组循环就行了,但是不怎么会lisp,在lisp里面没有数组的概念,因此怎么存大量数据,还有后期的怎么读取都让我很迷惑,请各位懂得朋友帮个忙。在网上也找到了几个提spline坐标的程序,可是里面使用vl那些命令,这个我不知道怎么用,也没法修改成我想要的,哪位高手能帮下我,非常感谢!
; ~1 |8 O3 t9 p9 c9 J! q现附上 这两条曲线的dwg文件。) v0 O: _3 n3 C' R6 D& i. ^9 k5 f
2011-7-29 19-17-21.jpg 9 u5 x9 P# C% M4 d/ }/ v- S

$ i, r" A/ n9 y& Y0 {8 W! `今早一打开我的帖子,就看到斑竹的答复!很激动,没想到这么快就回复了!
9 w6 |1 U. D) {7 z7 L4 G非常感谢斑竹的帮助!不但给出了源代码,还有详细的注解,斑竹的认真热心和负责让我肃然起敬,以前的我提的几个问题也是斑竹给解决的。刚
看了一下发帖时间,半夜02:53....看到这个时间,明白人心理都懂得,再多赞美的词也显得苍白了...." N+ A4 q# I/ Y5 E
辛苦斑竹了,今天周末请多休息!

spline.dwg

172.45 KB, 下载次数: 8

发表于 2011-7-30 02:53:11 | 显示全部楼层 来自: 中国辽宁
本帖最后由 woaishuijia 于 2011-8-4 09:43 编辑
) A! G+ ?- m8 B% ]+ Q  H. d- s9 U
  1. % x( w  J% z$ U% x% d! W
  2. (defun c:aaa (/ ss ft fd c1 c2 i j dmin d)
    * I) k% F' [: o0 h" a+ t
  3.   (vl-load-com)    ;将 Visual LISP 扩展功能加载到 AutoLISP " e" i: C8 f4 e' V& S  O; M
  4.   (setq     ;将一个或多个符号的值设置为相应表达式的值2 I0 `. f; {# g9 t; m
  5.     ss (vla-add    ;用 vla- 前缀函数调用 activeX 对象(下面的代码--该方法的第一个参数--指定的选择集集合对象)的 add 方法/ E5 O3 B$ l3 C
  6.   (vla-get-selectionsets  ;用 vla-get- 前缀函数获取 activeX 对象--当前文档对象--的属性:选择集集合子对象,即使用 add 方法的集合对象5 \- \! t- A- u4 n& S' L$ D- P
  7.     (vla-get-activedocument ;用 vla-get- 前缀函数获取 activeX 对象--当前 AutoCAD 应用程序对象--的属性:活动文档子对象
    & \: |/ L+ x: s6 x5 l- ?% @4 T
  8.       (vlax-get-acad-object) ;用 vlax-get-acad-object 函数检索当前 AutoCAD 任务中的顶层 AutoCAD 应用程序对象" b: Z, a! L& {! \! Q/ u
  9.     )
    8 q8 U" C/ H. v& r+ A1 I
  10.   )
    + x8 P9 m' Y; }: K7 G
  11.   "ss"    ;选择集名称4 C  o! {  e' H& E, a/ j; l
  12.        )
    ; h, K5 n4 P7 J/ u# Z! `, A0 n0 ~1 B
  13.     ft (vlax-make-safearray vlax-vbinteger '(0 . 0))
    2 `# }  A3 _- S& D8 [! {- {
  14.      ;定义选择集过滤器的过滤类型数组.用 vlax-make-safearray 函数创建安全数组,整形,一维,一个元素(0 to 0).3 v: Y. s, [& E7 T
  15.     fd (vlax-make-safearray vlax-vbvariant '(0 . 0))" w2 T: G; G! _1 ^7 o; P
  16.      ;定义选择集过滤器的过滤值数组.用 vlax-make-safearray 函数创建安全数组,变体,一维,一个元素(0 to 0).
    ' q, X, W1 N' E" _4 `
  17.   )& z& `2 |- H2 o$ b
  18.   (vlax-safearray-put-element fd 0 "spline" )
    : r) k. t" j6 ]/ q. a! y
  19.      ;用 vlax-safearray-put-element 函数为数组 fd 的第一个元素(索引号 0)赋值"spline"
    9 O5 S  @) K1 v* V$ h; Y/ G
  20.   (vla-selectonscreen ss ft fd)  ;用 vla- 前缀函数调用 ss 对象的 selectonscreen 方法,由用户在屏幕上选取样条曲线对象
    # O4 Q! t( X$ E2 r; k! W0 c3 w  C
  21.   (if (= (vla-get-count ss) 2)  ;如果 ss 集合的 count 属性等于2(即用户选择了两条曲线)则执行下面的代码
    + Q0 k* u( o" f( x3 V8 A
  22.     (progn
    . ~6 b# Q5 c$ }- @; ]) |) v/ j
  23.       (setq c1 (vla-get-controlpoints ;用 vla-get- 前缀函数获取样条曲线对象的控制点坐标数组并赋值给c1(变量类型为变体,值为双精度数组)+ {5 i9 e3 ~1 i0 O3 _' M4 i
  24.    (vla-item ss 0) ;用 vla- 前缀函数调用集合对象的 item 方法,获取选择集中的索引号为 0 的样条曲线对象; B9 L. k2 J3 q
  25.         )
    ) y1 h1 z# {% T
  26.      c2 (vla-get-controlpoints ;用 vla-get- 前缀函数获取样条曲线对象的控制点坐标数组并赋值给c2(变量类型为变体,值为双精度数组)
    " B, ~' Q+ Z" v0 i
  27.    (vla-item ss 1) ;用 vla- 前缀函数调用集合对象的 item 方法,获取选择集中的索引号为 1 的样条曲线对象
    : E6 x$ L* `" B& S0 X9 {
  28.         )  y  b0 z# a' o: p6 O  b
  29.      i  0   ;初始化外层循环变量! _# p% s/ d3 F8 l6 N1 e$ z; X
  30.       )
    3 N1 t$ g, Q: ?6 Z: i+ \
  31.       (repeat    ;循环,外层. H; m2 c6 G: @! j
  32. (/ (1+ (vlax-safearray-get-u-bound" O4 S% \  O6 @$ }, y. ]
  33.      ;用 vlax-safearray-get-u-bound 函数获取数组最大下标.第一个参数是数组,第二个参数是维数
    0 ^$ ?& I( k" y/ E6 e
  34.    (vlax-variant-value c1);用 vlax-variant-value 函数获取变体变量 c1 的值(双精度数组)
    / t. z3 a# o% J  ~3 n0 H5 [2 {
  35.    1, l+ d' Y6 z; I3 n1 _% V& t/ L
  36.         )
    8 d+ w" f! ^8 y8 w
  37.     )
    * o' }" i! ]8 r: ?! P2 {' W) M$ @
  38.     3
    * S' @' \. E! w" E. ^- z4 r. A8 z
  39. )    ;用数组最大下标加1再除以3,所得结果做为循环次数--数组中每三个元素为一组代表一个控制点
    : @: H, z& A6 b- [& s& f* v
  40.   (setq j 0)   ;初始化内层循环变量
    ; g' m, J7 I- k' g2 ^
  41.   (repeat
    ! g7 ^+ C7 t0 B* t
  42.     (/ (1+ (vlax-safearray-get-u-bound& Y4 F6 s( Y+ P* \1 ^
  43.      ;第二条样条曲线控制点坐标数组的最大下标加1再除以3,做为内层循环次数
    5 t( W  c5 d1 m1 b6 B
  44.       (vlax-variant-value c2)" u& v' t- D6 k  [1 \! v& m7 L4 G% Z
  45.       1
    8 ]- U7 x0 p1 B7 Z- W, n" i% J
  46.     )
    0 d2 w" x# i- ^
  47.        )
    9 Z- b# Y$ g: D0 t2 \  W
  48.        3; I# X  d* [+ [  ]5 ~
  49.     ), M7 q+ Z- s' T) S- W+ N+ ?0 Y
  50.      (setq d (distance  ;计算第一条曲线索引号为 i 的控制点到第二条曲线索引号为 j 的控制点之间的三维距离, `8 x- w& n1 m% \( j: x9 r  g* M
  51.         (list  ;从 c1 数组中取出第一条曲线索引号为 i 的控制点的点表
    % z7 f, k- o5 t- L, Q; ?5 x1 u
  52.    (vlax-safearray-get-element
    : @" `3 g1 S$ C+ K4 s1 @. K
  53.      ;用 vlax-safearray-get-element 函数获取数组中的指定的元素
    % `; ]- g# y( p3 U5 q
  54.      (vlax-variant-value c1) ;数组# P1 x, p9 C; w3 t2 G3 u( b2 c
  55.      (* i 3) ;数组元素下标8 N+ X5 o) C7 v0 p! a. _5 F
  56.    )
    8 c# \: J" @& C" `, q5 d
  57.    (vlax-safearray-get-element  p5 S) P4 _) |3 V! y1 ^9 R
  58.      (vlax-variant-value c1)
    6 g1 f/ h; c& S) u3 N6 O0 p
  59.      (+ (* i 3) 1)
      ]  E9 t+ T* S
  60.    )8 Y$ d) Q8 y- h- D
  61.    (vlax-safearray-get-element' R5 z  m( f. l! h# j5 h! @# w
  62.      (vlax-variant-value c1)
    8 c* W# w6 ^6 i9 d% ~: H. }
  63.      (+ (* i 3) 2), ^1 u4 K8 A/ E$ C, n& }
  64.    )
    $ P' R7 ~9 z4 U5 ?# M. o: Q5 U% r; f# }
  65.         )
    ' X% O* ]+ {/ I$ q: e
  66.         (list  ;从 c2 数组中取出第二条曲线索引号为 j 的控制点的点表/ y/ ^  Z9 U' _/ e3 \. K8 }2 l0 y5 C
  67.    (vlax-safearray-get-element
    3 O1 P+ Q8 h$ k2 t9 @1 e4 E% h
  68.      (vlax-variant-value c2)
    , ?2 R6 ]4 C' t' [
  69.      (* j 3)1 h; Z  u" T( s6 E
  70.    )1 a) H& D7 Y% m7 G% G  k. I
  71.    (vlax-safearray-get-element6 }* f2 O( ^$ E, i% D' ^! l
  72.      (vlax-variant-value c2)
    5 i6 z; t; s; f; H. G+ ?: t
  73.      (+ (* j 3) 1)% u6 R& ?. }- w+ q; A- B( g' p+ l
  74.    )6 t; t+ U, d! a
  75.    (vlax-safearray-get-element
    4 h' ^1 O8 w. A' f, }
  76.      (vlax-variant-value c2): l. q% ~9 y6 Q7 c
  77.      (+ (* j 3) 2)& C& n7 j0 F/ r/ ~4 e) P& o
  78.    )
    3 }3 {7 p5 Q, N) m$ }4 M: |1 a( P
  79.         )2 l2 T: Z) z4 Q5 [
  80.       )
    - C/ [' ^/ q3 K% R4 J3 ~- s( x: U
  81.      )
    7 Y' F# C6 I7 ~! _& w4 Q* H; K  t1 @1 ^
  82.      (if dmin   ;检查最小距离是否为 nil (是否首次)$ V8 {  v5 C5 n% @
  83.        (if (> dmin d)  ;不是首次,比较计算所得的距离与已保存的最小距离,如发现更小的距离则保存* k1 K. |3 t- q; L9 p/ L
  84.   (setq dmin d)6 d$ Z+ I& |6 f2 z0 _( C
  85.        )
    1 C3 T9 l- k! Y' u9 k7 e0 Z
  86.        (setq dmin d)  ;首次,把首个距离记录为最小距离3 l* m( _5 B0 e) h6 I
  87.      )
      D& a7 d/ K0 v* q9 p# R* }. G
  88.      (setq j (1+ j))  ;内层循环变量递增
    & M7 u: T) N9 s8 v% P  h
  89.   )
    , p1 m3 Y3 A& E# w. o2 C
  90.   (setq i (1+ i))  ;外层循环变量递增
    ) [* b; L' P0 Z' n% @- Q
  91.       )( o  ]; T; s7 u; R$ Z3 B
  92.     )5 {1 ?2 H6 G) W! E' L
  93.   )% V2 r4 c7 A5 o( [' k* e0 D) b
  94.   (vla-delete ss)   ;用 vla- 前缀函数调用 ss 集合的 delete 方法,删除用过的选择集( d( b; r$ h, D, s
  95.   (princ dmin)    ;命令行输出计算结果
    . H2 i7 v. G( w7 L) ^
  96.   (princ)    ;静默退出
    : e. z' s/ w$ [1 V: y" T; d
  97. )+ E3 u2 W9 |/ T/ Y! m: p
复制代码
发表于 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 )

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