QQ登录

只需一步,快速开始

登录 | 注册 | 找回密码

三维网

 找回密码
 注册

QQ登录

只需一步,快速开始

展开

通知     

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

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

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

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

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

x
本帖最后由 tataki 于 2011-7-30 07:13 编辑 * G" @( z6 O  @: k& m$ v
0 K# \% n4 v! I  e
各位好,最近遇到一个问题,在cad中做了两个闭合的三维spline,我是想算一算他们两者最近的距离是多少,当然不用负责的公式就算,就想着用最直观,也是很简单的方法来计算。见附图。% ]- g5 n1 @. j& O8 Q; @, c0 Z
我的想法是在红色spline上将这条曲线上的每个点计算到蓝色曲线上的每个点距离,也就是一个二次循环,最后找出最小值就行。然而在操作中遇到了两个问题:; T6 |0 X% M6 D5 ~; r& [$ D1 O6 n
1.在spline的图元了保存的控制点坐标怎么提取出来?以前只提过其中的一项,现在面对这几百个数据不知道该怎么提取了。
6 _6 y) r" m% l  ^8 g2.提取的数据怎么存放呢?我以前是学c++的,在C里面肯定用个数组循环就行了,但是不怎么会lisp,在lisp里面没有数组的概念,因此怎么存大量数据,还有后期的怎么读取都让我很迷惑,请各位懂得朋友帮个忙。在网上也找到了几个提spline坐标的程序,可是里面使用vl那些命令,这个我不知道怎么用,也没法修改成我想要的,哪位高手能帮下我,非常感谢!
2 }8 N  z+ f* m8 ?现附上 这两条曲线的dwg文件。
4 X- ]7 d: ~3 G2 ^+ u 2011-7-29 19-17-21.jpg / ~& U$ |2 S0 V6 Z3 i1 z

