QQ登录

只需一步,快速开始

登录 | 注册 | 找回密码

三维网

 找回密码
 注册

QQ登录

只需一步,快速开始

展开

通知     

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

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

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

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

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

x
本帖最后由 tataki 于 2011-7-30 07:13 编辑 . U  M8 N+ Y8 M: F2 a5 j* k
$ p3 P' @% A; k, t4 U/ x
各位好,最近遇到一个问题,在cad中做了两个闭合的三维spline,我是想算一算他们两者最近的距离是多少,当然不用负责的公式就算,就想着用最直观,也是很简单的方法来计算。见附图。
" |8 j1 H9 c  w8 A, |$ x我的想法是在红色spline上将这条曲线上的每个点计算到蓝色曲线上的每个点距离,也就是一个二次循环,最后找出最小值就行。然而在操作中遇到了两个问题:& b) ^( n  P6 R2 Q. v- Q% M5 R
1.在spline的图元了保存的控制点坐标怎么提取出来?以前只提过其中的一项,现在面对这几百个数据不知道该怎么提取了。4 g! Z) d( D7 c9 f0 M' _: O1 T1 l4 d
2.提取的数据怎么存放呢?我以前是学c++的,在C里面肯定用个数组循环就行了,但是不怎么会lisp,在lisp里面没有数组的概念,因此怎么存大量数据,还有后期的怎么读取都让我很迷惑,请各位懂得朋友帮个忙。在网上也找到了几个提spline坐标的程序,可是里面使用vl那些命令,这个我不知道怎么用,也没法修改成我想要的,哪位高手能帮下我,非常感谢!
4 k  b- M' Q1 M- O$ d" C" @现附上 这两条曲线的dwg文件。0 z( o# j0 c- ]# B& C
2011-7-29 19-17-21.jpg
; u+ `2 s8 j* P" L- K0 U. h& P
( |- S; `# a1 e8 A今早一打开我的帖子,就看到斑竹的答复!很激动,没想到这么快就回复了!
8 q* z) d4 z& B7 @非常感谢斑竹的帮助!不但给出了源代码,还有详细的注解,斑竹的认真热心和负责让我肃然起敬,以前的我提的几个问题也是斑竹给解决的。刚
看了一下发帖时间,半夜02:53....看到这个时间,明白人心理都懂得,再多赞美的词也显得苍白了....
2 r* W1 M- x* A% o- F辛苦斑竹了,今天周末请多休息!

spline.dwg

172.45 KB, 下载次数: 8

