QQ登录

只需一步,快速开始

登录 | 注册 | 找回密码

三维网

 找回密码
 注册

QQ登录

只需一步,快速开始

展开

通知     

全站
goto3d 说: 此次SW竞赛获奖名单公布如下,抱歉晚了,版主最近太忙:一等奖:塔山817;二等奖:a9041、飞鱼;三等奖:wx_dfA5IKla、xwj960414、bzlgl、hklecon;请以上各位和版主联系,领取奖金!!!
2022-03-11
全站
goto3d 说: 在线网校新上线表哥同事(Mastercam2022)+虞为民版大(inventor2022)的最新课程,来围观吧!
2021-06-26
查看: 4456|回复: 4
收起左侧

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

[复制链接]
发表于 2011-7-29 20:17:21 | 显示全部楼层 |阅读模式

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

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

x
本帖最后由 tataki 于 2011-7-30 07:13 编辑 % J7 `+ i' d5 {+ U& x

: Z- ^! C- p  X) S7 f  M. c5 p5 d6 X各位好,最近遇到一个问题,在cad中做了两个闭合的三维spline,我是想算一算他们两者最近的距离是多少,当然不用负责的公式就算,就想着用最直观,也是很简单的方法来计算。见附图。
" z6 h( g7 T% a+ K我的想法是在红色spline上将这条曲线上的每个点计算到蓝色曲线上的每个点距离,也就是一个二次循环,最后找出最小值就行。然而在操作中遇到了两个问题:
) \; z' T% E0 A" ^; \1.在spline的图元了保存的控制点坐标怎么提取出来?以前只提过其中的一项,现在面对这几百个数据不知道该怎么提取了。
! G7 y/ O1 e- @- ^$ u8 X2.提取的数据怎么存放呢?我以前是学c++的,在C里面肯定用个数组循环就行了,但是不怎么会lisp,在lisp里面没有数组的概念,因此怎么存大量数据,还有后期的怎么读取都让我很迷惑,请各位懂得朋友帮个忙。在网上也找到了几个提spline坐标的程序,可是里面使用vl那些命令,这个我不知道怎么用,也没法修改成我想要的,哪位高手能帮下我,非常感谢!
1 Y, Z5 J# [5 {3 F现附上 这两条曲线的dwg文件。' V7 `4 ~- f. J7 h" F  o
2011-7-29 19-17-21.jpg $ P5 }. L7 o; d9 P

' S) z/ C+ `1 R7 R今早一打开我的帖子,就看到斑竹的答复!很激动,没想到这么快就回复了!3 B; a/ u# d! [% y
非常感谢斑竹的帮助!不但给出了源代码,还有详细的注解,斑竹的认真热心和负责让我肃然起敬,以前的我提的几个问题也是斑竹给解决的。刚
看了一下发帖时间,半夜02:53....看到这个时间,明白人心理都懂得,再多赞美的词也显得苍白了....
1 a# s8 k# S  K辛苦斑竹了,今天周末请多休息!

spline.dwg

172.45 KB, 下载次数: 8

