cumtjh 发表于 2011-7-2 20:45:30

沿着指定的路径曲线阵列问题?

本帖最后由 cumtjh 于 2011-7-3 16:35 编辑

曾经很火的晓东CAD论坛上有沿着指定的路径曲线阵列,现在只能从百度快照中搜寻它的影子了(http://cache.baidu.com/c?m=9d78d513d9d437ac4f9b9e690c66c0171c43f4102ba6a40209a08449e3732d465012e2ac56210772d1d27c1656fc1806a1e47132690c7af1dd8a9f4baea68f6d6acd30340756d01041850eafbc1a72873dc407a9e846fafbaa6fd6e88893880705dd537238dab29c5b7456972eb64f67f4a7ef43175b13bb&p=c06ac54ad2c019e60be2900c5442&user=baidu&fm=sc&query=%D1%D8%C7%FA%CF%DF%D5%F3%C1%D0+eachy&qid=9cb4a2ee027696c0&p1=3)

把使用源码展示出来,相信论坛上很多朋友都想实现沿任意路径阵列
1、路径阵列对话框版 (无源码)
http://bbs.mjtd.com/forum.php?mod=viewthread&tid=42551&highlight=%D5%F3%C1%D0
2、 [原创]沿曲线路径阵列程序(无源码)
http://bbs.mjtd.com/forum.php?mod=viewthread&tid=66190&highlight=%D5%F3%C1%D0
3、[讨论] 如何在曲线上实现阵列 (提问,无结果)
http://bbs.mjtd.com/forum.php?mod=viewthread&tid=85955&highlight=%D5%F3%C1%D0
4、[资源] 动态阵列(强烈推荐)(不是我想要的)
http://bbs.mjtd.com/forum.php?mod=viewthread&tid=85014&highlight=%D5%F3%C1%D0
5、[基础] 求助,那位大侠帮忙编一个方框阵列程序
http://bbs.mjtd.com/forum.php?mod=viewthread&tid=66333&highlight=%D5%F3%C1%D0
6、[趣味] 动态阵列
http://bbs.mjtd.com/forum.php?mod=viewthread&tid=85752&highlight=%D5%F3%C1%D0
7、[函数] [已解决]请高手帮忙做个简单的等分工具
http://bbs.mjtd.com/thread-87683-5-1.html


转入正题:沿着指定的路径曲线阵列问题,有源码,说需要配合配合XDRX_API B11208以上版本使用,不明白什么意思(哪里找XDRX_API B11208,这是个什么东西 会不会有cad版本限制)直接运行下面的Lsp会出错,不知道错误原因在哪里? 请大虾们帮忙看下小弟初学,在此先谢啦
源码如下:


;|
修改一个路径阵列的lisp [转贴 2005-10-10 21:24:41]   
命令:XDTB_ArrayByPath
功能:沿着指定的路径曲线(line,polyline,lwpolyline,spline,arc,circle,ellipse)
阵列选择的实体(选择集),可以保持实体相对路径的位置。

说明:程序计算出沿着指定路径可以阵列的最大数量,请输入小于等于这个最大值的数。

配合XDRX_API B11208以上版本使用

|;

(defun c:XDTB_ArrayByPath (/    $get_point    $remake_l
      ss    curve   dist    tf    num
      maxnumpnt    pntl    vect    xform
      vT1    vT2    mMat1   mMat2   mRot
      m0    mMat
   )
;;构造曲线上点pnt至曲线结束点间间隔为dist的点表,和曲线方向有关系;
;;对ARC沿逆时针方向的起点才是起始点,阵列时注意选择集的相对位置。
(defun $get_point (curve pnt dist / ptl pt dist1)
    (setq dist1 #xarray_dist);#xarray_dist 默认间隔
    ;从曲线起点dist1距离起计算一定间隔的点
    (while (setq pt (xdrx_curve_getpointatdist curve (+ dist dist1)))
      (setq dist1 (+ dist1 #xarray_dist)
   ptl   (cons (trans pt 1 0) ptl)
      )
    )
    (reverse ptl)
)
;;取出表l中起始的num个原子
(defun $remake_l (l num / ptl tf i)
    (setq ptl (reverse l))
    (if (< num (length l))
      (progn
(setq ptl nil)
(setq tf t)
(setq i 0)
(while tf
   (if (< i num)
   (setq ptl (cons (nth i l) ptl)
    i   (1+ i)
   )
   (setq tf nil)
   )
)
      )
    )
    (reverse ptl)
)
(prompt "\n请选取要沿路径阵列的实体<退出>")
(if (and
(setq ss (ssget))
(setq curve (car (xdrx_entsel
      "\n点取一个路径(曲线)<退出>:"
      '
       ((0 . "*line,arc,circle,ellipse"))
    )
      )
)
      )
    (progn
      (xdrx_begin)
      (xdrx_ucson)
      (if (not #xarray_dist)
(setq #xarray_dist 100)
      )
      (redraw curve 3)
      (initget 6)
      (if (setq dist (getreal (strcat "\n阵列距离<"
          (rtos #xarray_dist 2 2)
          ">:"
         )
       )
   )
(setq #xarray_dist dist)
      )
      (setq box      (xdrx_entity_box ss) ;选择集包围盒
   cen      (xdrx_midp (car box) (caddr box)) ;cen包围盒中心
   ;;包围盒中心cen至曲线上最近点pnt
   pnt      (xdrx_curve_getClosestPoint curve cen)
   ;;pnt点的切向量
   vec1   (xdrx_curve_getFirstDeriv curve pnt)
   pnt      (trans pnt 1 0) ;pnt(WCS)
   ;;点pnt至曲线起点的距离
   baseDist (xdrx_curve_GetDistAtPoint curve pnt)
   pntl   ($get_point curve pnt baseDist)
      )
      (initget 6)
      (setq maxnum (length pntl)
   tf    t
      )
      (while tf
(setq num (getint (strcat "\n输入数量(该路径上最大允许数量"
      (itoa maxnum)
      ")<"
      (itoa maxnum)
      ">:"
   )
    )
       num (if (not num)
      maxnum
      num
    )
       tf(if (> num maxnum)
      t
      nil
    )
)
      )
      (setq pntl($remake_l pntl num);构造指定数量的曲线间隔点表
   m0   (xdrx_matrix_identity)
   xForm (mapcar
      '(lambda (x) ;构造每个曲线点的矩阵
         (setq vFDeriv (xdrx_curve_GetFirstDeriv
         curve
         (trans x 0 1)
         ) ;点的切向量(WCS)
      mRot    (xdrx_vector_rotateTo vec1 vFDeriv);pnt向量旋转
      vT1   (mapcar '-
          (trans '(0 0 0) 0 1)
          (trans pnt 0 1)
         ) ;pnt位移向量
      vT2   (mapcar '- (trans x 0 1) (trans '(0 0 0) 0 1));点的偏移向量
      mMat1   (xdrx_matrix_setTranslation m0 vT1);pnt偏移矩阵
      mMat2   (xdrx_matrix_setTranslation m0 vT2);点的偏移矩阵
      mMat    (xdrx_matrix_product mRot mMat1);pnt处旋转
      mMat    (xdrx_matrix_product mMat2 mMat);矩阵相乘
         )
       )
      pntl
    )
      )
      ;;xForm-曲线上点与点pnt转换的矩阵表
      (mapcar
'(lambda (x)
    (xdrx_entity_transformedcopy ss x) ;构造选择集拷贝
)
xForm
      )
      (redraw curve 4)
      (xdrx_ucsoff)
      (xdrx_end)
    )
)
(princ)
)
;说明中说:这个lisp是eachy的作品,很好用,但是必需要和XDRX_API使用,arx是根据版本不同,加载不一样的
;arx,太麻烦了,打算把这里里面调用arx的修改掉,重新改一个不用调用的lisp。

在晓东工具箱中找到一个xdrx_api16.arx,加载到autocad2006 失败


20110703修改======================================================
经过发帖咨询,才知道上面代码不能直接用了,因为XDRX.ARX没有更新,而且即使更新,受版本限制通用性也比较差。只能另寻他路。但实现思想基本上是一样的,求大侠们帮我们解解。
想要实现下面的效果。
阵列对象:红色锚杆阵列路径:外圆弧(这只是个例子,还有其他形状曲线,总之是圆弧曲线)等分数:根据间距确定等分数 例如确定间距为16(1:50比例下标注为800),等分数为4600*3.14/800/2 四舍五入结果为9,阵列数为10。
预期效果图如下:


希望能实现路径阵列对话框版中的基本功能。
路径阵列对话框版
http://bbs.mjtd.com/forum.php?mod=viewthread&tid=42551&fromuid=269329
即:1、选择对象、路径、点选。
2、确定间距 由等分数确定或者等分间距确定。
3、随曲线。使用路径阵列对话框版输入的角度为-90度。这个角度-90是如何定义的我也没搞明白,试验得出结论。
4、该程序中其他功能就不需要了,只要前面三个基本功能。肯定大虾们出手相助,相信此贴必火。

该贴已经同步到 cumtjh的微博




tianbeiyuan 发表于 2019-11-23 20:20:04

有才华啊,我也在研究中。。

cjjh8301 发表于 2020-6-24 17:59:04

留下脚印,慢慢研究!!!

qq1254582201 发表于 2019-6-13 03:02:18

希望楼主找到答案

ZZXXQQ 发表于 2011-7-2 21:34:17

本帖最后由 ZZXXQQ 于 2011-7-3 08:51 编辑

程序调试通过。

;沿曲线阵列 明经 ZZXXQQ 2011.7.3
(defun c:ar_path ()
(setvar "CMDECHO" 0)
(if (progn (print "\n请选取要沿路径阵列的实体<退出>")
            (setq ss (ssget))) (progn
(if (and (setq s1 (entsel "\n点取一个路径(曲线)<退出>:"))
         (wcmatch (cdr(assoc 0 (entget (car s1))))"*LINE,ARC,CIRCLE,ELLIPSE")
         (setq dist (getdist "\n阵列距离 :"))) (progn
   (wx ss)
   (setq pc (polar pmin (angle pmin pmax) (/ (distance pmin pmax) 2)))
   (command "_measure" s1 dist)
   (setq ss2 (ssget "P"))
   (setq i -1)
   (setq pt (cdr(assoc 10 (entget(ssname ss2 0)))))
   (command "_COPY" ss "" "M" pc "end" pt)
   (repeat (sslength ss2)
    (setq pt (cdr(assoc 10 (entget(ssname ss2 (setq i (1+ i)))))))
    (command "non" pt)
   )
   (command "")
   (command "_ERASE" ss2 "")
))
))
(setvar "CMDECHO" 1)
(princ)
)
(defun wx (ss1);求选择集外形
(vl-load-com)
(setq minx0 1e6 miny0 1e6 maxx0 -1e6 maxy0 -1e6)
(setq i 0)
(repeat (sslength ss1)
(setq end (ssname ss1 i))
(Min_Max)
(setq i(1+ i))
)
(setq pmin (list minx0 miny0)
       pmax (list maxx0 maxy0))
)
;子程序,单个物体最大外形
(defun Min_Max()
(vla-getboundingbox(vlax-ename->vla-object end) 'minp 'maxp)
(setq minp (vlax-safearray->list minp)
       maxp (vlax-safearray->list maxp))
(setq minx (car minp)
       maxx (car maxp)
       miny (cadr minp)
       maxy (cadr maxp))
(if (> minx0 minx) (setq minx0 minx))
(if (> miny0 miny) (setq miny0 miny))
(if (< maxx0 maxx) (setq maxx0 maxx))
(if (< maxy0 maxy) (setq maxy0 maxy))
)

cumtjh 发表于 2011-7-2 22:00:27

本帖最后由 cumtjh 于 2011-7-2 22:04 编辑

ZZXXQQ 发表于 2011-7-2 21:34 http://space.mjtd.com/static/image/common/back.gif
程序未经调试。


运行 没有达到要求 屏幕上面都是点点
好像也没有选基点,已经是否随曲线 阵列
代码说真的没大看懂,只了解基本原理利用measure 其他就不知道了

例子 沿着圆弧拱阵列


zhynt 发表于 2011-7-2 23:09:29

XDRX_API B11208 这是传说中的晓东工具箱中的函数。有版本限制。好像04之后就没新版本了。

cumtjh 发表于 2011-7-2 23:12:31

本帖最后由 cumtjh 于 2011-7-3 15:11 编辑

zhynt 发表于 2011-7-2 23:09 http://space.mjtd.com/static/image/common/back.gif
XDRX_API B11208 这是传说中的晓东工具箱中的函数。有版本限制。好像04之后就没新版本了。

zhynt大侠能不能把我改写个,参照您帮人做的这个简单等分例子 http://bbs.mjtd.com/thread-87683-4-1.html
因为我选择的路径对象主要是半圆拱、圆弧拱、三星拱 (特点都是圆弧形状的),本身对lisp不熟悉,目前处于能看懂基本语法的代码的程度上,麻烦您出手相助下。

ZZXXQQ 发表于 2011-7-3 08:54:19

“沙发”程序调试好了。

cumtjh 发表于 2011-7-3 15:04:32

本帖最后由 cumtjh 于 2011-7-3 15:43 编辑

ZZXXQQ 发表于 2011-7-3 08:54 http://space.mjtd.com/static/image/common/back.gif
“沙发”程序调试好了。

Z版主,感谢您的调试,程序已经明显改善。但功能还没有实现,麻烦您再修改下:
1、图上没有实现等分曲线,这个我问题我不知道是怎么产生的,曲线被分的不均匀。比如我下图中阵列距离给的16但1:50量出来有的是749 ,有的791 ,还有1个1584 是其他的两倍。如下图所示产生不均匀阵列:

操作说明:阵列对象:选红色锚杆 路径:外圆弧 间距:16
Z版主,你看能不能这样实现等分,输入阵列间距后,计算下等分数n=取整(曲线长度/间距),取整函数满足四舍五入要求。最后将曲线等分成n,间距就与输入间距相近,沿曲线阵列后,图形满足对称。
预期效果:



2、沿阵列时没有指定阵列对象的基点,图上需要指定路径和阵列对象的焦点(也是这个阵列块对象的基点)作为阵列的基点。当前程序好像是以阵列对象的最左边点作为基点,然后将对象依次复制到路径分段点上。
3、阵列过程中,阵列对象没有随着曲线旋转。希望能够实现阵列对象随曲线旋转逆时针旋转,阵列对象与路径方向夹角为90度。
要求有点多,难度也比较大,目的就一个沿着路径阵列。麻烦高手再帮忙啊
再次感谢Z版主,祝您愉快!


ZZXXQQ 发表于 2011-7-3 22:14:09

我完全是的按照原来的程序改写的,原程序未要求对曲线等分。
如果要等分曲线,将定长画点改成定数等分divide就行。
原程序未见与曲线相切的计算,因此程序未写。这部分请自行搜索下论坛,有曲线切线的程序。

caoyin 发表于 2011-7-3 22:28:00

其实不用xdcad的函数,用vlax-curve函数处理起来也相当简单的

cumtjh 发表于 2011-7-4 12:15:07

ZZXXQQ 发表于 2011-7-3 08:54 static/image/common/back.gif
“沙发”程序调试好了。

老大,麻烦你抽空回头看看啊
页: [1] 2 3
查看完整版本: 沿着指定的路径曲线阵列问题?