QQ登录

只需一步,快速开始

登录 | 注册 | 找回密码

三维网

 找回密码
 注册

QQ登录

只需一步,快速开始

展开

通知     

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

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

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

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

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

x
本帖最后由 tataki 于 2011-7-30 07:13 编辑   g) h) F. [* L& c4 O# v

4 P) b4 s: I- }% C' G各位好,最近遇到一个问题,在cad中做了两个闭合的三维spline,我是想算一算他们两者最近的距离是多少,当然不用负责的公式就算,就想着用最直观,也是很简单的方法来计算。见附图。! e- |2 N5 {, R6 k
我的想法是在红色spline上将这条曲线上的每个点计算到蓝色曲线上的每个点距离,也就是一个二次循环,最后找出最小值就行。然而在操作中遇到了两个问题:5 j+ M6 m( m! k- l# @. S
1.在spline的图元了保存的控制点坐标怎么提取出来?以前只提过其中的一项,现在面对这几百个数据不知道该怎么提取了。
' X4 i) J% p3 x' E9 T: Q2.提取的数据怎么存放呢?我以前是学c++的,在C里面肯定用个数组循环就行了,但是不怎么会lisp,在lisp里面没有数组的概念,因此怎么存大量数据,还有后期的怎么读取都让我很迷惑,请各位懂得朋友帮个忙。在网上也找到了几个提spline坐标的程序,可是里面使用vl那些命令,这个我不知道怎么用,也没法修改成我想要的,哪位高手能帮下我,非常感谢!
" l# g. b/ F0 O4 M现附上 这两条曲线的dwg文件。
3 N- D4 v# [. { 2011-7-29 19-17-21.jpg ; O6 ~$ E( |7 ~6 B% \! N) j

& B- [, i) A* o4 B今早一打开我的帖子,就看到斑竹的答复!很激动,没想到这么快就回复了!
$ _% s7 V# x, V7 Z6 P# b非常感谢斑竹的帮助!不但给出了源代码,还有详细的注解,斑竹的认真热心和负责让我肃然起敬,以前的我提的几个问题也是斑竹给解决的。刚
看了一下发帖时间,半夜02:53....看到这个时间,明白人心理都懂得,再多赞美的词也显得苍白了....* R% G6 e3 m8 r6 k/ Y
辛苦斑竹了,今天周末请多休息!

spline.dwg

172.45 KB, 下载次数: 8

发表于 2011-7-30 02:53:11 | 显示全部楼层 来自: 中国辽宁
本帖最后由 woaishuijia 于 2011-8-4 09:43 编辑 2 b+ v( @0 b  z" T8 i

  1. 2 T. W* U/ L/ j
  2. (defun c:aaa (/ ss ft fd c1 c2 i j dmin d)
    " N6 z) k: t& ~! p
  3.   (vl-load-com)    ;将 Visual LISP 扩展功能加载到 AutoLISP - a- F5 d( j% G. o
  4.   (setq     ;将一个或多个符号的值设置为相应表达式的值
    3 D6 s- k; H8 K0 ~; e/ l
  5.     ss (vla-add    ;用 vla- 前缀函数调用 activeX 对象(下面的代码--该方法的第一个参数--指定的选择集集合对象)的 add 方法
    4 D6 t8 U$ m& k7 {; p1 k+ B' D
  6.   (vla-get-selectionsets  ;用 vla-get- 前缀函数获取 activeX 对象--当前文档对象--的属性:选择集集合子对象,即使用 add 方法的集合对象+ {( c, w. ^5 D* y. b+ W$ u' C4 a: e
  7.     (vla-get-activedocument ;用 vla-get- 前缀函数获取 activeX 对象--当前 AutoCAD 应用程序对象--的属性:活动文档子对象
    " G. m7 `7 ~- }  X3 G
  8.       (vlax-get-acad-object) ;用 vlax-get-acad-object 函数检索当前 AutoCAD 任务中的顶层 AutoCAD 应用程序对象3 p* a) ^% s+ Q/ h' _$ q
  9.     )8 m/ t1 J" N4 E  x; z
  10.   )5 Z$ v" n5 R5 y* D* u* T$ E7 v& I* n
  11.   "ss"    ;选择集名称
    0 i- q3 ]! a+ |
  12.        )' l) I  h% @- W* t% c; Z. j
  13.     ft (vlax-make-safearray vlax-vbinteger '(0 . 0))$ ?( \. d9 c+ |! u. B9 X* E
  14.      ;定义选择集过滤器的过滤类型数组.用 vlax-make-safearray 函数创建安全数组,整形,一维,一个元素(0 to 0).0 k3 ~; c, p4 S' b$ Q# }: G
  15.     fd (vlax-make-safearray vlax-vbvariant '(0 . 0))5 I- O" [+ v- z3 a; C3 ^$ \
  16.      ;定义选择集过滤器的过滤值数组.用 vlax-make-safearray 函数创建安全数组,变体,一维,一个元素(0 to 0).+ B0 Z" h! q% R/ w: V
  17.   )4 G% W4 U" k. v4 {# @9 a
  18.   (vlax-safearray-put-element fd 0 "spline" )& x$ o% ]# q2 D4 ?# I3 |. E
  19.      ;用 vlax-safearray-put-element 函数为数组 fd 的第一个元素(索引号 0)赋值"spline"
    5 w1 }# a6 @( ?/ H# t- S; I
  20.   (vla-selectonscreen ss ft fd)  ;用 vla- 前缀函数调用 ss 对象的 selectonscreen 方法,由用户在屏幕上选取样条曲线对象* D5 E) T9 p8 _# \4 B
  21.   (if (= (vla-get-count ss) 2)  ;如果 ss 集合的 count 属性等于2(即用户选择了两条曲线)则执行下面的代码
    % K' M9 Z+ H/ M) d( A$ N
  22.     (progn6 J) G& R# h1 W% ]! s9 q) o
  23.       (setq c1 (vla-get-controlpoints ;用 vla-get- 前缀函数获取样条曲线对象的控制点坐标数组并赋值给c1(变量类型为变体,值为双精度数组)
    + ^2 I. @! d2 W) r: u
  24.    (vla-item ss 0) ;用 vla- 前缀函数调用集合对象的 item 方法,获取选择集中的索引号为 0 的样条曲线对象9 @8 l5 d- B% I" ^  E! h
  25.         )
    6 [" `; h3 Q! I  H2 D
  26.      c2 (vla-get-controlpoints ;用 vla-get- 前缀函数获取样条曲线对象的控制点坐标数组并赋值给c2(变量类型为变体,值为双精度数组), \1 l2 a) u  v7 n
  27.    (vla-item ss 1) ;用 vla- 前缀函数调用集合对象的 item 方法,获取选择集中的索引号为 1 的样条曲线对象
    9 m5 z1 ?% l4 Q$ J% R* D7 ~5 {) j
  28.         )
    6 O9 d8 }) u% ^6 h% \% C
  29.      i  0   ;初始化外层循环变量
    . V$ Y* a& a6 {$ W" t. ^1 r0 N4 Y
  30.       )9 m( H. R( d1 R" |, o% T. J. E
  31.       (repeat    ;循环,外层
    + Q2 V' ~2 j$ N/ _, {
  32. (/ (1+ (vlax-safearray-get-u-bound/ n( @  M- \- u1 ?
  33.      ;用 vlax-safearray-get-u-bound 函数获取数组最大下标.第一个参数是数组,第二个参数是维数
    + O! I5 R1 ~: a
  34.    (vlax-variant-value c1);用 vlax-variant-value 函数获取变体变量 c1 的值(双精度数组)6 l& s: d7 o4 E) D, c$ H
  35.    1' S( D( K3 u  K4 f
  36.         )
    ! x) C% s0 i+ Z
  37.     )  S  ^$ H6 U$ J0 i9 v' W
  38.     3
    ; l2 J% y( p6 n
  39. )    ;用数组最大下标加1再除以3,所得结果做为循环次数--数组中每三个元素为一组代表一个控制点8 W2 z+ a' |) w1 G" ]: G, B+ Q
  40.   (setq j 0)   ;初始化内层循环变量
    0 f3 @* u8 K, n, s
  41.   (repeat+ O% r+ Y1 B7 e# O& k( [1 x
  42.     (/ (1+ (vlax-safearray-get-u-bound5 j/ n% z% ?9 l! I
  43.      ;第二条样条曲线控制点坐标数组的最大下标加1再除以3,做为内层循环次数
    - B9 K9 O7 C, l$ \; s& X6 L/ o
  44.       (vlax-variant-value c2)
    4 ?& g' A0 t$ a7 J! z4 A1 H
  45.       1
    # k# u7 m6 D* d6 |! p: v
  46.     )
    & M4 U  C- W+ P2 @) d" E6 v
  47.        )) |0 N( D/ X2 S- s. o
  48.        3
    ! m" y  t8 r+ C  h6 A7 G" c- s& d
  49.     )) R) A+ y* W0 A" {4 M9 P
  50.      (setq d (distance  ;计算第一条曲线索引号为 i 的控制点到第二条曲线索引号为 j 的控制点之间的三维距离5 j2 Y! ]! d  g! c
  51.         (list  ;从 c1 数组中取出第一条曲线索引号为 i 的控制点的点表/ ?/ Y2 \5 R$ u' U& n5 D# @4 H
  52.    (vlax-safearray-get-element2 Q+ Y# Q3 H1 Y- E6 M1 V8 F
  53.      ;用 vlax-safearray-get-element 函数获取数组中的指定的元素; ^9 }  \3 B/ \0 v8 [
  54.      (vlax-variant-value c1) ;数组% G* Q6 ~: n7 K3 L
  55.      (* i 3) ;数组元素下标2 P2 K( T) m- W! ]; \: h
  56.    )
    9 J* F3 T6 v2 d8 o* r; A" ]( \, i
  57.    (vlax-safearray-get-element
    9 j, g( W; T6 p2 g% K& E
  58.      (vlax-variant-value c1)! ^* X3 e( o" F5 ?$ {
  59.      (+ (* i 3) 1)2 w% B% w& G* v" h3 y2 P
  60.    )
    0 h4 B3 p" A/ u; u) ]$ \) r) w* S
  61.    (vlax-safearray-get-element
    3 A3 L; o7 F/ k8 S1 v$ V
  62.      (vlax-variant-value c1)
    & p* o! W: U5 I
  63.      (+ (* i 3) 2)
    - X5 c  B7 k% i* k4 C1 }
  64.    )
    3 L" l7 s# p: O, i/ B, T
  65.         )
    / j, d6 p; D7 V' Q* c
  66.         (list  ;从 c2 数组中取出第二条曲线索引号为 j 的控制点的点表
    7 E( `+ |" u- L
  67.    (vlax-safearray-get-element0 }7 E6 {9 _4 L1 d3 C
  68.      (vlax-variant-value c2)
    6 P; y  s$ w, W1 _& w% N
  69.      (* j 3)
    , v+ g& U  t0 |( P
  70.    )
    ( E5 {! X: Q' T( s: W
  71.    (vlax-safearray-get-element; l" M0 P4 ]9 X. h  r
  72.      (vlax-variant-value c2)
    ) a& _: B2 q) h# d8 Q. g1 J" o
  73.      (+ (* j 3) 1). |# Q$ i$ r/ r
  74.    )# V0 U8 C  r6 m0 j
  75.    (vlax-safearray-get-element
    / z$ C' }# K* |) t7 O3 v6 d/ s; Q) {
  76.      (vlax-variant-value c2)
    ) y) X; t( ?& J6 K& Z  |
  77.      (+ (* j 3) 2)$ G' K4 ^, V4 Q, C! T
  78.    )" n4 _7 i; V: s% L& ~
  79.         )
    : U* ?  Z7 }9 p/ U0 b9 ^% P
  80.       )5 ]& s& s' q. Q$ m5 m
  81.      )
      v+ d9 t; i$ Z3 U# H! [
  82.      (if dmin   ;检查最小距离是否为 nil (是否首次)% S, Y: x' V' C) Z( X$ J+ x! I, f
  83.        (if (> dmin d)  ;不是首次,比较计算所得的距离与已保存的最小距离,如发现更小的距离则保存
    : ~8 Y) T; j: ^  C3 }
  84.   (setq dmin d)
    & A/ s) c+ O/ J  o
  85.        )' N7 i0 e. w  G: \8 c
  86.        (setq dmin d)  ;首次,把首个距离记录为最小距离
    8 v6 O% J6 L8 D( f- z  i
  87.      )6 \% g+ V7 t5 ^5 q' C
  88.      (setq j (1+ j))  ;内层循环变量递增
    ( S5 @9 g* k% Z/ q  _# I
  89.   ); K8 V) |1 }, X8 [
  90.   (setq i (1+ i))  ;外层循环变量递增2 p. u2 o; F" X+ U8 n
  91.       )7 X5 @5 ~5 `& L! L
  92.     )) [) W& I" {/ L7 F( z8 |8 x
  93.   )0 F9 \& k. g4 x! _' M1 {  ?
  94.   (vla-delete ss)   ;用 vla- 前缀函数调用 ss 集合的 delete 方法,删除用过的选择集2 I9 W0 Q2 ]2 a0 W& q
  95.   (princ dmin)    ;命令行输出计算结果6 ^: D3 A1 v3 a
  96.   (princ)    ;静默退出
    2 r0 ^0 `6 A7 F  y# u
  97. )
    4 u5 Y; l) c( _( P* @( i
复制代码
发表于 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 )

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