QQ登录

只需一步,快速开始

登录 | 注册 | 找回密码

三维网

 找回密码
 注册

QQ登录

只需一步,快速开始

展开

通知     

全站
goto3d 说: 版主微信号:caivin811031;还未入三维微信群的小伙伴,速度加
2022-07-04
全站
goto3d 说: 此次SW竞赛获奖名单公布如下,抱歉晚了,版主最近太忙:一等奖:塔山817;二等奖:a9041、飞鱼;三等奖:wx_dfA5IKla、xwj960414、bzlgl、hklecon;请以上各位和版主联系,领取奖金!!!
2022-03-11
查看: 4248|回复: 4
收起左侧

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

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

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

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

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

spline.dwg

172.45 KB, 下载次数: 8

发表于 2011-7-30 02:53:11 | 显示全部楼层
本帖最后由 woaishuijia 于 2011-8-4 09:43 编辑 ; Z$ f8 ^9 D( D% X3 B

  1. ( T$ H8 a2 h4 |, a, H8 S
  2. (defun c:aaa (/ ss ft fd c1 c2 i j dmin d)
    9 s- I3 x& o, U5 |0 K
  3.   (vl-load-com)    ;将 Visual LISP 扩展功能加载到 AutoLISP 4 G9 s' p! ]8 c9 ]8 |" q2 J2 u& s* y
  4.   (setq     ;将一个或多个符号的值设置为相应表达式的值
    ) T7 j# w. F2 s6 U8 h* H, p
  5.     ss (vla-add    ;用 vla- 前缀函数调用 activeX 对象(下面的代码--该方法的第一个参数--指定的选择集集合对象)的 add 方法
      T/ f+ Y. g, s% t: ]( D
  6.   (vla-get-selectionsets  ;用 vla-get- 前缀函数获取 activeX 对象--当前文档对象--的属性:选择集集合子对象,即使用 add 方法的集合对象4 j9 E* ^) U/ Q
  7.     (vla-get-activedocument ;用 vla-get- 前缀函数获取 activeX 对象--当前 AutoCAD 应用程序对象--的属性:活动文档子对象9 e+ K1 W. v; I9 X/ j
  8.       (vlax-get-acad-object) ;用 vlax-get-acad-object 函数检索当前 AutoCAD 任务中的顶层 AutoCAD 应用程序对象
    & z, D4 \5 P3 N/ `7 o/ q# @
  9.     )3 Y: ~+ c2 p5 |: T
  10.   )0 e3 Z$ Q7 t' W0 o9 K
  11.   "ss"    ;选择集名称  i3 ~$ I8 J5 \4 `0 \, @- H9 e
  12.        )
    ( Y; I- W# P1 y5 e
  13.     ft (vlax-make-safearray vlax-vbinteger '(0 . 0))
    % n9 b, Z, u# S: V
  14.      ;定义选择集过滤器的过滤类型数组.用 vlax-make-safearray 函数创建安全数组,整形,一维,一个元素(0 to 0)., [0 |" T& q  `6 ^: t9 h
  15.     fd (vlax-make-safearray vlax-vbvariant '(0 . 0))6 o, L5 s: r+ B! S! q# m" C
  16.      ;定义选择集过滤器的过滤值数组.用 vlax-make-safearray 函数创建安全数组,变体,一维,一个元素(0 to 0).+ \0 a) U8 O% a4 S" I
  17.   )
    + d: l1 x3 o) W' y
  18.   (vlax-safearray-put-element fd 0 "spline" )
    6 D# r, N! @/ F3 T3 e$ c
  19.      ;用 vlax-safearray-put-element 函数为数组 fd 的第一个元素(索引号 0)赋值"spline"
    0 r, ?, g; G0 ^9 H! K2 d$ E3 Y* s7 @
  20.   (vla-selectonscreen ss ft fd)  ;用 vla- 前缀函数调用 ss 对象的 selectonscreen 方法,由用户在屏幕上选取样条曲线对象
    * ]5 H& k. e0 C" S  U# O
  21.   (if (= (vla-get-count ss) 2)  ;如果 ss 集合的 count 属性等于2(即用户选择了两条曲线)则执行下面的代码
    9 h5 |% ~- z2 g( G5 i' N1 d
  22.     (progn- x- R7 ]$ `7 ^& m8 {' `
  23.       (setq c1 (vla-get-controlpoints ;用 vla-get- 前缀函数获取样条曲线对象的控制点坐标数组并赋值给c1(变量类型为变体,值为双精度数组)
    6 i6 K% o/ d5 d/ N
  24.    (vla-item ss 0) ;用 vla- 前缀函数调用集合对象的 item 方法,获取选择集中的索引号为 0 的样条曲线对象
    : e  h( b9 \1 p  ]. {$ H( K! ~
  25.         )! c. a; V2 s; J0 E6 X6 ]- L8 b9 S
  26.      c2 (vla-get-controlpoints ;用 vla-get- 前缀函数获取样条曲线对象的控制点坐标数组并赋值给c2(变量类型为变体,值为双精度数组)% b7 }8 }) b* B& U% k
  27.    (vla-item ss 1) ;用 vla- 前缀函数调用集合对象的 item 方法,获取选择集中的索引号为 1 的样条曲线对象' n/ L1 X  ?; K/ x$ [# M
  28.         )/ Z. V; {) i: h6 l; R# |
  29.      i  0   ;初始化外层循环变量- `% ~& p8 S4 _5 a
  30.       )
    7 V" O1 M9 v/ `% k, P: ~
  31.       (repeat    ;循环,外层
    / ~* l' O" F$ z
  32. (/ (1+ (vlax-safearray-get-u-bound
    3 o0 l: |' Y+ M# n$ [8 }  k
  33.      ;用 vlax-safearray-get-u-bound 函数获取数组最大下标.第一个参数是数组,第二个参数是维数3 S! a7 D' |: B$ ?4 o' W
  34.    (vlax-variant-value c1);用 vlax-variant-value 函数获取变体变量 c1 的值(双精度数组)
    , T6 \6 v: H" V* {: ]
  35.    1% K8 S1 b0 {% e3 z* w- Y0 J$ I
  36.         )
    ! ?9 C( y5 ~# M& D" {- _
  37.     )
    ( z8 t5 ^" U% W9 o
  38.     3
    ( i1 e/ d( _2 L$ g
  39. )    ;用数组最大下标加1再除以3,所得结果做为循环次数--数组中每三个元素为一组代表一个控制点
    7 u/ I# x- w, Z  R+ f
  40.   (setq j 0)   ;初始化内层循环变量
    ! o% w( M. m0 g6 N9 e- b3 |
  41.   (repeat4 d& C- V' [/ T! I* U1 _  ~
  42.     (/ (1+ (vlax-safearray-get-u-bound
    & Z& ^7 u5 a& c7 V. ?
  43.      ;第二条样条曲线控制点坐标数组的最大下标加1再除以3,做为内层循环次数* v5 N+ N/ O0 h: r! W' r
  44.       (vlax-variant-value c2)
    % G1 t- s. v( H( E
  45.       1
    . D0 E: l- K, x6 F  O9 U! K
  46.     )8 X2 Q3 }/ g- F, Z3 l  B$ l
  47.        )
    # f9 @- P; G' f+ |
  48.        3
    , |1 l1 a7 S9 @& u( R# h2 {6 z
  49.     )! O8 |$ r: p6 {) G  W
  50.      (setq d (distance  ;计算第一条曲线索引号为 i 的控制点到第二条曲线索引号为 j 的控制点之间的三维距离' u1 @0 l9 R6 }
  51.         (list  ;从 c1 数组中取出第一条曲线索引号为 i 的控制点的点表
    3 G8 Q$ j) ?3 O
  52.    (vlax-safearray-get-element
    5 {' X" y) Z5 X2 C
  53.      ;用 vlax-safearray-get-element 函数获取数组中的指定的元素
    ; G. k, G7 P; ?  `
  54.      (vlax-variant-value c1) ;数组2 g2 [/ S' e; R# ~! [/ @
  55.      (* i 3) ;数组元素下标
    0 I& q" d  x& C& D) J1 h
  56.    )( B+ @5 r# r) G6 w5 q! @+ y/ Y
  57.    (vlax-safearray-get-element
    0 c+ _* Y2 X' j! v# ]
  58.      (vlax-variant-value c1)- e9 Z* {- \9 y, j5 d( [- u4 q
  59.      (+ (* i 3) 1)
    5 K) L: M8 U9 V4 d4 }4 W
  60.    )# a( A5 x6 V8 H  B
  61.    (vlax-safearray-get-element
    : |! P% C" @& K1 d, Y- }
  62.      (vlax-variant-value c1)4 k5 U4 U3 B5 Z% ]4 u" s# }1 v% D
  63.      (+ (* i 3) 2): T/ h0 I. u# J
  64.    )/ V$ D4 N( G5 o  r' S
  65.         )" y1 W! b3 ?( A' n: ?- B
  66.         (list  ;从 c2 数组中取出第二条曲线索引号为 j 的控制点的点表
    7 a% l/ r0 a) u) @9 [
  67.    (vlax-safearray-get-element  H. Z  e7 M0 E2 h( u
  68.      (vlax-variant-value c2)
    ' {) G8 ^' k( S! V* r
  69.      (* j 3)
    % [  k; t( I7 L1 W3 [7 n' t
  70.    )
    5 B' l' v0 v% a2 R/ f
  71.    (vlax-safearray-get-element
    , ^+ M& _$ C  r, l# {
  72.      (vlax-variant-value c2)2 i7 {- O3 ]/ V- y
  73.      (+ (* j 3) 1)
    ' v+ N) s; o9 A" W4 p
  74.    )
    ( `! V# n4 R* C' J8 c2 t
  75.    (vlax-safearray-get-element
    4 h( u; A3 W3 {( u9 O3 D9 ]5 t
  76.      (vlax-variant-value c2)
    " ]1 E+ y' }4 @4 W! @. z
  77.      (+ (* j 3) 2)- f/ R; }) @9 ]! z
  78.    )! t: i$ w$ _' k7 P, T
  79.         )
    ( L8 o# U* r# P/ S3 F
  80.       ). }7 ]9 X: O- v" l+ T8 S
  81.      )6 ?( Q% T0 R/ |7 u2 J1 @- Z  i7 W) B
  82.      (if dmin   ;检查最小距离是否为 nil (是否首次)
    / C1 o; _& W% T
  83.        (if (> dmin d)  ;不是首次,比较计算所得的距离与已保存的最小距离,如发现更小的距离则保存
    / n0 \, _, Y6 l  d$ J$ b
  84.   (setq dmin d)
    8 y# H# a: A' H/ f3 r3 k3 ]- t- l
  85.        ). T+ s' o8 x, n6 @1 N8 P5 z( t
  86.        (setq dmin d)  ;首次,把首个距离记录为最小距离
    , T4 C$ r. j5 W' }. B
  87.      )# j7 ?$ {8 v- m3 r7 V" E- P
  88.      (setq j (1+ j))  ;内层循环变量递增; F" F; a' t" J
  89.   )
    # q) m: v' b" {
  90.   (setq i (1+ i))  ;外层循环变量递增
    8 u! p" J+ L+ O% w# c. k+ E5 m9 L; C8 [
  91.       )
    ; P1 ~; ~2 i; G* |+ f' e: y* g! r
  92.     )
    7 J% b$ c5 I9 d- o( p  b+ i
  93.   )
    6 f2 G$ e4 e* Y* H: a4 ]1 W1 |
  94.   (vla-delete ss)   ;用 vla- 前缀函数调用 ss 集合的 delete 方法,删除用过的选择集
    + d, I9 h( |1 v4 h- s4 W/ N
  95.   (princ dmin)    ;命令行输出计算结果* N3 ?0 m( l. W: \2 N
  96.   (princ)    ;静默退出, f: I3 v/ F/ A4 S0 P
  97. )2 X* Z/ R2 K( X" z
复制代码
发表于 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备13008828号-1 )

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