QQ登录

只需一步,快速开始

登录 | 注册 | 找回密码

三维网

 找回密码
 注册

QQ登录

只需一步,快速开始

展开

通知     

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

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

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

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

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

x
本帖最后由 tataki 于 2011-7-30 07:13 编辑 ; T- y2 R8 B% P, n
8 P) q, k# `2 o# p
各位好,最近遇到一个问题,在cad中做了两个闭合的三维spline,我是想算一算他们两者最近的距离是多少,当然不用负责的公式就算,就想着用最直观,也是很简单的方法来计算。见附图。1 c2 m8 `' [1 q" z) B
我的想法是在红色spline上将这条曲线上的每个点计算到蓝色曲线上的每个点距离,也就是一个二次循环,最后找出最小值就行。然而在操作中遇到了两个问题:
4 g0 l+ o7 y. M; b& s9 s5 N1.在spline的图元了保存的控制点坐标怎么提取出来?以前只提过其中的一项,现在面对这几百个数据不知道该怎么提取了。  {$ C2 n" d, Z9 {9 b) G
2.提取的数据怎么存放呢?我以前是学c++的,在C里面肯定用个数组循环就行了,但是不怎么会lisp,在lisp里面没有数组的概念,因此怎么存大量数据,还有后期的怎么读取都让我很迷惑,请各位懂得朋友帮个忙。在网上也找到了几个提spline坐标的程序,可是里面使用vl那些命令,这个我不知道怎么用,也没法修改成我想要的,哪位高手能帮下我,非常感谢!! M9 y# @& z" l/ y
现附上 这两条曲线的dwg文件。9 W8 C, d. b& ]1 V3 @2 p' z
2011-7-29 19-17-21.jpg
/ ]7 Q" z7 X. t* c- G& w1 k+ Y9 F3 T5 K$ B
今早一打开我的帖子,就看到斑竹的答复!很激动,没想到这么快就回复了!/ Y* G* N) y6 p  E2 T- D
非常感谢斑竹的帮助!不但给出了源代码,还有详细的注解,斑竹的认真热心和负责让我肃然起敬,以前的我提的几个问题也是斑竹给解决的。刚
看了一下发帖时间,半夜02:53....看到这个时间,明白人心理都懂得,再多赞美的词也显得苍白了....' H1 D1 Q: |" i5 k8 I# b$ s& a
辛苦斑竹了,今天周末请多休息!

spline.dwg

172.45 KB, 下载次数: 8

发表于 2011-7-30 02:53:11 | 显示全部楼层 来自: 中国辽宁
本帖最后由 woaishuijia 于 2011-8-4 09:43 编辑 # @- e, T* n' _* c& T9 a$ ]0 r0 |

  1. # I& m! H( y: t5 j# `: E% y
  2. (defun c:aaa (/ ss ft fd c1 c2 i j dmin d)
    2 B( W/ u* D. D  T; U
  3.   (vl-load-com)    ;将 Visual LISP 扩展功能加载到 AutoLISP % r9 i& B6 O+ D# [$ \
  4.   (setq     ;将一个或多个符号的值设置为相应表达式的值
    2 H: {6 [& F; r7 S6 V
  5.     ss (vla-add    ;用 vla- 前缀函数调用 activeX 对象(下面的代码--该方法的第一个参数--指定的选择集集合对象)的 add 方法
    % D8 P+ K, j, Y3 `3 c% L0 @) @
  6.   (vla-get-selectionsets  ;用 vla-get- 前缀函数获取 activeX 对象--当前文档对象--的属性:选择集集合子对象,即使用 add 方法的集合对象) d( e3 V/ e( c7 O6 W$ f6 l8 e, C
  7.     (vla-get-activedocument ;用 vla-get- 前缀函数获取 activeX 对象--当前 AutoCAD 应用程序对象--的属性:活动文档子对象
    9 j, M% T# T$ y: Z& e2 Q+ X% A
  8.       (vlax-get-acad-object) ;用 vlax-get-acad-object 函数检索当前 AutoCAD 任务中的顶层 AutoCAD 应用程序对象6 y' V7 H7 h3 U
  9.     )% M0 ^9 X: R& N! |. ]3 ~5 B
  10.   )+ Y# q; J# x! Y; ^3 p0 c* b
  11.   "ss"    ;选择集名称- v" @. H+ d4 A; O9 a
  12.        )4 o1 j5 D) \- e! s4 a. z& }0 ]$ ]
  13.     ft (vlax-make-safearray vlax-vbinteger '(0 . 0))
    2 Q" X% ?/ O$ w2 O, F) Z  U
  14.      ;定义选择集过滤器的过滤类型数组.用 vlax-make-safearray 函数创建安全数组,整形,一维,一个元素(0 to 0).
    3 e( \) T4 P2 U% t5 a
  15.     fd (vlax-make-safearray vlax-vbvariant '(0 . 0))# b% K4 p9 ]$ O0 o
  16.      ;定义选择集过滤器的过滤值数组.用 vlax-make-safearray 函数创建安全数组,变体,一维,一个元素(0 to 0).7 ?) O& r5 K4 y/ M  {' r
  17.   )
    $ {7 z3 G" I$ {9 I, f; [$ @
  18.   (vlax-safearray-put-element fd 0 "spline" )
    4 f! D6 p& z$ p& _; q( y2 P, A
  19.      ;用 vlax-safearray-put-element 函数为数组 fd 的第一个元素(索引号 0)赋值"spline"
    9 ]. j, G9 C6 g* w0 |* U3 o3 b
  20.   (vla-selectonscreen ss ft fd)  ;用 vla- 前缀函数调用 ss 对象的 selectonscreen 方法,由用户在屏幕上选取样条曲线对象8 v6 a. W( V: k5 n
  21.   (if (= (vla-get-count ss) 2)  ;如果 ss 集合的 count 属性等于2(即用户选择了两条曲线)则执行下面的代码1 ~/ {5 X8 k: b8 a0 |
  22.     (progn3 p6 Z5 X5 r! Z; B, t$ e
  23.       (setq c1 (vla-get-controlpoints ;用 vla-get- 前缀函数获取样条曲线对象的控制点坐标数组并赋值给c1(变量类型为变体,值为双精度数组)7 M* x+ N. u" E5 C- n5 J( M
  24.    (vla-item ss 0) ;用 vla- 前缀函数调用集合对象的 item 方法,获取选择集中的索引号为 0 的样条曲线对象
    ' C: y7 Q$ L* ^2 O" {
  25.         )
    ; i/ u- l* [, H/ s( w% r& |
  26.      c2 (vla-get-controlpoints ;用 vla-get- 前缀函数获取样条曲线对象的控制点坐标数组并赋值给c2(变量类型为变体,值为双精度数组), v5 d* @# \% x  L
  27.    (vla-item ss 1) ;用 vla- 前缀函数调用集合对象的 item 方法,获取选择集中的索引号为 1 的样条曲线对象
    / {& W: A& h% n9 w; l2 j
  28.         )
    % a5 M  ^, Y. H
  29.      i  0   ;初始化外层循环变量4 ^, W1 Z# j: }0 I9 @
  30.       ). r7 z9 X; ]% R( }( h" @
  31.       (repeat    ;循环,外层" F4 p- P( ^- B' p* x" u0 b
  32. (/ (1+ (vlax-safearray-get-u-bound
    9 B+ X, B3 a1 n6 P' q
  33.      ;用 vlax-safearray-get-u-bound 函数获取数组最大下标.第一个参数是数组,第二个参数是维数
    & ]/ v3 ~- k/ J
  34.    (vlax-variant-value c1);用 vlax-variant-value 函数获取变体变量 c1 的值(双精度数组)
    2 w- K# U0 r, m/ Y. }7 F+ w2 A
  35.    1
    2 P3 R3 n/ p# p9 e* ?5 J
  36.         )3 w. q2 }% i$ z- O) A: u; r
  37.     )
    # l3 ^2 h* X: G' O( d" V( ]* b0 N
  38.     3+ g; O) j" `" ^
  39. )    ;用数组最大下标加1再除以3,所得结果做为循环次数--数组中每三个元素为一组代表一个控制点. S" z: y7 C* d/ U
  40.   (setq j 0)   ;初始化内层循环变量
    3 U* d6 o3 B7 z2 N" u
  41.   (repeat: {- W- J& q) ]8 a% h
  42.     (/ (1+ (vlax-safearray-get-u-bound. k2 N% g* D. t+ j1 L6 h0 f# Y
  43.      ;第二条样条曲线控制点坐标数组的最大下标加1再除以3,做为内层循环次数
    5 C' x$ o; @, k0 }) E' a( S
  44.       (vlax-variant-value c2)
    9 R/ E' q! Q8 G7 B5 x
  45.       1' U% [* o: G# J' u/ A1 H# N
  46.     )$ [* }0 _1 K* f- f% l4 s
  47.        )
    8 @2 o$ k0 v2 r) |3 S/ ?+ O* x
  48.        32 z5 ^! q/ `: s9 t) d6 Y5 v. o
  49.     )# I; s- I4 e% Z( I! S* F  p
  50.      (setq d (distance  ;计算第一条曲线索引号为 i 的控制点到第二条曲线索引号为 j 的控制点之间的三维距离
    4 A( }: T+ F* w( c: e1 s7 R0 D
  51.         (list  ;从 c1 数组中取出第一条曲线索引号为 i 的控制点的点表) z0 ?; G) p' |2 x
  52.    (vlax-safearray-get-element
    7 j' f5 D" G2 c$ q( ~5 p7 V0 R1 ^
  53.      ;用 vlax-safearray-get-element 函数获取数组中的指定的元素
    ) c; W5 V7 v+ M8 c* R; M; `
  54.      (vlax-variant-value c1) ;数组
    8 p" I0 ^) M, ?. E. k  N
  55.      (* i 3) ;数组元素下标  ]* `7 o% U3 T7 E3 }* D
  56.    )4 p( v7 i% ]7 B
  57.    (vlax-safearray-get-element; s1 u) x9 p* ~/ V$ g) A
  58.      (vlax-variant-value c1)( U" Z% p- m' A) k1 y3 Q
  59.      (+ (* i 3) 1)9 b, N$ Z* u! a: \3 ~  Q. J0 V
  60.    )1 i: B) ~! A8 B% A, T
  61.    (vlax-safearray-get-element+ B3 |* R' x- t, G' i% r
  62.      (vlax-variant-value c1)  o  H" t4 `) l  I1 N4 M6 k
  63.      (+ (* i 3) 2)
    6 T6 b3 P, z! j" G
  64.    ); F' G7 V$ d  d, f
  65.         )
    1 v6 O$ b! D7 Y  P" Z
  66.         (list  ;从 c2 数组中取出第二条曲线索引号为 j 的控制点的点表
    $ I# |: I7 n+ q2 b/ Q: d. y
  67.    (vlax-safearray-get-element8 ^; r! Y  W$ v. a: R# d" f( y7 q+ K, a
  68.      (vlax-variant-value c2)$ p0 Q& L. C1 A, t
  69.      (* j 3)% {5 V. }/ J  N' d4 S" U/ d
  70.    )7 Z. Y! W3 m8 X: u
  71.    (vlax-safearray-get-element
    8 L, b& g0 S( G" ~0 H
  72.      (vlax-variant-value c2)
    ! ~. T3 p3 s# q
  73.      (+ (* j 3) 1)/ n, n6 N3 h0 ^
  74.    )
    * H+ O3 c4 w( [7 N8 N
  75.    (vlax-safearray-get-element
    * F( {- g8 s, q, ^
  76.      (vlax-variant-value c2)& q4 L  h2 P9 m
  77.      (+ (* j 3) 2)4 {" o7 X- T5 M# R
  78.    )
    ! B) E5 ]7 \% r# @& T) q! T4 z
  79.         )
    3 l5 _1 z6 D5 P! n
  80.       )
    8 g9 Y+ L! C2 H# P+ n/ G
  81.      )
    3 {# m( S5 ?- ~; o- D# U( B" Y
  82.      (if dmin   ;检查最小距离是否为 nil (是否首次)6 s1 X( f- l6 L: S: S/ I
  83.        (if (> dmin d)  ;不是首次,比较计算所得的距离与已保存的最小距离,如发现更小的距离则保存
    5 n  v: Z2 l" b% H4 }
  84.   (setq dmin d)
    ( D$ o3 F* Q/ w  f/ S$ d' m7 R
  85.        )
    + ~: P& @$ v. _& n: R% L+ S/ \
  86.        (setq dmin d)  ;首次,把首个距离记录为最小距离
    8 q. v/ I( u0 Y6 n
  87.      )
    2 a7 H- _: P5 _9 I  }
  88.      (setq j (1+ j))  ;内层循环变量递增6 T. X& R' P. I1 J* U6 t5 K
  89.   )" c4 \2 a; @6 E- G0 d
  90.   (setq i (1+ i))  ;外层循环变量递增
      ?4 D& b. T1 f8 l
  91.       )
    5 I: o4 q# K3 N: E8 j
  92.     )
    ) f$ l  p: e6 v5 _8 ?# {- A+ g& t% e
  93.   )
    / C1 r- u& o' c: k2 l
  94.   (vla-delete ss)   ;用 vla- 前缀函数调用 ss 集合的 delete 方法,删除用过的选择集
    3 f& c9 c9 ^- Z- z, s' W, g' Y
  95.   (princ dmin)    ;命令行输出计算结果( O  W8 e  A9 e: }- l
  96.   (princ)    ;静默退出
    ! L& Q% D% U2 L3 E8 h6 x% T" k1 `, s1 F
  97. ): R7 o4 t4 o3 d8 B: y( _$ W4 g$ V: @
复制代码
发表于 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 )

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