QQ登录

只需一步,快速开始

登录 | 注册 | 找回密码

三维网

 找回密码
 注册

QQ登录

只需一步,快速开始

展开

通知     

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

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

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

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

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

x
本帖最后由 tataki 于 2011-7-30 07:13 编辑 / ^8 ~" J7 u% {4 K- f

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

spline.dwg

172.45 KB, 下载次数: 8

发表于 2011-7-30 02:53:11 | 显示全部楼层
本帖最后由 woaishuijia 于 2011-8-4 09:43 编辑   y' k) t. R* K, _: b- k: i

  1. / Z" i1 K( A& H) a/ E: U
  2. (defun c:aaa (/ ss ft fd c1 c2 i j dmin d), P) P: K, h) h8 f) x$ @9 [' }0 O
  3.   (vl-load-com)    ;将 Visual LISP 扩展功能加载到 AutoLISP
    0 p7 b8 c9 Q! `2 S( x5 y: b5 k/ {
  4.   (setq     ;将一个或多个符号的值设置为相应表达式的值
    $ f* F/ P! i/ s1 B# K
  5.     ss (vla-add    ;用 vla- 前缀函数调用 activeX 对象(下面的代码--该方法的第一个参数--指定的选择集集合对象)的 add 方法& z) q6 ^( n+ y0 k0 ^6 H
  6.   (vla-get-selectionsets  ;用 vla-get- 前缀函数获取 activeX 对象--当前文档对象--的属性:选择集集合子对象,即使用 add 方法的集合对象( K" P% m# k8 l$ D4 O5 I" l
  7.     (vla-get-activedocument ;用 vla-get- 前缀函数获取 activeX 对象--当前 AutoCAD 应用程序对象--的属性:活动文档子对象
    ; D' l, p7 r9 a+ h$ s8 y
  8.       (vlax-get-acad-object) ;用 vlax-get-acad-object 函数检索当前 AutoCAD 任务中的顶层 AutoCAD 应用程序对象6 M/ z3 g/ }/ T1 d+ k! L( z) Q9 J& x
  9.     )1 f- n, `! X% F8 t* J! z
  10.   )" C7 `! ^% ~, n: u3 R) x
  11.   "ss"    ;选择集名称
    4 u' K" l  v4 ?
  12.        )
    , x5 j- D- t! W' K' _% `- {6 Q0 k
  13.     ft (vlax-make-safearray vlax-vbinteger '(0 . 0)): p% q9 |% n3 ]6 n0 w
  14.      ;定义选择集过滤器的过滤类型数组.用 vlax-make-safearray 函数创建安全数组,整形,一维,一个元素(0 to 0).* S7 Q; S' h' q8 B0 H' Q8 G3 V
  15.     fd (vlax-make-safearray vlax-vbvariant '(0 . 0)): J2 C3 u5 v2 o
  16.      ;定义选择集过滤器的过滤值数组.用 vlax-make-safearray 函数创建安全数组,变体,一维,一个元素(0 to 0).' s$ O9 o% a9 w9 n( X* W. P
  17.   )3 G# y( r1 B! R/ M' o
  18.   (vlax-safearray-put-element fd 0 "spline" )
    + B4 a& P& |+ U) g5 g1 E# L
  19.      ;用 vlax-safearray-put-element 函数为数组 fd 的第一个元素(索引号 0)赋值"spline"
    9 U* D( A9 f8 ?& j+ \/ m4 O
  20.   (vla-selectonscreen ss ft fd)  ;用 vla- 前缀函数调用 ss 对象的 selectonscreen 方法,由用户在屏幕上选取样条曲线对象
    ! _: _' K- }; K  `$ O7 }' Z
  21.   (if (= (vla-get-count ss) 2)  ;如果 ss 集合的 count 属性等于2(即用户选择了两条曲线)则执行下面的代码
    0 A: J+ s5 p' v7 v( W8 g7 s% U
  22.     (progn
    1 V  m' k3 Z: O5 Q: Z2 H( m3 Z; D
  23.       (setq c1 (vla-get-controlpoints ;用 vla-get- 前缀函数获取样条曲线对象的控制点坐标数组并赋值给c1(变量类型为变体,值为双精度数组)
    - o& |' B) x3 @9 G. K: Z( z
  24.    (vla-item ss 0) ;用 vla- 前缀函数调用集合对象的 item 方法,获取选择集中的索引号为 0 的样条曲线对象% h+ [: d. W- ~4 q
  25.         )8 U2 ~1 O2 a7 z* n6 K" Z
  26.      c2 (vla-get-controlpoints ;用 vla-get- 前缀函数获取样条曲线对象的控制点坐标数组并赋值给c2(变量类型为变体,值为双精度数组)0 f8 Q' d/ x# L+ V8 v3 u( }
  27.    (vla-item ss 1) ;用 vla- 前缀函数调用集合对象的 item 方法,获取选择集中的索引号为 1 的样条曲线对象' K+ }4 F5 T4 c8 u0 X6 r. o2 H
  28.         )6 d/ N% M/ h' M2 U1 H6 ]' {2 v
  29.      i  0   ;初始化外层循环变量) W/ ?2 x" E0 G3 e
  30.       )/ [& h8 Q& D, i% A
  31.       (repeat    ;循环,外层3 q1 @, B. N+ `4 L1 M. J. I
  32. (/ (1+ (vlax-safearray-get-u-bound
    ; e9 c& C8 `) D8 I; ?
  33.      ;用 vlax-safearray-get-u-bound 函数获取数组最大下标.第一个参数是数组,第二个参数是维数
    0 `0 w/ x( B1 |8 X- |
  34.    (vlax-variant-value c1);用 vlax-variant-value 函数获取变体变量 c1 的值(双精度数组)
    4 f" _! E) O8 Z0 H7 T; o9 i4 Q' F
  35.    19 ~; m6 V3 L) \2 q& N7 b
  36.         )  k5 i. `4 g; {' o/ O: w% C+ R
  37.     )
    ' Q- |* {# Z+ i; |# V5 R% J
  38.     33 C; Q6 o( i1 R6 }# v
  39. )    ;用数组最大下标加1再除以3,所得结果做为循环次数--数组中每三个元素为一组代表一个控制点
    8 u" G" |, K5 N: z: J3 s) ?: b8 q
  40.   (setq j 0)   ;初始化内层循环变量0 U) t: j* R- N: D3 r
  41.   (repeat6 H$ }; g  X  T: \8 e- n
  42.     (/ (1+ (vlax-safearray-get-u-bound
    1 `6 p( t. \, \
  43.      ;第二条样条曲线控制点坐标数组的最大下标加1再除以3,做为内层循环次数% X. X8 g7 }' U, j, i
  44.       (vlax-variant-value c2)1 t, l' g7 ]  B
  45.       1
    % M+ P/ p7 g1 w  E. C; Q
  46.     ); c. Y, r7 m& C; @4 p
  47.        )
    ' H" a. c! x; a2 ~" A% K% ^6 u
  48.        3
    4 D: q& p5 b+ j( T7 q
  49.     )" g2 o+ p/ s; y, s, E3 D
  50.      (setq d (distance  ;计算第一条曲线索引号为 i 的控制点到第二条曲线索引号为 j 的控制点之间的三维距离
    / I2 A& [0 H: t6 P3 s5 w1 H, h
  51.         (list  ;从 c1 数组中取出第一条曲线索引号为 i 的控制点的点表
    ( r2 U6 z8 u9 h9 f& K+ h, x
  52.    (vlax-safearray-get-element
      W5 q! E. y( H, H% f
  53.      ;用 vlax-safearray-get-element 函数获取数组中的指定的元素* M0 w7 }$ j; R
  54.      (vlax-variant-value c1) ;数组9 u$ p8 @3 h5 [7 A, t7 W
  55.      (* i 3) ;数组元素下标7 b( e2 H0 q7 ~& g. x- T4 X6 F$ }
  56.    )+ M. G1 ]0 s' |- o
  57.    (vlax-safearray-get-element! K, {( V1 m5 h0 l9 t/ B
  58.      (vlax-variant-value c1)
    + y) q( s- b/ F, N0 F, C# e
  59.      (+ (* i 3) 1)
    ) f2 }1 `6 o2 q4 \9 U( v' V' a
  60.    )# q, \: }2 `' Y. b9 p: D- y
  61.    (vlax-safearray-get-element% A3 ~- N; `: K1 G. K, U  R
  62.      (vlax-variant-value c1): l7 y* i0 D6 _/ ?2 P
  63.      (+ (* i 3) 2)# M" [7 D" }- @2 {: h
  64.    )
    : d+ E5 p  q# q* I* z* n8 S/ M
  65.         )
    2 e5 L7 W- T( r1 t, A$ M$ G2 C! N
  66.         (list  ;从 c2 数组中取出第二条曲线索引号为 j 的控制点的点表- ]3 B' Y7 l. f9 ~
  67.    (vlax-safearray-get-element. d- @) w  F3 V6 \& I9 f! D( I- x
  68.      (vlax-variant-value c2)' u3 Q; c, R2 Y0 w3 `
  69.      (* j 3)# K+ l) \) f4 Y; b! o/ l7 d! G) A! G
  70.    ): E5 @5 l' s0 H8 i7 W
  71.    (vlax-safearray-get-element
    ( Q; p6 @6 Q7 O  ^! H3 Q
  72.      (vlax-variant-value c2). P7 K; M) K/ g+ Y4 \; j
  73.      (+ (* j 3) 1)
    ; w1 |/ {9 P: @$ |% }
  74.    )
    , o% v, A' i/ d0 @; h
  75.    (vlax-safearray-get-element
    , k# j: X0 t* V) B6 o
  76.      (vlax-variant-value c2); S4 U# W# d3 D5 t1 g8 C" B
  77.      (+ (* j 3) 2)
    + Y: O$ d+ I/ _' q
  78.    )
    * @! b; i: V- m7 W
  79.         )
    0 z% N+ @# }- h* B3 v" C2 A
  80.       )
    7 s8 U/ L  }# D' Y) N4 ~+ O' \
  81.      ). \( i( I3 Z3 d7 Q
  82.      (if dmin   ;检查最小距离是否为 nil (是否首次)
      Q# N  u* `+ n
  83.        (if (> dmin d)  ;不是首次,比较计算所得的距离与已保存的最小距离,如发现更小的距离则保存
    4 k* m7 P! i0 G
  84.   (setq dmin d)% {7 v1 F* R; }; z
  85.        )
    0 ?$ P# F  D) V
  86.        (setq dmin d)  ;首次,把首个距离记录为最小距离" i$ h' o3 p) _
  87.      )
    # \6 z7 ~! I, ]0 K
  88.      (setq j (1+ j))  ;内层循环变量递增
    7 U! c. y7 Y+ E9 ~7 }6 g
  89.   )
    0 d) B1 L$ y! S2 R" A1 ^: A
  90.   (setq i (1+ i))  ;外层循环变量递增/ E5 `) j7 D( E
  91.       )
    - @  ^8 C( J9 {! g& V- H& t1 v
  92.     ); @* `4 h, W1 t1 [& o* s- ]2 Y2 n
  93.   )6 U& v+ O% t) r0 M" }5 i
  94.   (vla-delete ss)   ;用 vla- 前缀函数调用 ss 集合的 delete 方法,删除用过的选择集. u; m. m! T; y2 j5 }) S8 |( Y- K
  95.   (princ dmin)    ;命令行输出计算结果
    ! m/ O( e# \( H! F
  96.   (princ)    ;静默退出7 w& z# }6 n" t' V6 q
  97. )
    ; B2 _3 Z; s7 C2 \
复制代码
发表于 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 )

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