QQ登录

只需一步,快速开始

登录 | 注册 | 找回密码

三维网

 找回密码
 注册

QQ登录

只需一步,快速开始

展开

通知     

全站
10天前
查看: 4632|回复: 4
收起左侧

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

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

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

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

x
本帖最后由 tataki 于 2011-7-30 07:13 编辑
! ]) H1 h/ i, y. A& l, H- x! w+ p; [6 ]. T& q. [2 s4 T
各位好,最近遇到一个问题,在cad中做了两个闭合的三维spline,我是想算一算他们两者最近的距离是多少,当然不用负责的公式就算,就想着用最直观,也是很简单的方法来计算。见附图。
- S) S$ k. e# |4 G6 N9 B4 V3 F  k我的想法是在红色spline上将这条曲线上的每个点计算到蓝色曲线上的每个点距离,也就是一个二次循环,最后找出最小值就行。然而在操作中遇到了两个问题:
2 K1 ?( s5 O: s* t, i: N1.在spline的图元了保存的控制点坐标怎么提取出来?以前只提过其中的一项,现在面对这几百个数据不知道该怎么提取了。( q: \5 L9 o8 `; j/ [3 P$ ~$ D
2.提取的数据怎么存放呢?我以前是学c++的,在C里面肯定用个数组循环就行了,但是不怎么会lisp,在lisp里面没有数组的概念,因此怎么存大量数据,还有后期的怎么读取都让我很迷惑,请各位懂得朋友帮个忙。在网上也找到了几个提spline坐标的程序,可是里面使用vl那些命令,这个我不知道怎么用,也没法修改成我想要的,哪位高手能帮下我,非常感谢!8 v2 ?' G( j& m! U/ L* h
现附上 这两条曲线的dwg文件。2 }, A% Y. C$ _* M2 ^% ?
2011-7-29 19-17-21.jpg 6 Z' a" }1 a" ~( Y& y

8 i1 p. h- ~7 q3 _; |" ~9 Y& O今早一打开我的帖子,就看到斑竹的答复!很激动,没想到这么快就回复了!
* w# G: b" E3 _+ U+ A非常感谢斑竹的帮助!不但给出了源代码,还有详细的注解,斑竹的认真热心和负责让我肃然起敬,以前的我提的几个问题也是斑竹给解决的。刚
看了一下发帖时间,半夜02:53....看到这个时间,明白人心理都懂得,再多赞美的词也显得苍白了....
3 T# f7 `- J5 Y% o$ K, Y3 c# q辛苦斑竹了,今天周末请多休息!

spline.dwg

172.45 KB, 下载次数: 8

发表于 2011-7-30 02:53:11 | 显示全部楼层 来自: 中国辽宁
本帖最后由 woaishuijia 于 2011-8-4 09:43 编辑
7 d- N; v; M, R% R: R

  1. * W8 z# F) W0 d6 [; e7 c7 R
  2. (defun c:aaa (/ ss ft fd c1 c2 i j dmin d)
    . d; G1 [8 t, Z+ b- \! X
  3.   (vl-load-com)    ;将 Visual LISP 扩展功能加载到 AutoLISP
    8 _9 R) B9 U+ e5 G$ b
  4.   (setq     ;将一个或多个符号的值设置为相应表达式的值5 ?) R4 ]# @* y( \$ T% n" S
  5.     ss (vla-add    ;用 vla- 前缀函数调用 activeX 对象(下面的代码--该方法的第一个参数--指定的选择集集合对象)的 add 方法
    7 h' H; l7 V$ O/ {
  6.   (vla-get-selectionsets  ;用 vla-get- 前缀函数获取 activeX 对象--当前文档对象--的属性:选择集集合子对象,即使用 add 方法的集合对象
    & F( E) ?  G# `* ]0 `: x# F
  7.     (vla-get-activedocument ;用 vla-get- 前缀函数获取 activeX 对象--当前 AutoCAD 应用程序对象--的属性:活动文档子对象. \+ ~% E1 u9 T
  8.       (vlax-get-acad-object) ;用 vlax-get-acad-object 函数检索当前 AutoCAD 任务中的顶层 AutoCAD 应用程序对象
    $ h; J$ Q9 h2 F. q) ~& p/ h& E( n
  9.     )
    : ~) g/ A! f3 P; Q2 B- G
  10.   )
    3 [+ u+ ^$ A0 l) m, m  E2 \
  11.   "ss"    ;选择集名称& D) u( l7 e  ^+ j1 X7 ?( x0 @( w
  12.        )" j  e( R7 E! x+ W1 {
  13.     ft (vlax-make-safearray vlax-vbinteger '(0 . 0))
    3 G3 V. X- q$ y5 E: o
  14.      ;定义选择集过滤器的过滤类型数组.用 vlax-make-safearray 函数创建安全数组,整形,一维,一个元素(0 to 0).: [- E9 |+ \- A( q
  15.     fd (vlax-make-safearray vlax-vbvariant '(0 . 0))( S3 a3 [  Y9 K
  16.      ;定义选择集过滤器的过滤值数组.用 vlax-make-safearray 函数创建安全数组,变体,一维,一个元素(0 to 0).
    $ }6 v5 e. {" c
  17.   )) n# U1 ?! X+ C, D' @& f
  18.   (vlax-safearray-put-element fd 0 "spline" )! i" J5 c) i$ w; p" q8 d+ a: ]: Y- Z
  19.      ;用 vlax-safearray-put-element 函数为数组 fd 的第一个元素(索引号 0)赋值"spline"& q( ?3 \3 ^$ F% k* {% w3 o
  20.   (vla-selectonscreen ss ft fd)  ;用 vla- 前缀函数调用 ss 对象的 selectonscreen 方法,由用户在屏幕上选取样条曲线对象
    , E" S2 i4 }6 q) [. r  q+ n* E
  21.   (if (= (vla-get-count ss) 2)  ;如果 ss 集合的 count 属性等于2(即用户选择了两条曲线)则执行下面的代码1 ]" u6 k9 \" x
  22.     (progn
    5 B5 J, }+ U6 l& d4 W7 a8 f2 t
  23.       (setq c1 (vla-get-controlpoints ;用 vla-get- 前缀函数获取样条曲线对象的控制点坐标数组并赋值给c1(变量类型为变体,值为双精度数组)* U6 h; _9 `, b# j5 U
  24.    (vla-item ss 0) ;用 vla- 前缀函数调用集合对象的 item 方法,获取选择集中的索引号为 0 的样条曲线对象6 n5 C# c# [6 }
  25.         )+ z( M: i$ J& \2 ^, N
  26.      c2 (vla-get-controlpoints ;用 vla-get- 前缀函数获取样条曲线对象的控制点坐标数组并赋值给c2(变量类型为变体,值为双精度数组)
    : y% z( D( S. x8 N. H4 K
  27.    (vla-item ss 1) ;用 vla- 前缀函数调用集合对象的 item 方法,获取选择集中的索引号为 1 的样条曲线对象' w) M- S1 G- \: T% u5 U
  28.         )
    ) \8 f5 a' J2 m" N' b
  29.      i  0   ;初始化外层循环变量
    , F# u$ B! e1 o& m3 r' |8 O
  30.       )
    2 E/ r) K1 G2 p$ V8 a) E
  31.       (repeat    ;循环,外层
    0 u0 |0 _8 P3 {
  32. (/ (1+ (vlax-safearray-get-u-bound7 P: c' W" o# C7 z8 Z5 ]
  33.      ;用 vlax-safearray-get-u-bound 函数获取数组最大下标.第一个参数是数组,第二个参数是维数
    ! I1 Y, v& Y8 u
  34.    (vlax-variant-value c1);用 vlax-variant-value 函数获取变体变量 c1 的值(双精度数组)
    5 t5 ~4 i# b) H. Z3 o
  35.    1' Q1 z5 Y* C6 F5 R) s- \! X( h
  36.         )4 l6 ?6 f' B- }+ E
  37.     )
    ( N3 J  o# o" x
  38.     3$ }# w7 b# `; d$ S! c  O$ P1 g
  39. )    ;用数组最大下标加1再除以3,所得结果做为循环次数--数组中每三个元素为一组代表一个控制点0 ^3 i% I1 k% C& _5 A; p. I1 S
  40.   (setq j 0)   ;初始化内层循环变量
    . f$ V# K; a% d2 u$ I0 Y
  41.   (repeat
    8 O; b3 X* g1 }9 h( v
  42.     (/ (1+ (vlax-safearray-get-u-bound
    ) P1 a( i# A9 @0 p3 z# E# S! g+ B- A1 e
  43.      ;第二条样条曲线控制点坐标数组的最大下标加1再除以3,做为内层循环次数% m) z! z% n* @7 Z( ^- v
  44.       (vlax-variant-value c2)  U9 B) W. ?1 d
  45.       1
    " C% E- t4 e2 g8 g- o
  46.     )# h+ M  a; i% N
  47.        )
    ) |3 `) b/ o% |0 F8 U
  48.        3$ G0 G' Y& M  b& k" F8 b
  49.     )
    2 @! b. z5 k. K2 k( `$ Z
  50.      (setq d (distance  ;计算第一条曲线索引号为 i 的控制点到第二条曲线索引号为 j 的控制点之间的三维距离# P) e9 X; p. f9 L2 g/ I, Y
  51.         (list  ;从 c1 数组中取出第一条曲线索引号为 i 的控制点的点表! A# Y3 A/ C3 ?" `+ S" A" P" U% y
  52.    (vlax-safearray-get-element9 h8 h2 h* J" U
  53.      ;用 vlax-safearray-get-element 函数获取数组中的指定的元素* f3 ]& g4 e- D5 c( U
  54.      (vlax-variant-value c1) ;数组9 s) n- e' e; d
  55.      (* i 3) ;数组元素下标2 ?9 P) Y0 Y5 i" r
  56.    )+ R  p) p% L8 p; n
  57.    (vlax-safearray-get-element
    9 l2 u+ a( n1 d. _4 |
  58.      (vlax-variant-value c1)0 V  Q% q& U: C: g4 M0 D5 E5 U) _
  59.      (+ (* i 3) 1)
    2 ^1 d+ N' G9 d: x, c$ b
  60.    )
    ; S- ?6 k; g+ {* v' g0 t  ^
  61.    (vlax-safearray-get-element
    , Q$ F% u  O$ `9 |+ S  w% ]1 m5 Q" l
  62.      (vlax-variant-value c1)! r4 w+ u: L9 X, L/ {) Q4 F- U
  63.      (+ (* i 3) 2)
    & I; v; C9 b" L0 L. C
  64.    )
    " C0 h3 _& E2 h& S
  65.         )5 t3 |3 K% ^, ?
  66.         (list  ;从 c2 数组中取出第二条曲线索引号为 j 的控制点的点表: A; b, Z) S8 R) l* _
  67.    (vlax-safearray-get-element6 V) s  m! o+ }! j. V
  68.      (vlax-variant-value c2)5 [" z! ?! V1 Q$ Q
  69.      (* j 3)$ k: B8 i2 s. Z% T+ G* ?
  70.    )$ s$ Q$ {0 _  G
  71.    (vlax-safearray-get-element% b8 E) h4 p: h8 p" Y0 C
  72.      (vlax-variant-value c2): @" M6 q! M8 [" z: b; V2 h7 A
  73.      (+ (* j 3) 1), `. r  }+ t8 v
  74.    )* R* c0 [7 Z0 m
  75.    (vlax-safearray-get-element7 I) i' q% B6 Y. s: u% A
  76.      (vlax-variant-value c2)6 }3 B+ U8 v" h, O$ f1 y/ Y
  77.      (+ (* j 3) 2)1 E( D! u  N! {" j
  78.    )$ [  \/ S$ q6 E$ q
  79.         )
    / c. I4 o7 }, a  j' R& @" Y# F
  80.       )1 E) a0 y3 O8 [: `
  81.      )$ X- `: K+ i5 B" u" H* l* A, ^) ~
  82.      (if dmin   ;检查最小距离是否为 nil (是否首次)$ l: l( N  X# H' w+ E, D. A
  83.        (if (> dmin d)  ;不是首次,比较计算所得的距离与已保存的最小距离,如发现更小的距离则保存' ^" l& A( w2 x, m9 P
  84.   (setq dmin d)9 s* N7 T) D' |# O& f" |% H
  85.        )1 Q: t) p, J/ T, V9 d1 b0 ^
  86.        (setq dmin d)  ;首次,把首个距离记录为最小距离
    . n7 I1 B. G2 d% ]' U
  87.      )! L. t  F* `& W
  88.      (setq j (1+ j))  ;内层循环变量递增
    # R, v  a- Y5 @. ^' g
  89.   )
    ; y# L) [/ ~4 j
  90.   (setq i (1+ i))  ;外层循环变量递增% _* @, f( B# Y) k
  91.       )
      o$ N) X* z0 {! l1 h
  92.     )6 ^8 g$ [4 E0 {" p: w- k7 x
  93.   )
      i# u: Y( P( d) A0 ?
  94.   (vla-delete ss)   ;用 vla- 前缀函数调用 ss 集合的 delete 方法,删除用过的选择集
    . W# a/ }, X+ W1 P" ?% h
  95.   (princ dmin)    ;命令行输出计算结果
    9 ~3 d% D' v# s
  96.   (princ)    ;静默退出# i0 p5 Y5 b( }& s$ ]! h
  97. )
    : b5 O+ J& I! k% Y# M9 e
复制代码
发表于 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 )

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