QQ登录

只需一步,快速开始

登录 | 注册 | 找回密码

三维网

 找回密码
 注册

QQ登录

只需一步,快速开始

展开

通知     

全站
3天前
查看: 4617|回复: 4
收起左侧

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

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

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

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

x
本帖最后由 tataki 于 2011-7-30 07:13 编辑 ' R# h+ h5 t$ `* N

8 H5 {7 W  [# E' R# W7 y' V各位好,最近遇到一个问题,在cad中做了两个闭合的三维spline,我是想算一算他们两者最近的距离是多少,当然不用负责的公式就算,就想着用最直观,也是很简单的方法来计算。见附图。' @' G5 N& i& c: g3 H( v# _2 ~
我的想法是在红色spline上将这条曲线上的每个点计算到蓝色曲线上的每个点距离,也就是一个二次循环,最后找出最小值就行。然而在操作中遇到了两个问题:
9 Q# A1 ]; E5 V4 O1.在spline的图元了保存的控制点坐标怎么提取出来?以前只提过其中的一项,现在面对这几百个数据不知道该怎么提取了。: ?7 p6 M( R+ s- X+ [% g
2.提取的数据怎么存放呢?我以前是学c++的,在C里面肯定用个数组循环就行了,但是不怎么会lisp,在lisp里面没有数组的概念,因此怎么存大量数据,还有后期的怎么读取都让我很迷惑,请各位懂得朋友帮个忙。在网上也找到了几个提spline坐标的程序,可是里面使用vl那些命令,这个我不知道怎么用,也没法修改成我想要的,哪位高手能帮下我,非常感谢!
4 l! O: @" R* Z8 n  \1 W+ s0 U现附上 这两条曲线的dwg文件。# G2 j6 ?# r8 m/ g& ~3 f
2011-7-29 19-17-21.jpg
- `9 w7 I5 c/ v$ U$ M6 r
- h/ R- y3 O% b6 f* Q3 a今早一打开我的帖子,就看到斑竹的答复!很激动,没想到这么快就回复了!9 K7 ~* c" K2 l+ A) u% T
非常感谢斑竹的帮助!不但给出了源代码,还有详细的注解,斑竹的认真热心和负责让我肃然起敬,以前的我提的几个问题也是斑竹给解决的。刚
看了一下发帖时间,半夜02:53....看到这个时间,明白人心理都懂得,再多赞美的词也显得苍白了....1 Y3 [7 u( H: {) S8 h7 N
辛苦斑竹了,今天周末请多休息!

spline.dwg

172.45 KB, 下载次数: 8

发表于 2011-7-30 02:53:11 | 显示全部楼层 来自: 中国辽宁
本帖最后由 woaishuijia 于 2011-8-4 09:43 编辑
% D* ^, k+ c  k' |3 b  x8 ~

  1. : H: E3 O6 [) O; A# _1 M6 Y7 a# m2 n
  2. (defun c:aaa (/ ss ft fd c1 c2 i j dmin d)
    4 Z/ {. _: L/ i
  3.   (vl-load-com)    ;将 Visual LISP 扩展功能加载到 AutoLISP
    & W1 H9 I4 z$ T- G* r! k5 w3 r4 a3 M
  4.   (setq     ;将一个或多个符号的值设置为相应表达式的值
    ! C& `/ u. G. O& g/ x1 I1 q
  5.     ss (vla-add    ;用 vla- 前缀函数调用 activeX 对象(下面的代码--该方法的第一个参数--指定的选择集集合对象)的 add 方法7 u. h! e  |5 ^( R+ f: D+ Y( |0 n
  6.   (vla-get-selectionsets  ;用 vla-get- 前缀函数获取 activeX 对象--当前文档对象--的属性:选择集集合子对象,即使用 add 方法的集合对象
    / m0 w: M* G% Q# h4 v
  7.     (vla-get-activedocument ;用 vla-get- 前缀函数获取 activeX 对象--当前 AutoCAD 应用程序对象--的属性:活动文档子对象
    9 Z5 {: \8 x5 r; W& A2 A2 p" S
  8.       (vlax-get-acad-object) ;用 vlax-get-acad-object 函数检索当前 AutoCAD 任务中的顶层 AutoCAD 应用程序对象
    9 a5 T! m- ?' B+ L0 c1 Y) o- M
  9.     )
    4 i  s& V' K& u, g
  10.   ). {$ q* l9 R/ U8 ]  @
  11.   "ss"    ;选择集名称7 }1 R' Y  m. {) j5 E
  12.        )" g% Q$ p' X+ h9 p! P
  13.     ft (vlax-make-safearray vlax-vbinteger '(0 . 0))" e9 \% H4 `3 i" K! N; {8 O) p
  14.      ;定义选择集过滤器的过滤类型数组.用 vlax-make-safearray 函数创建安全数组,整形,一维,一个元素(0 to 0).
    / l0 i* r3 j. @# j" L
  15.     fd (vlax-make-safearray vlax-vbvariant '(0 . 0))
    ! V; H" y' d" V! v% H0 R
  16.      ;定义选择集过滤器的过滤值数组.用 vlax-make-safearray 函数创建安全数组,变体,一维,一个元素(0 to 0).& |% G+ E; ?2 q4 V
  17.   )
    - \: Z  p7 v. T6 ^% c! y" Q
  18.   (vlax-safearray-put-element fd 0 "spline" )' V; Z% U/ i4 v' O+ z" s
  19.      ;用 vlax-safearray-put-element 函数为数组 fd 的第一个元素(索引号 0)赋值"spline"9 ]" y3 @& U; w+ S. e. M( e
  20.   (vla-selectonscreen ss ft fd)  ;用 vla- 前缀函数调用 ss 对象的 selectonscreen 方法,由用户在屏幕上选取样条曲线对象
    ) A( p8 Z- v$ z' _: t
  21.   (if (= (vla-get-count ss) 2)  ;如果 ss 集合的 count 属性等于2(即用户选择了两条曲线)则执行下面的代码, @& Q/ {* H+ d# l; K( @
  22.     (progn. R' ^% k) s$ y$ p3 E/ N! @2 R' h
  23.       (setq c1 (vla-get-controlpoints ;用 vla-get- 前缀函数获取样条曲线对象的控制点坐标数组并赋值给c1(变量类型为变体,值为双精度数组)
    1 w! [% |  w- y) j1 X
  24.    (vla-item ss 0) ;用 vla- 前缀函数调用集合对象的 item 方法,获取选择集中的索引号为 0 的样条曲线对象( \' s) h; p" C! D/ C7 H
  25.         ), Y* J: n# x: v1 g1 M0 _
  26.      c2 (vla-get-controlpoints ;用 vla-get- 前缀函数获取样条曲线对象的控制点坐标数组并赋值给c2(变量类型为变体,值为双精度数组)
    , k) p! G: x* ?* Y8 }
  27.    (vla-item ss 1) ;用 vla- 前缀函数调用集合对象的 item 方法,获取选择集中的索引号为 1 的样条曲线对象/ i, c) M- v+ W2 l4 s' `6 c
  28.         )
    ) m1 g# t: b3 k  |
  29.      i  0   ;初始化外层循环变量$ [8 K$ g' A( B+ K( f
  30.       )
    1 z  U* M+ W' I
  31.       (repeat    ;循环,外层
    2 w/ Y. D2 ^2 _; y. h
  32. (/ (1+ (vlax-safearray-get-u-bound
    2 l% U0 w9 P/ M* t! [8 N  V+ a, @$ j
  33.      ;用 vlax-safearray-get-u-bound 函数获取数组最大下标.第一个参数是数组,第二个参数是维数
    9 L  U" A& j0 u$ ]) K3 {0 \" B0 q
  34.    (vlax-variant-value c1);用 vlax-variant-value 函数获取变体变量 c1 的值(双精度数组)
    ( E3 \9 n# e: k, ^$ B; z, x: f
  35.    1
    : l0 G) r4 R7 I! F
  36.         )0 @( S8 X: @  J" p8 l3 K5 n
  37.     )
    4 t& z( B9 E! V5 Y8 G
  38.     3
      Z8 {6 `& D2 {" f$ ~2 b
  39. )    ;用数组最大下标加1再除以3,所得结果做为循环次数--数组中每三个元素为一组代表一个控制点
    ' X3 @! k# v6 m
  40.   (setq j 0)   ;初始化内层循环变量% ?$ C" {& u4 l3 n
  41.   (repeat
    1 s5 i" ], u: M$ ?1 G
  42.     (/ (1+ (vlax-safearray-get-u-bound
    * E4 |# _1 \; Q  y% v
  43.      ;第二条样条曲线控制点坐标数组的最大下标加1再除以3,做为内层循环次数
    6 ^' k) G' F+ F  j; }0 a* D
  44.       (vlax-variant-value c2)
    4 _( P# U' k$ F2 r  j
  45.       18 k% l! j0 n$ ^( r1 L* N
  46.     ); u$ l9 G3 V9 k: |7 F" P7 d3 a
  47.        )
    1 T7 T6 N: L% Q4 U3 J: V$ a
  48.        38 v) K3 v$ G. F8 N$ g' i' ]
  49.     )
    # |, u4 H  `9 t4 d
  50.      (setq d (distance  ;计算第一条曲线索引号为 i 的控制点到第二条曲线索引号为 j 的控制点之间的三维距离
    1 l1 k; T9 w3 W% ]( G  }# u5 l% a
  51.         (list  ;从 c1 数组中取出第一条曲线索引号为 i 的控制点的点表6 v6 m" C+ Q2 w+ s1 k$ H* Z( E
  52.    (vlax-safearray-get-element, q* o& S/ |1 E& `
  53.      ;用 vlax-safearray-get-element 函数获取数组中的指定的元素
    9 \( g$ {# A1 [; {/ F
  54.      (vlax-variant-value c1) ;数组. \- l. g$ C/ Y6 Q
  55.      (* i 3) ;数组元素下标
    3 A; M3 N* q: p% b8 F
  56.    )
      _- o9 r5 R3 p6 |; U( ]2 n3 G
  57.    (vlax-safearray-get-element
    5 p( f* h) {( ?4 Z
  58.      (vlax-variant-value c1)8 ^& Z- ^, e' Y& [4 ^
  59.      (+ (* i 3) 1)
    : u( P& r# E9 _2 o% o* |
  60.    )& u% {' w6 M0 Z+ R
  61.    (vlax-safearray-get-element
    " A4 r8 c; Z* q0 s. T
  62.      (vlax-variant-value c1)
    ( W) B, H# j) @
  63.      (+ (* i 3) 2)
    + Y% ~  Y, ?0 J" l! r6 Z2 C+ f
  64.    )
    1 u) a' R: }  p# j8 ]6 @$ L
  65.         )
    * J9 e+ p! _" t
  66.         (list  ;从 c2 数组中取出第二条曲线索引号为 j 的控制点的点表! W+ E3 f' ]& L" A% d4 i8 P
  67.    (vlax-safearray-get-element
    % |1 R5 N" O) q) k( k: a0 L
  68.      (vlax-variant-value c2)
    & m9 R" Z! {- {% B
  69.      (* j 3), a, c# o7 u+ @# G8 E  h
  70.    )
    ) {+ e9 G( _0 W- H
  71.    (vlax-safearray-get-element
    . g* H& z% b  j$ p6 o- d& @
  72.      (vlax-variant-value c2)" P$ e6 Z' ]0 Z' {0 w
  73.      (+ (* j 3) 1)1 I. S% b1 K- G/ O
  74.    )
    + s* {8 D* l* e" d9 B8 [
  75.    (vlax-safearray-get-element4 `8 f1 W6 r. }% ^; z
  76.      (vlax-variant-value c2)
    " ^9 J/ C. e. M. e: Y* a
  77.      (+ (* j 3) 2)
    0 r+ S" m6 ?. d' |0 Z" f; N
  78.    )
    * M# l' e: L, R& F) r/ V& C9 Q
  79.         )
    0 V& K! p) G* a
  80.       )
    . d* I# Q; }$ Q& Z" a- y
  81.      )
    3 S3 c8 g- ^3 h9 [/ a
  82.      (if dmin   ;检查最小距离是否为 nil (是否首次)
    1 S8 T; w8 H7 [8 S9 k+ V/ y- K% [
  83.        (if (> dmin d)  ;不是首次,比较计算所得的距离与已保存的最小距离,如发现更小的距离则保存
    & H- m2 r$ m, k5 O1 J8 C
  84.   (setq dmin d)3 a2 Y9 U' C  O! v
  85.        )
    ; U1 I% P) V- Y# B. f' O* ?  W
  86.        (setq dmin d)  ;首次,把首个距离记录为最小距离
    ' J9 c+ X. o$ k
  87.      )
    # \( [' }4 z! Q5 c
  88.      (setq j (1+ j))  ;内层循环变量递增
    9 M$ C4 V  ~3 C7 z% h7 |
  89.   )7 |& p+ a4 P/ f4 _2 N
  90.   (setq i (1+ i))  ;外层循环变量递增+ ^( A; y; o2 y/ ?
  91.       )/ o) a" C# e3 z4 ]3 B
  92.     )
    # x9 c$ c, _/ u  S1 |# P
  93.   )
    $ N$ W2 N* T0 I
  94.   (vla-delete ss)   ;用 vla- 前缀函数调用 ss 集合的 delete 方法,删除用过的选择集$ B! z& [4 s) `9 P; x; `
  95.   (princ dmin)    ;命令行输出计算结果& Z0 j5 k$ O- c
  96.   (princ)    ;静默退出
    1 H3 ^/ |! Q+ @+ f( C
  97. )1 l2 }/ p" t  ~/ @9 y1 n9 V$ L
复制代码
发表于 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 )

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