发表于 2011-7-30 02:53:11 | 显示全部楼层
本帖最后由 woaishuijia 于 2011-8-4 09:43 编辑 8 F$ G  R( N# ^8 H

  1. # r& @1 ^# o) l1 d9 o: ?" @" c
  2. (defun c:aaa (/ ss ft fd c1 c2 i j dmin d)8 p1 k4 }" |! B" ^3 z
  3.   (vl-load-com)    ;将 Visual LISP 扩展功能加载到 AutoLISP 2 C  p( Z8 k, @. {; |1 h" b
  4.   (setq     ;将一个或多个符号的值设置为相应表达式的值0 R% r: b4 v& p% \$ `# ]" i
  5.     ss (vla-add    ;用 vla- 前缀函数调用 activeX 对象(下面的代码--该方法的第一个参数--指定的选择集集合对象)的 add 方法( k  P, X: c( T% G7 p0 I: O& l
  6.   (vla-get-selectionsets  ;用 vla-get- 前缀函数获取 activeX 对象--当前文档对象--的属性:选择集集合子对象,即使用 add 方法的集合对象
    3 o5 q4 l, }$ L; _. n/ f+ l, b6 u
  7.     (vla-get-activedocument ;用 vla-get- 前缀函数获取 activeX 对象--当前 AutoCAD 应用程序对象--的属性:活动文档子对象
    8 V2 y5 B6 Z; @6 K4 J
  8.       (vlax-get-acad-object) ;用 vlax-get-acad-object 函数检索当前 AutoCAD 任务中的顶层 AutoCAD 应用程序对象. s' L8 A4 F/ Q* q& C% I
  9.     )* p+ H( n  j! {
  10.   )# H( U6 @% G9 A6 ^. ^2 R
  11.   "ss"    ;选择集名称6 y$ `5 k' E( ~9 z/ D, p8 H
  12.        )- M5 d* i1 }5 |* x5 G8 `5 j2 ?* i
  13.     ft (vlax-make-safearray vlax-vbinteger '(0 . 0))# b( V+ H* J2 P. a1 r2 S
  14.      ;定义选择集过滤器的过滤类型数组.用 vlax-make-safearray 函数创建安全数组,整形,一维,一个元素(0 to 0).
    + R+ X% T5 u2 Y% ]
  15.     fd (vlax-make-safearray vlax-vbvariant '(0 . 0))$ u' R! F. ~7 R
  16.      ;定义选择集过滤器的过滤值数组.用 vlax-make-safearray 函数创建安全数组,变体,一维,一个元素(0 to 0).
    " f5 w  S9 Q. s! K
  17.   )
    / z  |. R, \2 Y9 n& |3 y
  18.   (vlax-safearray-put-element fd 0 "spline" )
    - D0 X5 R' j9 {) l, V
  19.      ;用 vlax-safearray-put-element 函数为数组 fd 的第一个元素(索引号 0)赋值"spline"
    / k8 l# I! o. p- n+ Z' _/ W3 j
  20.   (vla-selectonscreen ss ft fd)  ;用 vla- 前缀函数调用 ss 对象的 selectonscreen 方法,由用户在屏幕上选取样条曲线对象
    - E* ?( h0 d/ h' f( G, R* P
  21.   (if (= (vla-get-count ss) 2)  ;如果 ss 集合的 count 属性等于2(即用户选择了两条曲线)则执行下面的代码
    - f' C: T9 |! G# Z
  22.     (progn+ p+ Z4 P" _1 v% r
  23.       (setq c1 (vla-get-controlpoints ;用 vla-get- 前缀函数获取样条曲线对象的控制点坐标数组并赋值给c1(变量类型为变体,值为双精度数组)6 h3 ?. h' V# x* k' A: y
  24.    (vla-item ss 0) ;用 vla- 前缀函数调用集合对象的 item 方法,获取选择集中的索引号为 0 的样条曲线对象
    $ A( ^5 H# e: U/ r& C% S
  25.         )* t: \# X. M8 d6 w) K. k9 b
  26.      c2 (vla-get-controlpoints ;用 vla-get- 前缀函数获取样条曲线对象的控制点坐标数组并赋值给c2(变量类型为变体,值为双精度数组): T7 o6 F. X4 V) s3 k
  27.    (vla-item ss 1) ;用 vla- 前缀函数调用集合对象的 item 方法,获取选择集中的索引号为 1 的样条曲线对象
      u# H( {& f4 ~9 Y* @
  28.         )
    * j! H# i  h9 ^7 W
  29.      i  0   ;初始化外层循环变量
    4 s& a% K3 `% R
  30.       )
    & K0 D" T, u, w2 R* Y6 _5 e
  31.       (repeat    ;循环,外层
    5 [4 i) c6 M" ^# X
  32. (/ (1+ (vlax-safearray-get-u-bound
    % w3 p: z/ D: H; a/ y3 R" S
  33.      ;用 vlax-safearray-get-u-bound 函数获取数组最大下标.第一个参数是数组,第二个参数是维数
    1 s) d& i9 U; o3 z8 f! C
  34.    (vlax-variant-value c1);用 vlax-variant-value 函数获取变体变量 c1 的值(双精度数组)
    . ]0 D0 l' @6 s3 N) u
  35.    1
    : Q; I$ O2 ~- ~. h3 v6 u. m3 g
  36.         ); d8 M9 D$ r9 r: j6 y* W
  37.     )
    ' K" s, D; u8 b2 G& S$ G
  38.     3
    " D2 T( s# R3 B8 c+ t
  39. )    ;用数组最大下标加1再除以3,所得结果做为循环次数--数组中每三个元素为一组代表一个控制点" y& i, f8 N* r, a- |4 i
  40.   (setq j 0)   ;初始化内层循环变量0 j# s$ ?/ N/ u- [0 C5 |
  41.   (repeat; q. k, ~- S5 d4 |7 ]
  42.     (/ (1+ (vlax-safearray-get-u-bound
    * [( w# e; K: I- I: ]1 ?
  43.      ;第二条样条曲线控制点坐标数组的最大下标加1再除以3,做为内层循环次数0 E8 C4 ]$ L' g9 c# d! Z. f
  44.       (vlax-variant-value c2)
    ; d9 V% r; N0 N
  45.       1  m( ]& I& g1 s' J+ C2 G
  46.     )' x% ^7 E3 @( p4 F9 W* l) G! `  o
  47.        )& D1 D7 R9 K) ?; n, h
  48.        3! c, w# O! k2 _  x0 N0 ~
  49.     )
    5 }3 _- W  X; Y+ p& c8 D3 W3 I% r
  50.      (setq d (distance  ;计算第一条曲线索引号为 i 的控制点到第二条曲线索引号为 j 的控制点之间的三维距离1 b8 {9 Q0 s1 e- A( @6 o1 k
  51.         (list  ;从 c1 数组中取出第一条曲线索引号为 i 的控制点的点表
    9 K5 f, `+ j1 x3 s8 n  [9 F
  52.    (vlax-safearray-get-element
    7 K' H/ F1 \! W
  53.      ;用 vlax-safearray-get-element 函数获取数组中的指定的元素
    5 L/ P' |' Y; G1 @
  54.      (vlax-variant-value c1) ;数组6 `) ~( \2 P* `
  55.      (* i 3) ;数组元素下标, C( X# h3 t: K
  56.    )1 T+ l$ y3 s# D: D, B
  57.    (vlax-safearray-get-element
    2 w9 M! r9 o5 Q' a0 O" j+ F
  58.      (vlax-variant-value c1)' y- ^6 m' B8 w# B+ l6 a
  59.      (+ (* i 3) 1)
    + U" y" q. M& d" C
  60.    )
    9 M4 z- `- n! S# M- i" C6 |0 F/ O
  61.    (vlax-safearray-get-element2 C& H) \& E+ y/ O
  62.      (vlax-variant-value c1)/ i7 {& U* M/ c. y9 K& W
  63.      (+ (* i 3) 2)0 C, K* M2 X0 u$ `
  64.    )' t) E) u' E* X8 n7 Y
  65.         )% w9 q3 V( q3 I, f
  66.         (list  ;从 c2 数组中取出第二条曲线索引号为 j 的控制点的点表3 w* h; s% ^6 @* Q4 A  \3 M0 s5 T+ k
  67.    (vlax-safearray-get-element2 s* {. m! B! X9 Y
  68.      (vlax-variant-value c2)/ ^! y3 F+ f7 L* W  |
  69.      (* j 3)" Z) i4 A6 c: D! f2 l
  70.    )* J! R/ X' v; x$ c% f
  71.    (vlax-safearray-get-element! u" ^/ I" i' y4 Y+ Z* L
  72.      (vlax-variant-value c2)
    % X# C% U2 R" B5 ]/ n+ v9 n2 v+ r
  73.      (+ (* j 3) 1)
    7 H+ M8 x0 w( U4 v2 l, O
  74.    )
      G1 H! N0 M: F6 B3 s
  75.    (vlax-safearray-get-element( _9 b! {* L5 K" U
  76.      (vlax-variant-value c2)( y  p3 u% j+ n/ Y' h1 r2 P4 G
  77.      (+ (* j 3) 2)
    9 ?' q& b5 e% G% J6 }" c4 h) v
  78.    )5 s6 }2 j$ e: \4 p# W. w9 v
  79.         )
    % A9 S8 L; f* X2 Y3 W$ i! G: _
  80.       )
    - i) Q% Z! R7 x# ]
  81.      )3 r! ~. C3 c/ g. {% y% H1 {
  82.      (if dmin   ;检查最小距离是否为 nil (是否首次)
      h; X+ w6 m+ ^% o$ A3 h3 e7 p* Y7 d3 V
  83.        (if (> dmin d)  ;不是首次,比较计算所得的距离与已保存的最小距离,如发现更小的距离则保存! A( c# a1 R( {% }: s8 e; s+ Y  @
  84.   (setq dmin d)+ N) ^1 {2 t. R( `3 i
  85.        )
    # z# d+ d/ X7 `  g1 O  E! \5 o3 P
  86.        (setq dmin d)  ;首次,把首个距离记录为最小距离& F* \% A1 X$ j* [6 D
  87.      )
    0 y: k) ~* A7 [8 m' O' `
  88.      (setq j (1+ j))  ;内层循环变量递增$ J) f3 `5 S2 H- a! j* j' i
  89.   )
    $ E# \2 ], T, }( {) e
  90.   (setq i (1+ i))  ;外层循环变量递增. p6 U2 d4 B5 T6 k7 \$ I- s
  91.       )
    7 y" f% i4 S$ ~2 ?. Q2 {- q
  92.     )
    ) N' Q! e6 P) m* z& d- e' F
  93.   )
    0 V# o6 U9 t9 D( v
  94.   (vla-delete ss)   ;用 vla- 前缀函数调用 ss 集合的 delete 方法,删除用过的选择集
    0 @# p/ A) H$ H2 V$ O
  95.   (princ dmin)    ;命令行输出计算结果7 _) W2 E9 f! d7 Y# D) _; B
  96.   (princ)    ;静默退出
    . j+ L& I# B# q+ }% ?
  97. )$ u! r+ `+ \7 D2 [" L' }; 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 )

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