QQ登录

只需一步,快速开始

登录 | 注册 | 找回密码

三维网

 找回密码
 注册

QQ登录

只需一步,快速开始

展开

通知     

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

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

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

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

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

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

spline.dwg

172.45 KB, 下载次数: 8

发表于 2011-7-30 02:53:11 | 显示全部楼层 来自: 中国辽宁
本帖最后由 woaishuijia 于 2011-8-4 09:43 编辑 3 z0 `; ]9 \7 m' D7 d( m
  1. / `+ K7 _( B5 |& |
  2. (defun c:aaa (/ ss ft fd c1 c2 i j dmin d)
    " K/ t2 o1 W, t5 `$ k9 q
  3.   (vl-load-com)    ;将 Visual LISP 扩展功能加载到 AutoLISP
    ( g6 W$ X+ ^7 _$ d8 `9 \8 r$ u4 x
  4.   (setq     ;将一个或多个符号的值设置为相应表达式的值, \. \/ K4 m0 s$ ?8 Y2 Q
  5.     ss (vla-add    ;用 vla- 前缀函数调用 activeX 对象(下面的代码--该方法的第一个参数--指定的选择集集合对象)的 add 方法
    2 M- F4 S. N/ e$ x
  6.   (vla-get-selectionsets  ;用 vla-get- 前缀函数获取 activeX 对象--当前文档对象--的属性:选择集集合子对象,即使用 add 方法的集合对象4 x8 ?& Z; q! b. i$ `& Z, ?
  7.     (vla-get-activedocument ;用 vla-get- 前缀函数获取 activeX 对象--当前 AutoCAD 应用程序对象--的属性:活动文档子对象
    / z* e8 B$ F2 t9 S
  8.       (vlax-get-acad-object) ;用 vlax-get-acad-object 函数检索当前 AutoCAD 任务中的顶层 AutoCAD 应用程序对象3 M% K" R; }2 j9 A  u* u  ]* u
  9.     )
    ! [, X6 T. I2 p# v8 Q
  10.   )
    8 R4 C5 A0 z5 T: i
  11.   "ss"    ;选择集名称% |( i, T2 Z6 O. m# R. p: j% C
  12.        )
    * m6 f3 ]* t, [( R3 o+ R
  13.     ft (vlax-make-safearray vlax-vbinteger '(0 . 0))$ v- P9 y+ s5 ], p6 b6 r
  14.      ;定义选择集过滤器的过滤类型数组.用 vlax-make-safearray 函数创建安全数组,整形,一维,一个元素(0 to 0).
    3 j. u2 i8 ]5 _) f
  15.     fd (vlax-make-safearray vlax-vbvariant '(0 . 0))
    # [( p# E  S. l- D2 r  {
  16.      ;定义选择集过滤器的过滤值数组.用 vlax-make-safearray 函数创建安全数组,变体,一维,一个元素(0 to 0).
    9 S  ?6 X, Q/ t4 s1 C% R( [* C+ Z
  17.   )
    9 I* ~. w7 F0 O4 K4 H/ \2 x  R; d; J
  18.   (vlax-safearray-put-element fd 0 "spline" )6 m' Q2 _/ T% C0 I% i: x, g
  19.      ;用 vlax-safearray-put-element 函数为数组 fd 的第一个元素(索引号 0)赋值"spline"
    2 @' W2 e( M# y2 g8 v1 I
  20.   (vla-selectonscreen ss ft fd)  ;用 vla- 前缀函数调用 ss 对象的 selectonscreen 方法,由用户在屏幕上选取样条曲线对象/ N+ M; J( V' q+ ]7 @! T1 g! s
  21.   (if (= (vla-get-count ss) 2)  ;如果 ss 集合的 count 属性等于2(即用户选择了两条曲线)则执行下面的代码
    - D7 K( P# F5 _/ W: c3 Z
  22.     (progn/ o; [& {: V; Z( ~. N. B/ R7 ]
  23.       (setq c1 (vla-get-controlpoints ;用 vla-get- 前缀函数获取样条曲线对象的控制点坐标数组并赋值给c1(变量类型为变体,值为双精度数组)
    8 q7 o7 z% M2 \
  24.    (vla-item ss 0) ;用 vla- 前缀函数调用集合对象的 item 方法,获取选择集中的索引号为 0 的样条曲线对象9 e* E1 y7 _* M; s- Y
  25.         )
    % o: d1 V# Y0 s  u) {2 E
  26.      c2 (vla-get-controlpoints ;用 vla-get- 前缀函数获取样条曲线对象的控制点坐标数组并赋值给c2(变量类型为变体,值为双精度数组)
    0 L5 g5 `' }( v5 p6 G1 F
  27.    (vla-item ss 1) ;用 vla- 前缀函数调用集合对象的 item 方法,获取选择集中的索引号为 1 的样条曲线对象
    4 H8 H; U) |- L& ^
  28.         )
    8 o6 K9 f6 q3 ]* }- i/ R
  29.      i  0   ;初始化外层循环变量: c% J( ]% ~$ W/ n: ~0 [
  30.       )# [6 B2 e( [% W- p- r& @* V6 y% Q- i# ?
  31.       (repeat    ;循环,外层
    0 [6 [7 I  B* P& `, T/ d* y
  32. (/ (1+ (vlax-safearray-get-u-bound
    - F) c$ @8 t7 U/ p: ^
  33.      ;用 vlax-safearray-get-u-bound 函数获取数组最大下标.第一个参数是数组,第二个参数是维数9 Y! U- Q# p. N1 A$ ~5 `* Y8 ]
  34.    (vlax-variant-value c1);用 vlax-variant-value 函数获取变体变量 c1 的值(双精度数组); |8 t% A* R; E. h9 s# x
  35.    1
    ) t- R6 Y+ ~6 Z
  36.         )5 V4 a& e! v' |+ u0 q0 y" l
  37.     )& i1 ^' }" x. `/ W; T
  38.     3
    % g1 e5 x" `  e/ R
  39. )    ;用数组最大下标加1再除以3,所得结果做为循环次数--数组中每三个元素为一组代表一个控制点1 \* [5 x7 g' P* X
  40.   (setq j 0)   ;初始化内层循环变量4 A- @. G$ l, r8 {: n* \8 w
  41.   (repeat
      e9 r# N7 v1 L( Y
  42.     (/ (1+ (vlax-safearray-get-u-bound3 X$ i; Q+ r9 G
  43.      ;第二条样条曲线控制点坐标数组的最大下标加1再除以3,做为内层循环次数
    ) G- |7 J8 D1 t. y( a' y( O0 K3 t7 n
  44.       (vlax-variant-value c2)0 i) _6 u* H* k
  45.       1% F4 F- ~: e8 G. y
  46.     )
    2 |" ~0 d+ b, B* z; E
  47.        )
    : x) u" J/ H& v: c; n7 e% @
  48.        3
    , A* w' t- e2 D3 Z; y- J0 h% u
  49.     )* o* W  U7 {# ^6 U4 a) c
  50.      (setq d (distance  ;计算第一条曲线索引号为 i 的控制点到第二条曲线索引号为 j 的控制点之间的三维距离
    + ]5 x& z! ?4 p) x7 w2 j9 ~" o
  51.         (list  ;从 c1 数组中取出第一条曲线索引号为 i 的控制点的点表" v( V6 X5 m  A$ W' o8 s! X7 @  J6 l
  52.    (vlax-safearray-get-element+ v3 p$ L* M' Y
  53.      ;用 vlax-safearray-get-element 函数获取数组中的指定的元素
    , l8 i* y/ K) a
  54.      (vlax-variant-value c1) ;数组% g2 v( t6 c' |' Z# @3 b. {! S
  55.      (* i 3) ;数组元素下标% g$ p7 q4 M& M# f* W- A
  56.    )' n! V: y: z$ J% d  J
  57.    (vlax-safearray-get-element6 ~( q$ }+ a) v4 a3 S2 c! T1 ~
  58.      (vlax-variant-value c1)
    / G5 P% [3 s+ N# P
  59.      (+ (* i 3) 1)- C. `6 A$ ]6 d+ j- b7 f
  60.    )
    2 _8 S3 [1 {4 h& _, M4 Q' v
  61.    (vlax-safearray-get-element) f5 X' l, h0 K. p2 |
  62.      (vlax-variant-value c1)( p0 l* N5 f( M
  63.      (+ (* i 3) 2)6 ?. r2 Z; e7 m6 K# r
  64.    )
    ' f+ d4 ]7 @% j/ |( S+ e1 Q& W
  65.         )+ m/ X3 \1 `3 K; J' l# L# `
  66.         (list  ;从 c2 数组中取出第二条曲线索引号为 j 的控制点的点表
    1 K( d; l' q1 R: w" I+ u/ A
  67.    (vlax-safearray-get-element
    ) j: S  `' K* a+ ~
  68.      (vlax-variant-value c2)- ]4 Q: R1 [) N8 X7 V2 ^: J/ A% p
  69.      (* j 3)
    ; o6 y( @, n7 L& g$ P
  70.    )
    " M, Y! w* b# L% H0 Q+ Q
  71.    (vlax-safearray-get-element
    $ Z9 t% h3 m/ E
  72.      (vlax-variant-value c2)% _* p. x! P6 q# T4 [! G; t
  73.      (+ (* j 3) 1)3 p& D" L$ v  h* x' l8 ~" p$ j
  74.    )# [. D4 u6 W# X7 `7 i7 H
  75.    (vlax-safearray-get-element- J4 d* }% [. U: Q7 f1 H! t
  76.      (vlax-variant-value c2)1 A- ]5 _4 N- O* ^: y
  77.      (+ (* j 3) 2)
    3 g  f) a3 O* S# W0 X
  78.    )9 ~$ V9 l7 E% ]
  79.         )
    ) r& P4 j5 p  T8 k5 \; h- V* C
  80.       )/ y( j! O/ S; t: _
  81.      )  d- S  ~5 B' s
  82.      (if dmin   ;检查最小距离是否为 nil (是否首次)
    0 i  A- z$ X' x, g, s+ ~
  83.        (if (> dmin d)  ;不是首次,比较计算所得的距离与已保存的最小距离,如发现更小的距离则保存
    7 @4 c, y: Q0 u
  84.   (setq dmin d)! o' \1 w% h  ?* J+ b1 F
  85.        )+ C5 f+ F) p3 o4 K& T( i
  86.        (setq dmin d)  ;首次,把首个距离记录为最小距离/ F. m+ J: u  _. \2 `
  87.      )
    ( T* @9 U0 `2 g! P
  88.      (setq j (1+ j))  ;内层循环变量递增0 o: [8 w+ {5 ]
  89.   )3 T& }5 A$ Y# [/ ?
  90.   (setq i (1+ i))  ;外层循环变量递增* e% D9 B/ M; f- x- f
  91.       )3 l: ~% c0 V" [% |
  92.     )
    9 K' {% I& S4 m$ z" r% ^( F, P
  93.   )& r. E* J$ k4 e- w+ l) ^8 l+ E
  94.   (vla-delete ss)   ;用 vla- 前缀函数调用 ss 集合的 delete 方法,删除用过的选择集* h/ Z6 g3 x/ ?# ?8 d/ T  g0 H3 P
  95.   (princ dmin)    ;命令行输出计算结果& n0 G3 M6 }+ x* T: c% n& t
  96.   (princ)    ;静默退出
    " K2 o* K+ j' N2 W
  97. )- Q1 A) C2 j- u: ]6 ~
复制代码
发表于 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 )

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