QQ登录

只需一步,快速开始

登录 | 注册 | 找回密码

三维网

 找回密码
 注册

QQ登录

只需一步,快速开始

展开

通知     

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

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

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

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

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

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

spline.dwg

172.45 KB, 下载次数: 8

发表于 2011-7-30 02:53:11 | 显示全部楼层 来自: 中国辽宁
本帖最后由 woaishuijia 于 2011-8-4 09:43 编辑
+ x1 s: M1 `; {6 K

  1. 1 v  a4 `+ M1 i! \
  2. (defun c:aaa (/ ss ft fd c1 c2 i j dmin d)
    : E# M- `" G% t- |
  3.   (vl-load-com)    ;将 Visual LISP 扩展功能加载到 AutoLISP 6 o- m1 Q8 D+ V4 p; e- C& L
  4.   (setq     ;将一个或多个符号的值设置为相应表达式的值3 C8 t( B5 @6 _2 q
  5.     ss (vla-add    ;用 vla- 前缀函数调用 activeX 对象(下面的代码--该方法的第一个参数--指定的选择集集合对象)的 add 方法2 V3 ^% L! \4 C8 O( q
  6.   (vla-get-selectionsets  ;用 vla-get- 前缀函数获取 activeX 对象--当前文档对象--的属性:选择集集合子对象,即使用 add 方法的集合对象
    8 ]1 y) U' Y2 [* `  f; ]
  7.     (vla-get-activedocument ;用 vla-get- 前缀函数获取 activeX 对象--当前 AutoCAD 应用程序对象--的属性:活动文档子对象7 M( c) ]7 {/ d8 t
  8.       (vlax-get-acad-object) ;用 vlax-get-acad-object 函数检索当前 AutoCAD 任务中的顶层 AutoCAD 应用程序对象
    / W) M8 M* R+ o) q& k
  9.     )
    0 G" ~, a( C  E* p! m5 x5 y
  10.   )$ X2 E- a) |; a% Z, C2 x
  11.   "ss"    ;选择集名称
    2 P3 O0 _% s! `$ \& _1 m
  12.        )
    / Z$ {! ~# r& [) V* p$ K0 a
  13.     ft (vlax-make-safearray vlax-vbinteger '(0 . 0))
    7 M7 F2 @/ y/ m, o2 ]2 C/ H1 M4 D
  14.      ;定义选择集过滤器的过滤类型数组.用 vlax-make-safearray 函数创建安全数组,整形,一维,一个元素(0 to 0).4 d& a! i* l7 y3 A, Z
  15.     fd (vlax-make-safearray vlax-vbvariant '(0 . 0))
    * @) \; R" R- c, p0 I; @
  16.      ;定义选择集过滤器的过滤值数组.用 vlax-make-safearray 函数创建安全数组,变体,一维,一个元素(0 to 0).+ Z: R1 h  T& j% m3 `
  17.   )
    ! m3 m9 H9 D# \& E/ F0 z6 }
  18.   (vlax-safearray-put-element fd 0 "spline" )) [" b' M4 [, j6 h: I0 u) S' A
  19.      ;用 vlax-safearray-put-element 函数为数组 fd 的第一个元素(索引号 0)赋值"spline"
    % Y5 u9 n4 H* W% q# X
  20.   (vla-selectonscreen ss ft fd)  ;用 vla- 前缀函数调用 ss 对象的 selectonscreen 方法,由用户在屏幕上选取样条曲线对象5 T0 S$ Z# [# ^0 U, A1 c3 Q) `
  21.   (if (= (vla-get-count ss) 2)  ;如果 ss 集合的 count 属性等于2(即用户选择了两条曲线)则执行下面的代码% r7 N& Y; s/ o( e3 a
  22.     (progn
    , c& b: {  I& D6 n  ?6 t
  23.       (setq c1 (vla-get-controlpoints ;用 vla-get- 前缀函数获取样条曲线对象的控制点坐标数组并赋值给c1(变量类型为变体,值为双精度数组)
    ; n6 P' }7 K5 o
  24.    (vla-item ss 0) ;用 vla- 前缀函数调用集合对象的 item 方法,获取选择集中的索引号为 0 的样条曲线对象
    2 ^1 g0 n0 x3 I
  25.         )
    ; q4 O/ A5 n# p5 W
  26.      c2 (vla-get-controlpoints ;用 vla-get- 前缀函数获取样条曲线对象的控制点坐标数组并赋值给c2(变量类型为变体,值为双精度数组)
    & t9 W0 C& Z" [3 T$ S  b
  27.    (vla-item ss 1) ;用 vla- 前缀函数调用集合对象的 item 方法,获取选择集中的索引号为 1 的样条曲线对象
    # b1 g# s. d0 C1 ]8 ?
  28.         )" S' r! T' j% K! V* k
  29.      i  0   ;初始化外层循环变量
    7 L) D4 L. L, x5 Z7 e
  30.       )
    " F. h& j( [: L6 h& S; h1 P  a3 n
  31.       (repeat    ;循环,外层
    ( N% e) ~/ d; b
  32. (/ (1+ (vlax-safearray-get-u-bound
    / T# H0 s2 G- C& H# f
  33.      ;用 vlax-safearray-get-u-bound 函数获取数组最大下标.第一个参数是数组,第二个参数是维数1 ?8 ?" H1 H' c( L8 h5 z
  34.    (vlax-variant-value c1);用 vlax-variant-value 函数获取变体变量 c1 的值(双精度数组)
    " V# [# M$ Y* _  G! d8 r
  35.    1, D+ p3 X; J( y
  36.         )) m& [" J' k! @* ?% ?4 `2 C
  37.     )
    % E1 t, J" L" M) m5 D& A
  38.     3# b* I& A1 V% U( X
  39. )    ;用数组最大下标加1再除以3,所得结果做为循环次数--数组中每三个元素为一组代表一个控制点
    9 k& u+ [0 D) M
  40.   (setq j 0)   ;初始化内层循环变量
    9 M. e; o6 X5 l
  41.   (repeat
    9 r; H% U5 ]/ M4 y
  42.     (/ (1+ (vlax-safearray-get-u-bound- {" |# v# ?: _5 w/ o/ Z* P
  43.      ;第二条样条曲线控制点坐标数组的最大下标加1再除以3,做为内层循环次数
    : Y' }' P! ^3 \4 e8 d# B
  44.       (vlax-variant-value c2)
    / f4 r8 p8 O" }0 y( Z' d
  45.       12 j$ y7 v: Q% _6 o6 l4 k6 U
  46.     ). h; B+ U% R+ s/ ?5 [& r$ ^
  47.        )* H: j" j8 K, m% L0 h1 Y
  48.        3, K( q6 Y# M7 E9 c' {% ~5 ]
  49.     )" E3 X2 `0 L* q0 v
  50.      (setq d (distance  ;计算第一条曲线索引号为 i 的控制点到第二条曲线索引号为 j 的控制点之间的三维距离2 i8 e" N9 @/ M0 T9 [( i
  51.         (list  ;从 c1 数组中取出第一条曲线索引号为 i 的控制点的点表
    ' x/ T' `) e& Q7 R$ L8 \
  52.    (vlax-safearray-get-element  S8 L: ?# O0 s6 h9 V: \
  53.      ;用 vlax-safearray-get-element 函数获取数组中的指定的元素! m; R& Z$ a5 }! Y0 j% N2 J
  54.      (vlax-variant-value c1) ;数组( s8 F! G: v; C  j/ W) a& ?
  55.      (* i 3) ;数组元素下标7 a* s5 @$ T# Q$ _5 X6 o
  56.    )0 J+ H6 I7 q1 f' I: ~8 O% W
  57.    (vlax-safearray-get-element5 ]# ^  L$ e8 b+ Z
  58.      (vlax-variant-value c1)
    ; A; J$ h. X* c
  59.      (+ (* i 3) 1)& Q7 L8 U4 x8 X( q
  60.    )' v5 ~$ l+ k6 K* A) v8 ?: Q
  61.    (vlax-safearray-get-element
    " v6 u* O6 h# {3 @
  62.      (vlax-variant-value c1)4 U- Q" V; c: ]# l* A/ X% i7 h) }
  63.      (+ (* i 3) 2)! O: _1 r. {0 }: U. t% y/ j- y* a% V
  64.    )5 U/ ]( F% M5 G  {0 N7 |5 u8 T. t$ F, M
  65.         )
    ' D" K( Y2 }$ G  P
  66.         (list  ;从 c2 数组中取出第二条曲线索引号为 j 的控制点的点表
    , b+ l9 c- ~% n7 A# s$ R0 `  t
  67.    (vlax-safearray-get-element
    ; c7 G8 ]4 k3 r: l6 R, d. L
  68.      (vlax-variant-value c2)
    ! Y; S! ^+ z6 C) a' w( a2 I
  69.      (* j 3)
    7 n; L1 p: R/ |' ~( o
  70.    )6 N, z: o" j8 x, U  d5 d% _
  71.    (vlax-safearray-get-element
    8 K) F9 W# f& G! c* h" p8 O
  72.      (vlax-variant-value c2)# S, u& Z7 H/ U- E7 ]
  73.      (+ (* j 3) 1)
      A, _' d6 I& W: |+ I, p
  74.    )
    $ v5 G# H7 z; k4 C; C5 r
  75.    (vlax-safearray-get-element2 c7 f) A) {  L3 t1 E4 t' l8 k
  76.      (vlax-variant-value c2)
    5 }  u. x1 H) Q6 ^
  77.      (+ (* j 3) 2)
    0 f; C+ f, g. M
  78.    )
    . o9 N, Q: C$ W5 t2 e
  79.         )' ^/ d4 T- K3 N& H# u( e: i, b
  80.       ), R4 x% F! [" F9 J
  81.      )4 g% C% H$ z2 q7 g6 r5 N1 M
  82.      (if dmin   ;检查最小距离是否为 nil (是否首次)% |- ~, q; }5 d7 _- f$ U
  83.        (if (> dmin d)  ;不是首次,比较计算所得的距离与已保存的最小距离,如发现更小的距离则保存# Z, z4 Y2 B* ~, v, W3 q9 X2 M
  84.   (setq dmin d)
    . [$ C3 {! ?. X6 ~
  85.        )$ h4 z! S/ F1 C( b$ a8 O
  86.        (setq dmin d)  ;首次,把首个距离记录为最小距离2 `+ o3 v3 c' H1 s* v( V6 Q
  87.      )
    * F3 P9 \- m- S; P, l( z
  88.      (setq j (1+ j))  ;内层循环变量递增
    : `$ P: h2 F. U0 B
  89.   )
    5 t& z# t+ w4 a
  90.   (setq i (1+ i))  ;外层循环变量递增& {; ~2 {* B0 h8 L7 Y
  91.       )3 C" U( J$ d+ |. L5 u$ X
  92.     )
    0 ?. f9 b/ D7 [8 ?
  93.   )
    - M' p  G  I9 g0 O) O
  94.   (vla-delete ss)   ;用 vla- 前缀函数调用 ss 集合的 delete 方法,删除用过的选择集
    2 X4 S! ?7 G& `. L
  95.   (princ dmin)    ;命令行输出计算结果
    2 @5 q! Z+ ~5 N2 r" {3 m1 E2 o( q9 _
  96.   (princ)    ;静默退出: E3 \' W( V! [7 }2 o
  97. )
    % X& a6 e) `+ l: |' Z
复制代码
发表于 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 )

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