linhui12
发表于 2008-5-28 12:44:00
<p>xxsheng兄,您的程序可以用了,辛苦了,谢谢您啊.第20根的确不是平面的一根管,是我看错了. </p><p>目前尚有一个问题困饶着我:上面程序能否实现先将空间线上的点旋转,最后再用PL或3DPL线连接画出线呢(即程序最后再执行:command ".3dpoly" ptA ptB ptC ptD "")因为我想获取平放后的PTA,PTB,PTC,PTD的值,要怎么实现? </p><p>另:换行的变量为:"DH",如果DH>20即下移一行,DH>40下移两行,DH>60类退...</p>
linhui12
发表于 2008-5-28 13:18:00
sailorcwx发表于2008-5-28 11:47:00static/image/common/back.gif不知道楼主试过没有用二维多段线实现的就是躺在XY平面或平行XY平面的,不知道楼主是不是要这种效果而用三维多段线实现,还要旋转,太麻烦了
<p><font face="宋体">sailorcwx兄,您的思路我不是很理解,如果感兴趣也请您写写看,我也总觉的我的程序写的过于烦琐了,很不简练,主要是我才接触LISP编程,都是靠坛里的兄弟帮忙写的程序原形,我只懂弄一些小修改</font></p><p><strong>我数据的格式为:</strong></p><strong><p><strong>1,219,300,3,11567,8720,9970,12323,8720,9970,13013,8030,9970,13365,8030,9970</strong></p></strong><p><strong>DH,D1,R,N1,(此后为坐标)</strong></p><p><strong>程序最后实现描点:PTA,PTB或PTA,PTB,PTC或PTA,PTB,PTC,PTD画线</strong></p>
sailorcwx
发表于 2008-5-28 14:31:00
<p>帮你简化一步,数据点的读取<br/>(read (strcat "(" (vl-string-translate "," " " data) ")"))</p><p>其中data是read-line返回的字符串,剔出第一,第二,第三,第四个元素,剩下的就是顶点坐标了</p>
linhui12
发表于 2008-5-28 15:27:00
<font face="Verdana" color="#61b713"><strong>sailorcwx兄,小弟惭愧,受了您的"渔"却不知如何使用,烦请介绍一下</strong><font color="#000000">(read (strcat "(" (vl-string-translate "," " " data) ")")),应该替换掉我程序中的哪一部分代码??</font></font>
linhui12
发表于 2008-5-29 22:52:00
<p><font color="#ff3300" size="4">如今就差一小步,</font><font color="#ff3300" size="4">烦请哪位大虾帮忙编一下:</font></p><p><font color="#ff3300" size="4">1."自动换行".变量是"DH",如果DH>20即下移一行且向首移20行,DH>40下移两行且向首移20行,DH>60类推...</font></p><p><font color="#ff3300" size="4">2.请<strong><font face="Verdana" color="#ff0000">xxsheng兄或哪位好心兄弟帮忙改改,令程序先将PTA,PTB,PTC,PTD点放平于XY面,而后再用PL或3DPL将这些点连接,最后输出线(目的是想获取放平后的PTA,PTB,PTC,PTD坐标)</font></strong></font></p>
xxsheng
发表于 2008-5-30 08:31:00
你到底想要什么?<br/>1. (if startp<br/> (if (zerop(rem dh 20))<br/> (setq startp (mapcar '+ startp '(4200 3400 0)));;这里的4200和3400,代表x轴和y轴的间距-<br/> (setq startp (mapcar '+ startp '(4200 0 0)))<br/> )<br/> (setq startp '(0 0 0)))<br/>2.本身你的坐标到底怎么得到的?直接从坐标转换也是可以做到的(把rotate3d的步骤生成三维旋转矩阵,坐标点乘矩阵,就是一样了),自己想想怎么作吧.如果想在现在的基础上获得作标点的话,查找下"获得所有顶点"之类的,这里到处都是.<br/>
xxsheng
发表于 2008-5-30 08:33:00
;;哈,不好意思,,应该是y轴减<br/>(if startp<br/> (if (zerop(rem dh 20))<br/> (setq startp (mapcar '+ startp '(4200 -3400 0)))<br/> (setq startp (mapcar '+ startp '(4200 0 0)))<br/> )<br/> (setq startp '(0 0 0)))
linhui12
发表于 2008-5-30 18:16:00
<p><strong><font face="Verdana" color="#ff0000">xxsheng前辈,我本身的坐标就是从模型中提取的,编程的目的是为了出零件的小样图,所以放平后移动到每个方框内的多义先还须另外处理,所以还许获取他们的顶点坐标.</font></strong></p><p><font face="Verdana"><font color="#ff0000"><strong>请问如何作到"</strong>直接从坐标转换也是可以做到的<strong>"呢,还请帮忙写写吧,对我实在重要,还有楼上程序加到您的程序后出现换行后X坐标没归0,烦请改改.</strong></font></font></p><p><font face="Verdana"><strong>也多谢朋友们的关注,还请大家帮忙出出力,有好方案就贴上来</strong></font></p>
xxsheng
发表于 2008-5-31 09:38:00
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;<br/>(defun c:draw ( / cz startp f tmptxt tmp rcz n plent oldosmode oldcmdecho)<br/> (setq oldosmode(getvar "osmode")<br/> oldcmdecho(getvar "cmdecho")<br/> )<br/> (setvar "osmode" 0)<br/> (setvar "cmdecho" 0)<br/> (prompt "\n此程序读取各行数据格式为:参数1,参数2,参数3,数学坐标X值,数学坐标Y值,Z值。")<br/> (setq f(getfiled "选取文件" " " "txt" 2))<br/> (prompt "\n正在读取文件中的数据...")<br/> (setq f(open f "r"))<br/> (while (setq tmptxt(read-line f))<br/> (cond<br/> ((setq tmp(read(strcat "(" (vl-string-translate "," " " tmptxt)")"))) (setq cz (cons tmp cz)))<br/> (t nil)<br/> )<br/> )<br/> (close f)<br/> (setq cz (reverse cz))<br/> ;;上面读取文件为表下面开始进行绘制准备和坐标点转换为平面------<br/> (if startp nil (setq startp '(-4200 0 0)))<br/> (setq rcz(mapcar 'cddddr cz));;去除前三个参数,只留下坐标点----<br/> ;;下面分离坐标出来--------------------------------------------<br/> (setq rcz(mapcar '(lambda(x)<br/> (if tmptxt (setq tmptxt nil))<br/> (while (setq tmptxt (cons (list (car x) (cadr x) (caddr x)) tmptxt)<br/> x (cdddr x)))<br/> (reverse tmptxt)<br/> ) rcz))<br/> ;;下面先创建3dpl再旋转,再获得旋转后的坐标--------------------<br/> ;;不生成pl,直接用矩阵的方法等我有空再写一个------------------<br/> (setq n -1)<br/> (setq allplst(mapcar '(lambda(x)<br/> (apply 'command (cons "._3dpoly" x))(command "")<br/> (setq plent(entlast) n(1+ n))<br/> (planar plent);平面化----------------<br/> (getplst plent)<br/> ) rcz))<br/> (princ (strcat "\n总共生成" (itoa (1+ n)) "条多段线!"))<br/> ;这个allplst;;;这个就是所有多段线的新的端点-----------------<br/> (setvar "osmode" oldosmode)<br/> (setvar "cmdecho" oldcmdecho)<br/> (princ)<br/>)<br/>(defun getplst(pl / i plst tmp)<br/> (setq i -1)<br/> (while (setq tmp(vlax-curve-getPointAtParam pl (setq i(1+ i))))<br/> (setq plst(cons tmp plst))<br/> )<br/> (reverse plst)<br/>)<br/>(defun planar(pl / no1p v1 v2 norv rotatev cosv ang)<br/> ; ;;;上面增加一个获得绘制的多段线----------------<br/> ; ;;;下面开始进行平面放置(旋转)------------------<br/> (if pl<br/> (if (vlax-curve-isPlanar pl);判断是否可平面化---<br/> (progn<br/> (if (>= (vlax-curve-getEndParam pl) 2)<br/> (progn;多于两个点,判断面------------------<br/> (setq no1p(car x))<br/> (setq v1(mapcar '- (cadr x) no1p)<br/> v2(mapcar '- (caddr x) no1p)<br/> norv(>*> v1 v2);计算面的法向量----<br/> )<br/> (if (not (equal (setq rotatev(>*> norv '(0 0 1))) '(0 0 0) 1e-3));判断是否已经在xy面上--<br/> (progn;不在xy平面上,需要旋转------<br/> ;首先获得旋转角度和旋转轴-------<br/> (setq cosv(/ (>&> norv '(0 0 1)) (distance norv '(0 0 0))))<br/> (setq ang(acos cosv))<br/> ;;这里可以生成旋转矩阵或者利用rotate3d-----------------------<br/> (command "._rotate3d" pl "" no1p (mapcar '+ no1p rotatev) (* 180 (/ ang pi)))<br/> )<br/> )<br/> )<br/> (progn;两个点判断线-------------------<br/> (setq no1p(car x))<br/> (setq v1(mapcar '- (cadr x) no1p))<br/> (if (not (equal (>&> v1 '(0 0 1)) 0 1e-3))<br/> (progn;;线不在xy平面上------------<br/> (if (equal (setq rotatev(>*> v1 '(0 0 1))) '(0 0 0) 1e-3)<br/> (progn;和z轴平行绕x轴或者y轴都可以,先假定绕x轴旋转---------<br/> (command "._rotate3d" pl "" no1p (mapcar '+ no1p '(1 0 0)) 90)<br/> )<br/> (progn;不和z轴平行,计算旋转轴和旋转角度--------------------<br/> (setq cosv(/ (>&> v1 '(0 0 1)) (distance v1 '(0 0 0))))<br/> (setq ang(acos cosv))<br/> (command "._rotate3d" pl "" no1p (mapcar '+ no1p rotatev) (* 180 (/ ang pi)))<br/> )<br/> )<br/> )<br/> )<br/> )<br/> )<br/> )<br/> )<br/> )<br/> (if (and (zerop(rem n 20)) (> n 0))<br/> (setq startp (list 0 (- (cadr startp) 6800) 0))<br/> (setq startp (mapcar '+ startp '(4200 0 0)))<br/> )<br/> (if pl<br/> (command "._move" pl "" (car x) startp)<br/> )<br/>)<br/>(defun >*>(>a >b / a1 a2 a3 b1 b2 b3)<br/> (cond<br/> ((= 2 (length >a));; x1*y2 - x2*y1<br/> (setq a1(car >a)<br/> a2(cadr >a)<br/> b1(car >b)<br/> b2(cadr >b))<br/> (- (* a1 b2) (* a2 b1))<br/> )<br/> (t<br/> (setq a1(car >a)<br/> a2(cadr >a)<br/> a3(caddr >a)<br/> b1(car >b)<br/> b2(cadr >b)<br/> b3(caddr >b))<br/> (list (- (* a2 b3)(* a3 b2))<br/> (- (* a3 b1) (* a1 b3))<br/> (- (* a1 b2) (* a2 b1)))<br/> )<br/> )<br/>)<br/>(defun >&>(>a >b)<br/> (apply '+ (mapcar '* >a >b))<br/>)<br/>(defun acos(cosv)<br/> (cond<br/> ((equal 1 cosv 1e-5) 0)<br/> ((equal -1 cosv 1e-5) pi)<br/> (t (- (/ pi 2) (atan (/ cosv (expt (- 1 (* cosv cosv)) 0.5)))))<br/> )<br/>)<br/>;;你要的旋转后的所有多段线的坐标在变量allplst里面,直接利用矩阵的方法等我什么时候空闲再说<br/>
linhui12
发表于 2008-5-31 12:02:00
<p><strong><font face="Verdana" color="#ff0000">xxsheng你好厉害,原来我需要12k多的程序被你简化一下就不到5k了,而且功能是一样的!!!</font></strong></p><p><font><strong>烦请xxsheng及各位朋友帮忙写出</strong><font color="#0938f7">"直接利用矩阵的方法"</font><font color="#ff0000"><strong>,也就是先将顶点坐标平面化>>移动>>最后用LINE将顶点坐标连接.(因后续程序要用)</strong></font></font></p><p><font><font color="#ff0000"><strong>另:请各位在数据分离时顺便将前面三个参数分别赋值给DW,R,N(也因后续开发中要用)</strong></font></font></p><strong><font face="Verdana" color="#ff0000"><p><font face="Verdana" color="#ff0000"><strong>不好意思了,在下又提了过分要求,</strong></font>以上所求不仅可以解决在下难题,也可以为各位看官提供新的解题思路和方法,何乐而不为呢,拜托各位!</p></font></strong>