发表于 2011-7-30 02:53:11 | 显示全部楼层 来自: 中国辽宁
本帖最后由 woaishuijia 于 2011-8-4 09:43 编辑 8 x* T" T4 d8 p5 T- ]: o" U' `
  1. 3 c; W5 P& M( K5 L
  2. (defun c:aaa (/ ss ft fd c1 c2 i j dmin d)
    6 c% y! D2 {/ n1 I
  3.   (vl-load-com)    ;将 Visual LISP 扩展功能加载到 AutoLISP
    $ j" E) M  O6 B( w. n# G) T
  4.   (setq     ;将一个或多个符号的值设置为相应表达式的值
    4 _9 Q' w# |8 m( w, ~$ H
  5.     ss (vla-add    ;用 vla- 前缀函数调用 activeX 对象(下面的代码--该方法的第一个参数--指定的选择集集合对象)的 add 方法5 K- o  S; q# `) J, d7 r
  6.   (vla-get-selectionsets  ;用 vla-get- 前缀函数获取 activeX 对象--当前文档对象--的属性:选择集集合子对象,即使用 add 方法的集合对象
    2 m. m- I( m/ q/ y5 _( S4 @' b
  7.     (vla-get-activedocument ;用 vla-get- 前缀函数获取 activeX 对象--当前 AutoCAD 应用程序对象--的属性:活动文档子对象
    . E' |$ G0 n5 ]  k0 U" k
  8.       (vlax-get-acad-object) ;用 vlax-get-acad-object 函数检索当前 AutoCAD 任务中的顶层 AutoCAD 应用程序对象
    4 n6 I, A8 ^8 R# K& V
  9.     )
    * Y) n1 p5 O. w* a4 P( v9 Y1 z8 h
  10.   )
    4 B# v4 d2 q: o1 B' ?
  11.   "ss"    ;选择集名称# j6 x' X/ b! b+ V- J2 R; M" `4 L
  12.        )
    9 a  q: \* `' F1 D
  13.     ft (vlax-make-safearray vlax-vbinteger '(0 . 0))" _# v- q5 x/ y1 R. ^
  14.      ;定义选择集过滤器的过滤类型数组.用 vlax-make-safearray 函数创建安全数组,整形,一维,一个元素(0 to 0).
    4 u" N& p, Y: A- Z, D, v! `
  15.     fd (vlax-make-safearray vlax-vbvariant '(0 . 0))
    ( L" g" Y7 O1 F2 v
  16.      ;定义选择集过滤器的过滤值数组.用 vlax-make-safearray 函数创建安全数组,变体,一维,一个元素(0 to 0).% B1 d1 F1 O* q9 P, y
  17.   ), B  d( a8 ^: b- U
  18.   (vlax-safearray-put-element fd 0 "spline" )
    ; T3 {# {6 g6 _( s) z+ z
  19.      ;用 vlax-safearray-put-element 函数为数组 fd 的第一个元素(索引号 0)赋值"spline"# c$ k4 k7 G- Z% X3 ]$ F
  20.   (vla-selectonscreen ss ft fd)  ;用 vla- 前缀函数调用 ss 对象的 selectonscreen 方法,由用户在屏幕上选取样条曲线对象
    6 {. J) Y" @$ l- T" u3 M" I$ s* t( b
  21.   (if (= (vla-get-count ss) 2)  ;如果 ss 集合的 count 属性等于2(即用户选择了两条曲线)则执行下面的代码
    4 @+ a1 P2 h  K
  22.     (progn
    7 ]' W; `' O! j2 J* L) @; ?
  23.       (setq c1 (vla-get-controlpoints ;用 vla-get- 前缀函数获取样条曲线对象的控制点坐标数组并赋值给c1(变量类型为变体,值为双精度数组)$ s" ]% H  ~  ~4 T( s0 U3 g  |
  24.    (vla-item ss 0) ;用 vla- 前缀函数调用集合对象的 item 方法,获取选择集中的索引号为 0 的样条曲线对象* v* H$ E  e! f3 H' P4 e7 J
  25.         )' o6 Q) k% J* k
  26.      c2 (vla-get-controlpoints ;用 vla-get- 前缀函数获取样条曲线对象的控制点坐标数组并赋值给c2(变量类型为变体,值为双精度数组)$ P7 b# e! y  C: U6 Y- q% X0 R" _. D
  27.    (vla-item ss 1) ;用 vla- 前缀函数调用集合对象的 item 方法,获取选择集中的索引号为 1 的样条曲线对象! G/ Q$ N- s* D( P  \* c! F% y
  28.         )
    ! T) s+ s9 l7 j2 g1 T3 F
  29.      i  0   ;初始化外层循环变量& E, v5 O1 S! f4 L8 m: e# {3 l
  30.       )9 C' ]$ @" t# E( X9 \: w% s
  31.       (repeat    ;循环,外层* ?3 A5 k, s4 c9 r. L
  32. (/ (1+ (vlax-safearray-get-u-bound
    / t# s+ ~# B4 i6 J- S2 S% s
  33.      ;用 vlax-safearray-get-u-bound 函数获取数组最大下标.第一个参数是数组,第二个参数是维数
    9 L! R# I' E& w) G0 L' O) N& K8 y
  34.    (vlax-variant-value c1);用 vlax-variant-value 函数获取变体变量 c1 的值(双精度数组)0 o0 K/ f" c8 R+ P0 A) k: T( \
  35.    12 {& C) A. k6 V& X5 P# O5 o: O
  36.         )8 ?9 H3 s# t! v6 o% s" |
  37.     )
    / F0 Z1 H/ O% G. Y+ M8 ~
  38.     3
    " V1 _5 i& \3 l1 r9 L$ o
  39. )    ;用数组最大下标加1再除以3,所得结果做为循环次数--数组中每三个元素为一组代表一个控制点
      B# H0 O* }# j
  40.   (setq j 0)   ;初始化内层循环变量' p. r, `" _# x( @% y
  41.   (repeat) X8 R% t  \; z  P* \# e5 i
  42.     (/ (1+ (vlax-safearray-get-u-bound
    0 e' z* F; E  N- i7 v/ E" a
  43.      ;第二条样条曲线控制点坐标数组的最大下标加1再除以3,做为内层循环次数8 N  z8 W" K; _0 c$ r$ f0 e# v4 ^
  44.       (vlax-variant-value c2)2 R! Y  E7 z+ N  G
  45.       19 \( d' j3 k+ ]
  46.     )
    # A% }# `2 }3 v% a
  47.        )
    - _# [6 g+ u& `7 M
  48.        3- Z6 K, y* l5 b* Y7 c. r8 G
  49.     )* s$ ^) S3 z2 E5 l4 u
  50.      (setq d (distance  ;计算第一条曲线索引号为 i 的控制点到第二条曲线索引号为 j 的控制点之间的三维距离
    6 i* l" R0 ]; j. @
  51.         (list  ;从 c1 数组中取出第一条曲线索引号为 i 的控制点的点表
    - P1 H6 {# v; }6 ^/ r7 x
  52.    (vlax-safearray-get-element
    1 Y$ K) B( ?% F3 z3 l
  53.      ;用 vlax-safearray-get-element 函数获取数组中的指定的元素* A% z/ @1 _6 |/ E- o
  54.      (vlax-variant-value c1) ;数组
    ) @/ ~. `2 \$ b. p. M1 q
  55.      (* i 3) ;数组元素下标. v* ]" t' a; g2 F* v0 r$ o
  56.    )3 b- c& }, S9 ]: [0 ?2 q: E
  57.    (vlax-safearray-get-element" Y, I# N2 m0 g% Q3 F6 C
  58.      (vlax-variant-value c1)5 x0 u3 H! y  ?* v2 h+ T
  59.      (+ (* i 3) 1)
    ( V' d$ J  d* s0 C; K- [
  60.    )
    % u* M+ B4 \0 w4 C/ l5 G4 m" ~2 S
  61.    (vlax-safearray-get-element) [, V/ a; a8 h$ P; O' ], ~0 k9 C1 b
  62.      (vlax-variant-value c1)
    / \2 v* Z& K$ q$ ^; D
  63.      (+ (* i 3) 2)
    " z4 q" g: p) Q9 }+ {& |% f1 Y* u
  64.    )/ z) D8 I( l  d  v# I
  65.         )
    9 Z+ E- |* T& C- @) Z  r" m. v( @0 F
  66.         (list  ;从 c2 数组中取出第二条曲线索引号为 j 的控制点的点表1 @% q6 t0 `6 }! U4 C4 h( k6 _
  67.    (vlax-safearray-get-element
    0 a; T* K6 I! `" |0 @1 i: c% I
  68.      (vlax-variant-value c2)+ F! D8 D9 `3 i4 K8 i' H  U, `. Z
  69.      (* j 3)2 ]. l$ f: P& y3 L/ A
  70.    )8 L" u+ G! P; J  I9 @8 @
  71.    (vlax-safearray-get-element6 i  T/ a& J% |
  72.      (vlax-variant-value c2)1 Q- D# P5 E2 q6 b; `
  73.      (+ (* j 3) 1)1 S# q1 j; D- [$ l
  74.    )
    2 R5 h: S4 t- R; F/ i$ a. E# Z
  75.    (vlax-safearray-get-element/ ]( @& r9 D5 Y7 i' F: a$ v
  76.      (vlax-variant-value c2)
    7 Q+ k, m( J' Z1 d: ~
  77.      (+ (* j 3) 2)
    ! V" t, q0 g  W% ?
  78.    )
    4 F* {( H8 @0 t) E
  79.         )# a+ ~5 |0 e( L: E$ j
  80.       ); z3 u4 |: e: n% {) v6 m
  81.      )+ C) k' E" g( o! M" [
  82.      (if dmin   ;检查最小距离是否为 nil (是否首次)3 K# Z* T9 v: x
  83.        (if (> dmin d)  ;不是首次,比较计算所得的距离与已保存的最小距离,如发现更小的距离则保存
    8 o8 g. n, l' O5 A1 P8 P
  84.   (setq dmin d)5 j  x3 p/ `  U  _1 M8 h
  85.        )/ `# i/ m# i% e- A( H# c6 n/ d
  86.        (setq dmin d)  ;首次,把首个距离记录为最小距离6 U1 w8 K! M: T2 A* _. u
  87.      )9 w/ \5 H- m/ Y  h
  88.      (setq j (1+ j))  ;内层循环变量递增
      h! S& S0 B4 U+ t2 f- o4 W
  89.   ), @) J1 W- n* ]! x7 w  s9 p
  90.   (setq i (1+ i))  ;外层循环变量递增
    & L2 [3 {  l4 q* Y  r, e
  91.       )& d* A8 W/ L& \0 x+ F! g" s" ?
  92.     )
    % w' U2 p7 ?. v" e' `& y6 i
  93.   )
    & H4 [  [  O8 d
  94.   (vla-delete ss)   ;用 vla- 前缀函数调用 ss 集合的 delete 方法,删除用过的选择集- P1 m5 h  |( x( i) y/ x7 u; f
  95.   (princ dmin)    ;命令行输出计算结果
    8 q! B  O7 o; T5 w! ^, T
  96.   (princ)    ;静默退出- s  H( L4 g" \6 n  h# D
  97. )
    0 j$ ^- w: h3 D0 K5 a9 ~
复制代码
发表于 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 )

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