4 h6 _0 @8 N$ L# d. b. Y今早一打开我的帖子,就看到斑竹的答复!很激动,没想到这么快就回复了!5 m9 G5 L7 h! q3 J
非常感谢斑竹的帮助!不但给出了源代码,还有详细的注解,斑竹的认真热心和负责让我肃然起敬,以前的我提的几个问题也是斑竹给解决的。刚
看了一下发帖时间,半夜02:53....看到这个时间,明白人心理都懂得,再多赞美的词也显得苍白了....$ q0 [. d" c% v: c4 W3 k; \
辛苦斑竹了,今天周末请多休息!

spline.dwg

172.45 KB, 下载次数: 8

发表于 2011-7-30 02:53:11 | 显示全部楼层 来自: 中国辽宁
本帖最后由 woaishuijia 于 2011-8-4 09:43 编辑
; ]+ c3 M3 d: a1 M8 {+ u8 \

  1. 3 A3 X. C- }& r4 r2 r
  2. (defun c:aaa (/ ss ft fd c1 c2 i j dmin d)7 B0 I; U9 U8 W# N
  3.   (vl-load-com)    ;将 Visual LISP 扩展功能加载到 AutoLISP # ?/ `+ s7 ^( a3 f: H3 r. v& |
  4.   (setq     ;将一个或多个符号的值设置为相应表达式的值
    : y/ M/ L% g4 y& `' K& p1 \
  5.     ss (vla-add    ;用 vla- 前缀函数调用 activeX 对象(下面的代码--该方法的第一个参数--指定的选择集集合对象)的 add 方法
    5 q6 Y  j% n, B  D1 g+ n
  6.   (vla-get-selectionsets  ;用 vla-get- 前缀函数获取 activeX 对象--当前文档对象--的属性:选择集集合子对象,即使用 add 方法的集合对象5 d; n" h2 r* E9 N
  7.     (vla-get-activedocument ;用 vla-get- 前缀函数获取 activeX 对象--当前 AutoCAD 应用程序对象--的属性:活动文档子对象
    3 Y. k4 N; u. R! `+ v+ G% O
  8.       (vlax-get-acad-object) ;用 vlax-get-acad-object 函数检索当前 AutoCAD 任务中的顶层 AutoCAD 应用程序对象
    8 [, A# Y, Q5 V, [
  9.     )/ ]# ]3 `. R$ j2 c. n
  10.   )
      D/ b( p$ v, j
  11.   "ss"    ;选择集名称' ^8 y+ k% y) b* M  A1 R3 s
  12.        )
    ) r* i; |6 |$ e" l# l* k0 }) [
  13.     ft (vlax-make-safearray vlax-vbinteger '(0 . 0))- U# P! z4 `. X) `$ x
  14.      ;定义选择集过滤器的过滤类型数组.用 vlax-make-safearray 函数创建安全数组,整形,一维,一个元素(0 to 0).
    " y* ]# ]: s1 ~1 I6 A
  15.     fd (vlax-make-safearray vlax-vbvariant '(0 . 0))7 b8 @) x  p) u1 a+ G2 |
  16.      ;定义选择集过滤器的过滤值数组.用 vlax-make-safearray 函数创建安全数组,变体,一维,一个元素(0 to 0).
    4 c) A! ?8 c2 s8 M  Q; v
  17.   )
    , d2 a) y: L& v( E# U# V# G( n
  18.   (vlax-safearray-put-element fd 0 "spline" )
    3 \2 W! \) V: R/ K) [$ K8 F4 V
  19.      ;用 vlax-safearray-put-element 函数为数组 fd 的第一个元素(索引号 0)赋值"spline"
    ' p4 U5 C) Q( M  d9 c
  20.   (vla-selectonscreen ss ft fd)  ;用 vla- 前缀函数调用 ss 对象的 selectonscreen 方法,由用户在屏幕上选取样条曲线对象' y( Y' H5 o, Y, L; N: ?+ ^' e
  21.   (if (= (vla-get-count ss) 2)  ;如果 ss 集合的 count 属性等于2(即用户选择了两条曲线)则执行下面的代码2 L0 K2 O' F3 p, r1 ~( o
  22.     (progn
    : B$ y) M; ]6 }8 r  e
  23.       (setq c1 (vla-get-controlpoints ;用 vla-get- 前缀函数获取样条曲线对象的控制点坐标数组并赋值给c1(变量类型为变体,值为双精度数组)" P1 \6 I9 t. Z# R+ G
  24.    (vla-item ss 0) ;用 vla- 前缀函数调用集合对象的 item 方法,获取选择集中的索引号为 0 的样条曲线对象
    5 n+ T, D" z8 x, P  _% O
  25.         )
    ) {2 F7 P' |/ S5 ]: o
  26.      c2 (vla-get-controlpoints ;用 vla-get- 前缀函数获取样条曲线对象的控制点坐标数组并赋值给c2(变量类型为变体,值为双精度数组)
    0 m9 m* s7 z9 h4 y9 c
  27.    (vla-item ss 1) ;用 vla- 前缀函数调用集合对象的 item 方法,获取选择集中的索引号为 1 的样条曲线对象
    % O/ d' A& o, N. ?. s2 a
  28.         )
      p8 C# k9 X7 a: _/ |
  29.      i  0   ;初始化外层循环变量
    3 a% j# f( {. A& M7 F3 k
  30.       )
    - X% H" W6 R5 [* O+ u8 k/ _$ m
  31.       (repeat    ;循环,外层  y- x8 ^0 ?+ F! q/ Z2 ~
  32. (/ (1+ (vlax-safearray-get-u-bound& n# k- b9 I& u
  33.      ;用 vlax-safearray-get-u-bound 函数获取数组最大下标.第一个参数是数组,第二个参数是维数
    . Z; V9 Q- H( q) n- h
  34.    (vlax-variant-value c1);用 vlax-variant-value 函数获取变体变量 c1 的值(双精度数组)
    / t" F7 J4 m: O
  35.    15 O( o3 ]  _& F3 `  w7 I# t# ^
  36.         )
    ; O; M, b9 J9 t
  37.     )
    3 x# l; u. f+ A" Z, t# J
  38.     3
    % \! |8 n: v# D$ Z' N
  39. )    ;用数组最大下标加1再除以3,所得结果做为循环次数--数组中每三个元素为一组代表一个控制点; y1 l5 v  Y$ q( x" _/ `# ~# s
  40.   (setq j 0)   ;初始化内层循环变量
    . ]7 V" I4 E; r0 P( R7 y! O' ~1 x
  41.   (repeat2 i$ n4 l6 M+ b, y0 C
  42.     (/ (1+ (vlax-safearray-get-u-bound* y# \: e0 W% U; _; J) @) a' G
  43.      ;第二条样条曲线控制点坐标数组的最大下标加1再除以3,做为内层循环次数/ F7 j3 B# [/ u! V# P* Q( Z; x
  44.       (vlax-variant-value c2)
    2 Q0 t0 q4 P1 ]6 Q/ \) L7 x- O  ^7 x
  45.       1
      y: _: V  u4 e: o
  46.     )
    0 M4 k+ u4 r0 K& {8 L) L% B' X
  47.        )
    & ]/ D! j# ]( D1 E
  48.        3& U" J5 c6 v: E+ O3 k
  49.     )  g2 i  x! H1 p, i" m2 Q' y
  50.      (setq d (distance  ;计算第一条曲线索引号为 i 的控制点到第二条曲线索引号为 j 的控制点之间的三维距离
    6 c% L6 l; q# Q
  51.         (list  ;从 c1 数组中取出第一条曲线索引号为 i 的控制点的点表
    7 p; ~+ ^( x+ b0 C' J
  52.    (vlax-safearray-get-element/ u& ^: C5 I5 b8 W3 F
  53.      ;用 vlax-safearray-get-element 函数获取数组中的指定的元素. q4 _7 B, i/ g- T; @
  54.      (vlax-variant-value c1) ;数组# ?0 Z- v" E4 Z
  55.      (* i 3) ;数组元素下标
    / E8 l0 [7 I+ E1 s' x
  56.    )% Q# h8 t  M! V4 q. u% W' d  V& P
  57.    (vlax-safearray-get-element
    , I) R2 H3 A8 V- p  U$ F: \
  58.      (vlax-variant-value c1). E$ `/ Q9 t1 }3 c: g8 z4 X
  59.      (+ (* i 3) 1)
    7 W" j/ w2 Q# l" D- G9 m, f
  60.    )+ o4 t! t1 k5 g. M
  61.    (vlax-safearray-get-element% ~3 j, m  O# x. J1 I0 D
  62.      (vlax-variant-value c1)
    * S, m( r( Q- p
  63.      (+ (* i 3) 2)" i/ A) C+ S3 k/ M, ]9 u' W" R4 O
  64.    )$ p& S' ]& G: @1 {. [* g
  65.         )
    & U& E/ u  n$ c0 ]
  66.         (list  ;从 c2 数组中取出第二条曲线索引号为 j 的控制点的点表
    ' J2 }" B& t0 n( p+ J; ~' Z
  67.    (vlax-safearray-get-element7 ]2 b; V+ ^' Q3 c1 d) T8 `. \( [7 u: n
  68.      (vlax-variant-value c2)& K) c. U$ e  v" Z6 ]' G9 {9 P2 ]+ [
  69.      (* j 3)1 s+ Q9 `& Z3 a6 v1 R. K
  70.    )( Q  I8 f. A5 d) E; X! [5 r
  71.    (vlax-safearray-get-element; v2 ]" q1 i9 P
  72.      (vlax-variant-value c2)7 C' V3 y8 [$ }. f: M& O& n+ }4 ~  M  _
  73.      (+ (* j 3) 1)4 W+ M' O2 X. g0 Q1 [. O9 f
  74.    )
    ! [1 v1 P- P% r9 i; b) d6 x
  75.    (vlax-safearray-get-element& y/ }* O2 G% k8 z7 s
  76.      (vlax-variant-value c2)* A; z& j! c5 t8 |) P
  77.      (+ (* j 3) 2)0 W7 B. Q0 U' q. n
  78.    )
    5 U! U7 Y; s! ?$ E% U: F" \
  79.         )' k1 J! B9 i. _7 {$ o4 z
  80.       ). `8 @) p* A7 @7 ^
  81.      ): N- m  Z; E* v
  82.      (if dmin   ;检查最小距离是否为 nil (是否首次)
    + ^( L1 f6 a7 r( P" U# F
  83.        (if (> dmin d)  ;不是首次,比较计算所得的距离与已保存的最小距离,如发现更小的距离则保存" y7 {0 U+ d# v& k9 G. Y- S- v$ S
  84.   (setq dmin d)
    1 R5 N' h9 |+ e. G; x
  85.        )
    * r" ~! w) I0 }) i6 i! x
  86.        (setq dmin d)  ;首次,把首个距离记录为最小距离
    : |! @: D+ o; f7 Q9 z
  87.      )
    " l3 q( V2 x1 |# ]
  88.      (setq j (1+ j))  ;内层循环变量递增. l+ `5 g( w0 P- S! y. n
  89.   )5 _8 T1 j8 t! k: l7 h4 R
  90.   (setq i (1+ i))  ;外层循环变量递增$ e$ Q  D$ J- ?) b# y
  91.       )
    3 ?" b7 Z3 R( v( V) |& |
  92.     )
    ( X' Y) b9 i- Q5 I9 P
  93.   )" E/ o! E$ x$ ^& m8 {
  94.   (vla-delete ss)   ;用 vla- 前缀函数调用 ss 集合的 delete 方法,删除用过的选择集
    : D: ^+ L, B# ]! J  V5 G
  95.   (princ dmin)    ;命令行输出计算结果
    5 N! V: ~" E' E& k8 w. M" M4 ^
  96.   (princ)    ;静默退出* \  \( X: H( |
  97. )8 q7 s9 w$ f- ~* t, }8 b* U
复制代码
发表于 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 )

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