QQ登录

只需一步,快速开始

登录 | 注册 | 找回密码

三维网

 找回密码
 注册

QQ登录

只需一步,快速开始

展开

通知     

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

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

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

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

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

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

spline.dwg

172.45 KB, 下载次数: 8

发表于 2011-7-30 02:53:11 | 显示全部楼层 来自: 中国辽宁
本帖最后由 woaishuijia 于 2011-8-4 09:43 编辑 3 H5 n' C- B8 X
  1. 0 e2 ?# u( G3 c
  2. (defun c:aaa (/ ss ft fd c1 c2 i j dmin d)
    ) Y6 A1 g* z$ J+ E
  3.   (vl-load-com)    ;将 Visual LISP 扩展功能加载到 AutoLISP # `, L: A$ ^0 G7 z& g: \1 b
  4.   (setq     ;将一个或多个符号的值设置为相应表达式的值
    $ F& f' \' X5 o: Q3 c
  5.     ss (vla-add    ;用 vla- 前缀函数调用 activeX 对象(下面的代码--该方法的第一个参数--指定的选择集集合对象)的 add 方法$ |! Y$ N+ `& w/ e
  6.   (vla-get-selectionsets  ;用 vla-get- 前缀函数获取 activeX 对象--当前文档对象--的属性:选择集集合子对象,即使用 add 方法的集合对象5 C* Q3 F% W7 I* ^* \  \* g
  7.     (vla-get-activedocument ;用 vla-get- 前缀函数获取 activeX 对象--当前 AutoCAD 应用程序对象--的属性:活动文档子对象; c& _# `; [1 |$ L! [. H# w
  8.       (vlax-get-acad-object) ;用 vlax-get-acad-object 函数检索当前 AutoCAD 任务中的顶层 AutoCAD 应用程序对象
    ' D# m0 J3 Q, e% k( u
  9.     )
    , N; T  {2 n; l+ a6 h$ ^
  10.   )* V, H$ N; z# \: c. d
  11.   "ss"    ;选择集名称1 r% z# {2 F, s6 ^- k
  12.        ): z7 w3 M. ^' v# R% X0 h& ]2 ~- X
  13.     ft (vlax-make-safearray vlax-vbinteger '(0 . 0)); c* e- T6 D: K
  14.      ;定义选择集过滤器的过滤类型数组.用 vlax-make-safearray 函数创建安全数组,整形,一维,一个元素(0 to 0)., I0 t, \5 z' e, C
  15.     fd (vlax-make-safearray vlax-vbvariant '(0 . 0))
    1 L# s8 E$ B! G
  16.      ;定义选择集过滤器的过滤值数组.用 vlax-make-safearray 函数创建安全数组,变体,一维,一个元素(0 to 0).- @$ g; P" |- o# q
  17.   )0 r$ L; b" u2 J% V; o# w- l! x5 l
  18.   (vlax-safearray-put-element fd 0 "spline" )9 W% @  P# `2 R% g0 V- ~% R4 ~, E
  19.      ;用 vlax-safearray-put-element 函数为数组 fd 的第一个元素(索引号 0)赋值"spline"
    7 l5 \% d; g1 X1 j. C$ Y2 g
  20.   (vla-selectonscreen ss ft fd)  ;用 vla- 前缀函数调用 ss 对象的 selectonscreen 方法,由用户在屏幕上选取样条曲线对象! W/ k4 v* \) r5 e6 w
  21.   (if (= (vla-get-count ss) 2)  ;如果 ss 集合的 count 属性等于2(即用户选择了两条曲线)则执行下面的代码
    ( T7 a1 Z( ~  X/ ~# {
  22.     (progn
    7 D; I* g, h$ B# {" z4 B
  23.       (setq c1 (vla-get-controlpoints ;用 vla-get- 前缀函数获取样条曲线对象的控制点坐标数组并赋值给c1(变量类型为变体,值为双精度数组)# \9 N8 e* R* y# n2 E- y: ~8 P  h
  24.    (vla-item ss 0) ;用 vla- 前缀函数调用集合对象的 item 方法,获取选择集中的索引号为 0 的样条曲线对象
    0 a% S  |) G$ C  ?6 U  B3 W6 b
  25.         )
    ( b9 I; ~, \7 X$ V  k( @. K
  26.      c2 (vla-get-controlpoints ;用 vla-get- 前缀函数获取样条曲线对象的控制点坐标数组并赋值给c2(变量类型为变体,值为双精度数组)
    1 ~! c; t' r' h
  27.    (vla-item ss 1) ;用 vla- 前缀函数调用集合对象的 item 方法,获取选择集中的索引号为 1 的样条曲线对象
    0 R( B0 J. i, @' Y3 [1 L
  28.         )
    7 j( l. A9 B6 N7 V$ [% Z% c
  29.      i  0   ;初始化外层循环变量3 v, `' \; z9 g: }2 B/ Z6 U+ v
  30.       )
    1 r) _# k  _" E
  31.       (repeat    ;循环,外层+ J! H" K. }3 T3 ?- |4 F# c
  32. (/ (1+ (vlax-safearray-get-u-bound
    % a! D0 h% ]! w/ y. o' r
  33.      ;用 vlax-safearray-get-u-bound 函数获取数组最大下标.第一个参数是数组,第二个参数是维数
    ; a. F8 o# l! I# G
  34.    (vlax-variant-value c1);用 vlax-variant-value 函数获取变体变量 c1 的值(双精度数组)
    / `) E% m& l4 n3 ]/ m+ v4 X
  35.    1
    , V( R: J0 ~; \3 M2 f
  36.         )
    % m2 j# p  C) t6 u1 W" [
  37.     )2 |1 r% ?( b' X7 }
  38.     3* o6 ?4 A7 W$ }# ]  Q" |
  39. )    ;用数组最大下标加1再除以3,所得结果做为循环次数--数组中每三个元素为一组代表一个控制点( f+ ?3 A6 C: u7 E* n+ C6 I8 {; C
  40.   (setq j 0)   ;初始化内层循环变量! ^/ [8 m4 F* Q1 z; K
  41.   (repeat6 @$ W2 W# c0 j- e% l( b- ~
  42.     (/ (1+ (vlax-safearray-get-u-bound! W; g6 r  a8 l; }" D* p
  43.      ;第二条样条曲线控制点坐标数组的最大下标加1再除以3,做为内层循环次数
    3 k, {% Z9 f% `/ Z- Z4 M
  44.       (vlax-variant-value c2). u1 b/ M, ]/ n! `0 s% K9 L. P" u
  45.       11 p& {  ^" K, K& T( ~8 _
  46.     )
      W' Q" a, \( K: i2 f
  47.        )
    8 n5 k- ]$ T5 k7 Y+ i
  48.        3
    % Q. X, I% p0 A( E# W. r7 x9 J
  49.     )9 r4 v  ?6 z& k  A
  50.      (setq d (distance  ;计算第一条曲线索引号为 i 的控制点到第二条曲线索引号为 j 的控制点之间的三维距离
    % y2 `0 q3 G6 m' {
  51.         (list  ;从 c1 数组中取出第一条曲线索引号为 i 的控制点的点表
    0 k# @% G7 O4 X) L* g% `& Y
  52.    (vlax-safearray-get-element
    # F+ \+ O% X3 K) {8 O/ u: _3 k- ^
  53.      ;用 vlax-safearray-get-element 函数获取数组中的指定的元素* \  Z% S7 v4 n( P: }" b
  54.      (vlax-variant-value c1) ;数组
    , ]( U2 S, N! _) o8 d6 I4 W
  55.      (* i 3) ;数组元素下标
    8 d6 s- ~# c# W. E: S
  56.    )
    ' Z4 P8 \1 E2 n
  57.    (vlax-safearray-get-element9 L& @8 u0 t$ q' S
  58.      (vlax-variant-value c1)
    4 m5 \  e% P  p& {
  59.      (+ (* i 3) 1)
    ! S$ U% @3 K3 M+ W0 X8 w: b3 Y
  60.    )/ Y9 A7 h4 t4 x) L& r4 l
  61.    (vlax-safearray-get-element
    / V/ S9 q/ F  Y" O8 K. H
  62.      (vlax-variant-value c1)
    % v. B7 I) W4 i. y- g
  63.      (+ (* i 3) 2)
    0 m7 Z' o2 \) X7 R4 Z7 `8 `0 f0 I
  64.    )
    : z  S" F0 q  x7 ~
  65.         )
    ' ^) e, g4 t6 p7 I+ \4 f
  66.         (list  ;从 c2 数组中取出第二条曲线索引号为 j 的控制点的点表
    0 _: O6 q& n1 U
  67.    (vlax-safearray-get-element  R0 d, e" n" s% a
  68.      (vlax-variant-value c2)
    ; b& L+ G( w/ I0 b7 m% {* G
  69.      (* j 3). z& j8 ]  H4 K- z
  70.    )& |& n' ~; U. d$ L5 i' P
  71.    (vlax-safearray-get-element6 W0 v5 l- c, P1 T4 F% Y
  72.      (vlax-variant-value c2)$ C, _  k! h2 }8 F
  73.      (+ (* j 3) 1)# \& ]2 K0 }' R4 B$ j3 a3 k7 h7 E
  74.    )* S# {  m- _- Y
  75.    (vlax-safearray-get-element
    7 l# q+ Z' v) Z& z* w  E
  76.      (vlax-variant-value c2)
    9 Y) `- _! x" e9 |# C$ _
  77.      (+ (* j 3) 2)
    % c/ Z( L/ E! V" U, ]( c
  78.    )3 p. Y# v5 [6 p+ c- f' e1 I
  79.         )
    * o) X3 Z% a4 g
  80.       )4 r: P5 m' A- T" `
  81.      )+ ]" P1 n3 p7 r6 Q/ c
  82.      (if dmin   ;检查最小距离是否为 nil (是否首次)
    % n0 y( l3 M( y. @( B
  83.        (if (> dmin d)  ;不是首次,比较计算所得的距离与已保存的最小距离,如发现更小的距离则保存4 B/ D3 O8 |; x3 k! v' s
  84.   (setq dmin d)3 ^2 n5 b/ v9 o% p- B* @& y1 o
  85.        )
    " c$ a% u- p& \3 z
  86.        (setq dmin d)  ;首次,把首个距离记录为最小距离
    / n) ?. D+ \& N1 ?3 U
  87.      )3 |& M! ?8 F* Q! C
  88.      (setq j (1+ j))  ;内层循环变量递增* D( R) O3 E1 ]7 q5 x( i9 f% E
  89.   )
    - N+ U4 t! B- I: ~( e2 ]% S' H7 y
  90.   (setq i (1+ i))  ;外层循环变量递增
    1 ]; ^) P/ \2 G
  91.       )9 u" c: _% ~) @: C$ h. e. F
  92.     )! o! ^6 @! y* p+ R. W; t$ y
  93.   )
    , r" L! X3 D- ~/ E6 L. d+ d) r  C! J
  94.   (vla-delete ss)   ;用 vla- 前缀函数调用 ss 集合的 delete 方法,删除用过的选择集
    % b4 J! I' W& ]5 q. t* Q4 u' A
  95.   (princ dmin)    ;命令行输出计算结果
    ' f9 s$ D' D( f* H4 r, A5 P  E
  96.   (princ)    ;静默退出3 X' y. k1 Z; l: O; I
  97. )
    , D6 w% _! `( i+ c5 ^( ~) c( t
复制代码
发表于 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 )

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