QQ登录

只需一步,快速开始

登录 | 注册 | 找回密码

三维网

 找回密码
 注册

QQ登录

只需一步,快速开始

展开

通知     

全站
7天前
查看: 4755|回复: 4
收起左侧

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

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

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

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

x
本帖最后由 tataki 于 2011-7-30 07:13 编辑 9 l  G# `8 Q0 d& V0 r

: Q. Y. i! _/ @, B3 T* W: j. U3 m各位好,最近遇到一个问题,在cad中做了两个闭合的三维spline,我是想算一算他们两者最近的距离是多少,当然不用负责的公式就算,就想着用最直观,也是很简单的方法来计算。见附图。
2 w# J+ ?* }) x& H7 F" @6 l, o我的想法是在红色spline上将这条曲线上的每个点计算到蓝色曲线上的每个点距离,也就是一个二次循环,最后找出最小值就行。然而在操作中遇到了两个问题:7 G$ [5 a$ h- g
1.在spline的图元了保存的控制点坐标怎么提取出来?以前只提过其中的一项,现在面对这几百个数据不知道该怎么提取了。
' G$ C$ R5 }+ }/ c) r( l2.提取的数据怎么存放呢?我以前是学c++的,在C里面肯定用个数组循环就行了,但是不怎么会lisp,在lisp里面没有数组的概念,因此怎么存大量数据,还有后期的怎么读取都让我很迷惑,请各位懂得朋友帮个忙。在网上也找到了几个提spline坐标的程序,可是里面使用vl那些命令,这个我不知道怎么用,也没法修改成我想要的,哪位高手能帮下我,非常感谢!
$ y9 b7 s2 [6 F& H' M现附上 这两条曲线的dwg文件。
: V# f% T+ e: G2 A 2011-7-29 19-17-21.jpg : C7 k& S/ W, }; q$ s8 H) N* I# f4 B
$ b$ a" J; k0 T3 _
今早一打开我的帖子,就看到斑竹的答复!很激动,没想到这么快就回复了!1 K: x4 J( S& b8 }
非常感谢斑竹的帮助!不但给出了源代码,还有详细的注解,斑竹的认真热心和负责让我肃然起敬,以前的我提的几个问题也是斑竹给解决的。刚
看了一下发帖时间,半夜02:53....看到这个时间,明白人心理都懂得,再多赞美的词也显得苍白了....
- o9 ]; T8 C0 v7 h2 `- u$ E辛苦斑竹了,今天周末请多休息!

spline.dwg

172.45 KB, 下载次数: 8

发表于 2011-7-30 02:53:11 | 显示全部楼层 来自: 中国辽宁
本帖最后由 woaishuijia 于 2011-8-4 09:43 编辑
& O) s% d1 e9 U4 W1 {2 X. I& q0 k

  1. 0 O& U3 M' p' G+ L& N) n
  2. (defun c:aaa (/ ss ft fd c1 c2 i j dmin d)' U5 c1 F, n8 a& R' T: \
  3.   (vl-load-com)    ;将 Visual LISP 扩展功能加载到 AutoLISP " y% S& P& k. f
  4.   (setq     ;将一个或多个符号的值设置为相应表达式的值4 a" X' ?, g: F9 @$ Y1 ~
  5.     ss (vla-add    ;用 vla- 前缀函数调用 activeX 对象(下面的代码--该方法的第一个参数--指定的选择集集合对象)的 add 方法% }8 f0 L* J2 F9 W0 |4 c
  6.   (vla-get-selectionsets  ;用 vla-get- 前缀函数获取 activeX 对象--当前文档对象--的属性:选择集集合子对象,即使用 add 方法的集合对象8 V( e' T) k* O" \5 [" M, X
  7.     (vla-get-activedocument ;用 vla-get- 前缀函数获取 activeX 对象--当前 AutoCAD 应用程序对象--的属性:活动文档子对象
    , ^6 u, y' N9 a+ A$ K4 }; Y6 d
  8.       (vlax-get-acad-object) ;用 vlax-get-acad-object 函数检索当前 AutoCAD 任务中的顶层 AutoCAD 应用程序对象
    ; s. m2 j7 i% H8 u
  9.     )8 w. \2 @7 @& W3 e0 ?2 p# n. c* Y; ?
  10.   )$ r. G0 X8 ~! e% i5 |
  11.   "ss"    ;选择集名称1 l+ D7 L! D# ]
  12.        )- ]3 V- `7 Z6 D- d. w7 C
  13.     ft (vlax-make-safearray vlax-vbinteger '(0 . 0))# @& i$ e8 L7 u/ u7 U, j
  14.      ;定义选择集过滤器的过滤类型数组.用 vlax-make-safearray 函数创建安全数组,整形,一维,一个元素(0 to 0).
    9 {: j. C# F: X3 Y& v; \9 u- W
  15.     fd (vlax-make-safearray vlax-vbvariant '(0 . 0))& c# M: y. F) K9 K  f- d. `2 @
  16.      ;定义选择集过滤器的过滤值数组.用 vlax-make-safearray 函数创建安全数组,变体,一维,一个元素(0 to 0).
    . V1 p; w2 U7 Z0 W' C- L& ^
  17.   )
    + C' L6 u2 z- [; M
  18.   (vlax-safearray-put-element fd 0 "spline" )3 T0 k1 D8 w0 F" f; g
  19.      ;用 vlax-safearray-put-element 函数为数组 fd 的第一个元素(索引号 0)赋值"spline": {1 L5 S8 \! K
  20.   (vla-selectonscreen ss ft fd)  ;用 vla- 前缀函数调用 ss 对象的 selectonscreen 方法,由用户在屏幕上选取样条曲线对象. y+ W" u7 \8 _8 ^
  21.   (if (= (vla-get-count ss) 2)  ;如果 ss 集合的 count 属性等于2(即用户选择了两条曲线)则执行下面的代码% D% O3 |7 O1 A2 s
  22.     (progn
    . \% B8 h. H3 g# `& U
  23.       (setq c1 (vla-get-controlpoints ;用 vla-get- 前缀函数获取样条曲线对象的控制点坐标数组并赋值给c1(变量类型为变体,值为双精度数组)
    2 ^" m( j# J6 l. o7 e+ l
  24.    (vla-item ss 0) ;用 vla- 前缀函数调用集合对象的 item 方法,获取选择集中的索引号为 0 的样条曲线对象7 R. J$ |0 T; z4 I
  25.         )
    . x+ |7 N. V- y- O
  26.      c2 (vla-get-controlpoints ;用 vla-get- 前缀函数获取样条曲线对象的控制点坐标数组并赋值给c2(变量类型为变体,值为双精度数组)
    0 ~+ n. E, p6 @; g" D
  27.    (vla-item ss 1) ;用 vla- 前缀函数调用集合对象的 item 方法,获取选择集中的索引号为 1 的样条曲线对象9 w2 Z, U" D$ K+ i8 U/ g7 e
  28.         ): a7 a1 \7 r1 Z# n5 A; U! G) |+ G
  29.      i  0   ;初始化外层循环变量
    7 ^: j! F# a& W3 h* S/ T. n" c
  30.       )- e' m* E6 M9 a5 z% |5 B8 _: d
  31.       (repeat    ;循环,外层; n& G  t/ E* A' @: e; L
  32. (/ (1+ (vlax-safearray-get-u-bound
    / Y+ L* ~' Y; ^- |
  33.      ;用 vlax-safearray-get-u-bound 函数获取数组最大下标.第一个参数是数组,第二个参数是维数' u  }" W5 \, e( s
  34.    (vlax-variant-value c1);用 vlax-variant-value 函数获取变体变量 c1 的值(双精度数组)5 C( E0 y7 a% I8 c/ y- g
  35.    11 t% z* w0 u- J" ^4 G
  36.         )- [! s  y  F# i8 v5 ^" L- i
  37.     )! c! H# C; n* T6 Y
  38.     3
    7 ~) |5 Z9 E) N$ |
  39. )    ;用数组最大下标加1再除以3,所得结果做为循环次数--数组中每三个元素为一组代表一个控制点
    $ r9 N  k" w4 W4 c
  40.   (setq j 0)   ;初始化内层循环变量
    7 s5 N2 P( K0 k* {1 D' W
  41.   (repeat
    ) t" v: h" r) [/ J
  42.     (/ (1+ (vlax-safearray-get-u-bound
      A* H8 V9 e, F# @' W; E
  43.      ;第二条样条曲线控制点坐标数组的最大下标加1再除以3,做为内层循环次数7 p$ L8 Y3 W& x" R  ?8 u$ |. D
  44.       (vlax-variant-value c2)( H, u/ j: S0 }( A- K/ }
  45.       1
    / k7 s# ~, y! `. R, H$ N
  46.     )7 s5 S2 E  e$ n" H# F9 l. L
  47.        )0 u2 M' v0 h. B
  48.        3
    9 }9 P1 t; t' {! j5 ?, U! C8 y2 g" h
  49.     )" k5 G  D3 x  L, [. k' }
  50.      (setq d (distance  ;计算第一条曲线索引号为 i 的控制点到第二条曲线索引号为 j 的控制点之间的三维距离
    + p9 r' ]8 z3 b6 m5 G! F' k' c
  51.         (list  ;从 c1 数组中取出第一条曲线索引号为 i 的控制点的点表
    ( \: Y' g3 k$ O4 R* f* y5 R* y
  52.    (vlax-safearray-get-element
    5 y/ d) M0 ?7 N# A$ X4 l3 [* K# E
  53.      ;用 vlax-safearray-get-element 函数获取数组中的指定的元素
    ! [/ c, ~- p- c' C1 ]% J5 S* f! \
  54.      (vlax-variant-value c1) ;数组
    ( Z8 i# W# ?5 \+ h9 Z) M, T) i
  55.      (* i 3) ;数组元素下标* N7 m: `( ]* ^) O- {$ b
  56.    )
    - g: J. C% X7 V9 g! b  @) W  B4 S
  57.    (vlax-safearray-get-element' F: w# I: `& u+ W1 H7 o
  58.      (vlax-variant-value c1)
    . G0 i; A* F$ S9 {2 t; }
  59.      (+ (* i 3) 1)& ~$ P: O/ W# g
  60.    )
    5 K. d" x% ?9 ~; _7 D0 E
  61.    (vlax-safearray-get-element) |! M, A/ z6 u( n- d& k, }/ Q  [
  62.      (vlax-variant-value c1)
    6 f) S) j( {7 e, ?( ?( T& o
  63.      (+ (* i 3) 2)) P* Y% s  b. L7 G- C# j( @: r
  64.    )' @) u, o5 R5 G+ y( A- l
  65.         ): r# j: D7 |- V. C  Q: d
  66.         (list  ;从 c2 数组中取出第二条曲线索引号为 j 的控制点的点表
      d6 n( v8 o- D' p6 h" g' b
  67.    (vlax-safearray-get-element
    , V6 ?  O4 t7 U7 ?
  68.      (vlax-variant-value c2)
    4 c% P! |* X2 R+ M. ^0 K
  69.      (* j 3)
    5 i$ D. B& B7 S+ }6 q: L
  70.    )
    . D* R. O4 T! h+ q- t
  71.    (vlax-safearray-get-element; E0 H' t1 H7 I6 b5 m
  72.      (vlax-variant-value c2)
    ( T  h! b: U( {5 d' W
  73.      (+ (* j 3) 1)
    / {/ P' h$ q7 M6 U
  74.    )+ ^3 f0 w  M3 E7 E2 e  \
  75.    (vlax-safearray-get-element
    0 u4 B1 F; Q9 s! J  h5 g  x0 W+ g
  76.      (vlax-variant-value c2)
    1 ^1 Q$ j& w0 S* d& u0 f* ]
  77.      (+ (* j 3) 2); e. {3 A4 y# v
  78.    )
    3 S; J0 ]: \$ }8 [  i
  79.         )
    * a" }! z6 W2 E" f' _% U
  80.       )
    : Z+ j3 V0 a) I3 u( p
  81.      )0 N; K) }( H" D, a# ]( s3 T
  82.      (if dmin   ;检查最小距离是否为 nil (是否首次)
    7 }3 H& ]) K/ R
  83.        (if (> dmin d)  ;不是首次,比较计算所得的距离与已保存的最小距离,如发现更小的距离则保存
    3 H+ P7 A1 p) A) @: s
  84.   (setq dmin d)
    5 N: j. k1 ^7 l
  85.        )
    3 _4 a& o+ y: U4 L" {
  86.        (setq dmin d)  ;首次,把首个距离记录为最小距离' s9 [0 h5 B: K8 A! u5 K2 t, W) m
  87.      ): d+ q; E$ b$ S* `+ F/ \# U
  88.      (setq j (1+ j))  ;内层循环变量递增
    & O0 o$ c5 ^. Q
  89.   )
    0 D9 P+ P/ a3 M) k2 X6 k; y6 G! v
  90.   (setq i (1+ i))  ;外层循环变量递增" K- J" g) v- Z: K4 I5 |7 e
  91.       )- o& p: X6 l( \3 b
  92.     )
    - y1 m7 u& E- ^  l2 `& ^, ~4 l
  93.   )
    : B' ~: k1 o% i- k2 `8 [
  94.   (vla-delete ss)   ;用 vla- 前缀函数调用 ss 集合的 delete 方法,删除用过的选择集
    - Z" X" P0 z6 Z. E) M: f
  95.   (princ dmin)    ;命令行输出计算结果
    - _  G- R) _" g+ t# a% X8 H
  96.   (princ)    ;静默退出$ h# N0 S4 b/ w! ^
  97. )
    ( b3 P2 c) W7 o) H
复制代码
发表于 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 )

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