TO:"sailorcwx"兄和"xxsheng兄"程序OK,大恩不言谢啦!!!
本帖最后由 作者 于 2008-6-13 23:08:06 编辑 <br /><br /> <p>TO:"sailorcwx"兄和"xxsheng兄"程序OK,大恩不言谢啦!!!</p> <p>...多段线要“平躺”在XY面上(不要“站”着的,.</p><p>楼主真诙谐,帮你顶上去</p> <p>临睡前一顶....</p><p>这么多人关注,可就是没有人回帖啊,我知道这个很烦琐,一般人都不轻易出手的,还请大家不厌其烦帮帮忙啊,也许对您是没什么大不了的,可它对我实在是太重要了,谢谢各位务必出手...</p> 本帖最后由 作者 于 2008-5-30 8:20:34 编辑测试 <p>没弄懂什么样的叫躺着,什么样的叫站着,什么样的叫蹲着</p><p>这些线不是根据你的坐标文件来绘制的么,难道还要修改?</p> <p><strong><font face="Verdana" color="#61b713">xxsheng兄,非常感谢您的出手相助,您的方案已经下载,晚上告诉您测试结果.</font></strong></p><p><strong><font face="Verdana" color="#61b713">sailorcwx兄,先谢谢您的关注.</font></strong></p><p><strong><font face="Verdana" color="#61b713">是这样的:读取数据后绘制出的三维多段线都是空间线,我的目的是要把那些空间的三维多段线在不改变其原有型状(长度)的前提下通过三维旋转等手段,使三维多段线上的每个点Z为0(或Z相同)</font></strong></p> <p><strong><font face="Verdana" color="#61b713">xxsheng兄,您好,经过测试发现程序有如下问题:</font></strong></p><p><strong><font face="Verdana" color="#61b713">1.加载程序提示无法加载,后用visual lisp检查提示多了个括号,后查证是第212行的括号多出,去除后问题解决.</font></strong></p><p><strong><font face="Verdana" color="#61b713">2.程序加载运行后发现您编写的功能没有奏效,后将第208行程序移到212行后问题解决</font></strong></p><p><strong><font face="Verdana" color="#61b713">3.利用程序所绘制的三维多义线中第20根没有"放平"于XY面上,后经多次试验问题依旧,麻烦您查查看什么原因.</font></strong></p><p><strong><font face="Verdana" color="#61b713">4.小弟不才,实在不只如何编那段一行绘制满20根后自动跳行程序,还希望您帮忙实现了.</font></strong></p><p><strong><font face="Verdana" color="#61b713">再次感谢您的帮助.</font></strong></p> 本帖最后由 作者 于 2008-5-28 9:23:07 编辑 <br /><br /> 我的浏览器好像发帖就是多出逗号,不要改顺序,,,把注释的弄掉再试一下吧,208行和212行是不能调换,,,,<br/>至于换行,,加一个判断根数就可以了,不知道你前面总数的变量是什么,自己写吧,,,,,<br/><br/><br/>顺便说一下,我发现很多人图纸的版本都很高,现在好像都能另存版本的,每次都要转换成低版本实在是无聊的......<br/> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;<br/>;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; <br/>(defun CommaFirst (s2) ; ;CommaFirst函数,来判断变量是否到达了以逗号为开头,如果则去掉字符串逗号前面的子字符串。<br/> (while<br/> (and (/= (substr s2 1 1) ",")<br/> (/= (substr s2 1 1) "")<br/> ) ;判断变量是否到达了以逗号为开头,如果是则退出循环。<br/> (setq s2 (substr s2 2)) ;去掉字符串逗号前面的子字符串。<br/> )<br/>)<br/>;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;<br/>;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; <br/>(defun DeleteBlank (s3) ; ;DeleteBlank函数,去掉字符串最前面的空格。<br/> (if<br/> (= " " (substr s3 1 1)) ; ;判断字符串前面是否有空格。如果有则执行while循环,否则执行(setq s3 s3)这一。<br/> (while<br/> (= " " (substr s3 1 1))<br/> (setq s3 (substr s3 2)) ;去掉字符串最前面的一个空格,如果去掉一个空格后已无空格,则返回已经去掉空格的字符串。<br/> )<br/> (setq s3 s3) ;不是以空格开头的字符串,则返回其原值。<br/> )<br/>)<br/>;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;<br/>(defun c:draw (/ f savecmdecho n startp)<br/> (prompt<br/> "\n此程序读取各行数据格式为:参数1,参数2,参数3,数学坐标X值,数学坐标Y值,Z值。")<br/> (setq f (getfiled "选取文件" " " "txt" 2));设置变量f作为逗号分隔符文件全称及其路径的字符串值。<br/> (prompt "\n正在读取文件中的数据...")<br/> (princ)<br/> (setq f(open f "r") ; ;用open函数来打开文件,并把打开的文件指针传递给变量f。<br/> savecmdecho(getvar "cmdecho")<br/> saveosmode (getvar "osmode")<br/> savesnapmode (getvar "snapmode")<br/> s6 nil<br/> s7 nil<br/> n 0)<br/> (setvar "cmdecho" 0)<br/> (setvar "osmode" 0)<br/> (setvar "snapmode" 0)<br/> (while ;循环读取行数据并画点标注的函数。<br/> (setq s (read-line f)) ;此行用来判断是否读完了文件,如果是则返回nil。<br/> (setq s (DeleteBlank s)) ;调用DeleteBlank函数,去掉变量s前面的空格。<br/> (while<br/> (= s "") ; ;如果变量s不是空字符串,则跳出此循环,否则读取下一行数据。<br/> (setq s (read-line f)) ;读取下一行数据。<br/> (if ;判断是否已经读到文件的末尾。<br/> (= s nil)<br/> (princ "\已经完成读取\n")<br/> (setq s (DeleteBlank s)) ;未读到文件的末尾,去掉字符串前的一个空格。<br/> )<br/> )<br/><br/> (while<br/> (= (substr s 1 1) ",") ; ;如果变量s不是逗号,则跳出此循环,否则读取下一行。<br/> (setq s (read-line f)) ;读取下一行数据。<br/><br/> (while<br/> (= s "") ; ;如果变量s不是空字符串,则跳出此循环,否则读取下一行数据。<br/> (setq s (read-line f)) ;读取下一行数。<br/> (if ;判断是否已经读到文件的末尾。<br/> (= s nil)<br/> (princ "\已经完成读取\n")<br/> (setq s (DeleteBlank s)) ;未读到文件的末尾,去掉字符串前的一个空格。<br/> )<br/> )<br/> )<br/> (if<br/> (/= s nil) ;如果不是文件的末尾,则调用Draw函数画点、标注。<br/> (Draw s) ;调用画点及标注函数,调用一次来画并标注一个点。<br/> (princ)<br/> )<br/> (if<br/> (/= s nil) ;如果不是文件的末尾,则累加读入的点数。<br/> (setq n (+ n 1))<br/> )<br/> )<br/> (close f) ;关闭文件。<br/> (setvar "cmdecho" savecmdecho)<br/> (setvar "osmode" saveosmode)<br/> (setvar "snapmode" savesnapmode)<br/> (prompt (strcat "\n数据已经读取完毕;共读入<" (itoa n) ">根三维多段线" ) )<br/> (princ)<br/>)<br/>(defun Draw (s0 / s1 k1 k2 k3 k4 k5 k6 k7 k8<br/> k9 k10 k11 k12 k13 k14 xA yA zA xB yB<br/> zB xC yC zC xD yD zD ptA ptB ptC ptD<br/> DH D1 N1 s4 s5 s6 s7 plent v1 v2 norv rotatev cosv<br/> ang) ;定义画点及标注函数。<br/> (setq s1 s0<br/> s1 (CommaFirst s1) ;调用CommaFirst函数,来判断变量是否到达了以逗号为开头,如果则掉字符串逗号前面的子字符串。<br/> ;并把CommaFirst函数的返回值赋值给变量s1。<br/> k1(- (strlen s0) (strlen s1)) ;计算出字符串中第1个子字符串(即点号)的长度。<br/> DH(substr s0 1 k1) ;把字符串中第1个子字符串赋值给变量DH。<br/> s1(substr s1 2) ;把以逗号开头的字符串的最前面的逗号去掉。<br/> s1(CommaFirst s1) ;调用CommaFirst函数<br/> k2(- (strlen s0) (strlen s1)) ;计算出字符串中第2个子字符串(即点号)的长度。<br/> D1(substr s0 (+ k1 2) (- k2 (+ k1 1))) ;把字符串中第2个子字符串赋值给变量D1,保留后续另用。<br/> s1(substr s1 2) ;把以逗号开头的字符串的最前面的逗号去掉。<br/> s1(CommaFirst s1) ;调用CommaFirst函数<br/> k3(- (strlen s0) (strlen s1)) ;计算出字符串中第3个子字符串(即点号)的长。 <br/> R(substr s0 (+ k2 2) (- k3 (+ k2 1))) ;把字符串中第3个子字符串赋值给变量R,保留后续另用。<br/> s1(substr s1 2) ;把以逗号开头的字符串的最前面的逗号去掉。<br/> s1 (CommaFirst s1) ;调用CommaFirst函数<br/> k4 (- (strlen s0) (strlen s1)) ;计算出字符串中第3个子字符串(即点号)的长度。<br/> N1(substr s0 (+ k3 2) (- k4 (+ k3 1))) ;把字符串中第3个子字符串赋值给变量N1,保留后续另用。<br/> s1(substr s1 2) ;把以逗号开头的字符串的最前面的逗号去掉。<br/> s1 (CommaFirst s1) ;调用CommaFirst函数<br/> k5 (- (strlen s0) (strlen s1)) ;计算出字符串中第4个子字符串(即点号)的长度。<br/> xA(substr s0 (+ k4 2) (- k5 (+ k4 1))) ;把字符串中第4个子字符串赋值给变量xA。<br/> s1(substr s1 2) ;把以逗号开头的字符串的最前面的逗号去掉。<br/> s1 (CommaFirst s1) ;调用CommaFirst函数<br/> k6 (- (strlen s0) (strlen s1)) ;计算出字符串中第5个子字符串(即点号)的长度。<br/> yA(substr s0 (+ k5 2) (- k6 (+ k5 1))) ;把字符串中第5个子字符串赋值给变量yA。<br/> s1(substr s1 2) ;把以逗号开头的字符串的最前面的逗号去掉。<br/> s1 (CommaFirst s1) ;调用CommaFirst函数<br/> k7 (- (strlen s0) (strlen s1)) ;计算出字符串中第6个子字符串(即点号)的长度。<br/> zA(substr s0 (+ k6 2) (- k7 (+ k6 1))) ;把字符串中第6个子字符串赋值给变量zA。<br/> s1(substr s1 2) ;把以逗号开头的字符串的最前面的逗号去掉。<br/> s1 (CommaFirst s1) ;调用CommaFirst函数<br/> k8 (- (strlen s0) (strlen s1)) ;计算出字符串中第7个子字符串(即点号)的长度。<br/> xB(substr s0 (+ k7 2) (- k8 (+ k7 1))) ;把字符串中第7个子字符串赋值给变量xz。<br/> s1 (substr s1 2) ;把以逗号开头的字符串的最前面的逗号去掉。<br/> s1 (CommaFirst s1) ;调用CommaFirst函数<br/> k9 (- (strlen s0) (strlen s1)) ;计算出字符串中第8个子字符串(即点号)的长度。<br/> yB(substr s0 (+ k8 2) (- k9 (+ k8 1))) ;把字符串中第8个子字符串赋值给变量yB。<br/> s1 (substr s1 2) ;把以逗号开头的字符串的最前面的逗号去掉。<br/> s4 s1<br/> s1 (CommaFirst s1)) ;调用CommaFirst函数<br/> (if (= s1 "") (setq zB s4 s6 s1 ))<br/> (if (/= s1 "")<br/> (progn<br/> (setq k10 (- (strlen s0) (strlen s1)) ;计算出字符串中第9个子字符串(即点号)的长度。<br/> zB(substr s0 (+ k9 2) (- k10 (+ k9 1)));把字符串中第9个子字符串赋值给变量zB。<br/> s1 (substr s1 2) ;把以逗号开头的字符串的最前面的逗号去掉。<br/> s1 (CommaFirst s1) ;调用CommaFirst函数<br/> k11 (- (strlen s0) (strlen s1));计算出字符串中第10个子字符串(即点号)的长度。<br/> xC (substr s0 (+ k10 2) (- k11 (+ k10 1))) ;把字符串中第10个子字符串赋值给变量xC。<br/> s1 (substr s1 2) ;把以逗号开头的字符串的最前面的逗号去掉。<br/> s1 (CommaFirst s1) ;调用CommaFirst函数<br/> k12 (- (strlen s0) (strlen s1));计算出字符串中第11个子字符串(即点号)的长度。<br/> yC (substr s0 (+ k11 2) (- k12 (+ k11 1)));把字符串中第11个子字符串赋值给变量yC。<br/> s1 (substr s1 2) ;把以逗号开头的字符串的最前面的逗号去掉。<br/> s5 s1<br/> s1 (CommaFirst s1) ) ;调用CommaFirst函数<br/> (if (= s1 "")(setq zC s5 s7 s1))<br/> (if (/= s1 "")<br/> (progn<br/> (setq k13 (- (strlen s0) (strlen s1)) ;计算出字符串中第12个子字符串(即点号)的长度。<br/> zC (substr s0 (+ k12 2) (- k13 (+ k12 1)));把字符串中第12个子字符串赋值给变量zC。<br/> s1 (substr s1 2) ;把以逗号开头的字符串的最前面的逗号去掉。<br/> s1 (CommaFirst s1) ;调用CommaFirst函数<br/> k14 (- (strlen s0) (strlen s1));计算出字符串中第13个子字符串(即点号)的长度。<br/> xD (substr s0 (+ k13 2) (- k14 (+ k13 1)));把字符串中第13个子字符串赋值给变量xD。<br/> s1 (substr s1 2) ;把以逗号开头的字符串的最前面的逗号去掉。<br/> s1 (CommaFirst s1) ;调用CommaFirst函数<br/> k15 (- (strlen s0) (strlen s1));计算出字符串中第14个子字符串(即点号)的长度。<br/> yD (substr s0 (+ k14 2) (- k15 (+ k14 1)));把字符串中第14个子字符串赋值给变量yD。<br/> s1 (substr s1 2) ;把以逗号开头的字符串的最前面的逗号去掉。<br/> zD s1) ;把字符串中第15个子字符串赋值给变量zD。<br/> )<br/> )<br/> )<br/> )<br/> (setq xA (atof xA) yA (atof yA) zA (atof zA)) ;把字符串转换为实数。<br/> (setq xB (atof xB) yB (atof yB) zB (atof zB)) ;把字符串转换为实数。<br/> (if<br/> (/= s6 "")<br/> (progn<br/> (setq xC (atof xC) yC(atof yC) zC(atof zC));把字符串转换为实数。<br/> (if<br/> (/= s7 "")<br/> (setq xD (atof xD) yD (atof yD) zD (atof zD)) ;把字符串转换为实数。<br/> )<br/> )<br/> )<br/> (setq ptA (list xA yA zA) ;创建点列表。<br/> ptB (list xB yB zB)<br/> ) ;创建点列表。<br/> (if (/= s6 "")<br/> (progn<br/> (setq ptC (list xC yC zC)) ;创建点列表。<br/> (if (/= s7 "")<br/> (setq ptD (list xD yD zD)) ;创建点列表。<br/> )<br/> )<br/> )<br/> (if (= s6 "")<br/> (progn<br/> (command ".3dpoly" ptA ptB "")<br/> (setq plent(entlast))<br/> )<br/> (if (= s7 "")<br/> (progn<br/> (command ".3dpoly" ptA ptB ptC "")<br/> (setq plent(entlast))<br/> )<br/> (if (/= s7 "")<br/> (progn<br/> (command ".3dpoly" ptA ptB ptC ptD "")<br/> (setq plent(entlast))<br/> )<br/> )<br/> )<br/> )<br/> ; ;;;上面增加一个获得绘制的多段线----------------<br/> ; ;;;下面开始进行平面放置(旋转)------------------<br/> (if plent<br/> (if (vlax-curve-isPlanar plent);判断是否可平面化---<br/> (progn<br/> (if (>= (vlax-curve-getEndParam plent) 2)<br/> (progn;多于两个点,判断面--------------<br/> (setq v1(mapcar '- ptB ptA)<br/> v2(mapcar '- ptC ptA)<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" plent "" ptA (mapcar '+ ptA rotatev) (* 180 (/ ang pi)))<br/> )<br/> )<br/> )<br/> (progn;两个点判断线-------------------<br/> (setq v1(mapcar '- ptB ptA))<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" plent "" ptA (mapcar '+ ptA '(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" plent "" ptA (mapcar '+ ptA rotatev) (* 180 (/ ang pi)))<br/> )<br/> )<br/> )<br/> )<br/> )<br/> )<br/> )<br/> )<br/> )<br/> ; ;;;;下面开始进行平面放置(移动)----------------------------------------<br/> ; ;;;;没有详细读上面的代码,所以换行处理没有做,只是分开了位置,以便观察---<br/> ; ;;;;这个你自己写吧,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,---------<br/> (if startp (setq startp (mapcar '+ startp '(4200 0 0))) (setq startp '(0 0 0)))<br/> (if plent<br/> (command "._move" plent "" ptA 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/>;;第20根多段线不是一个平面,,,,,,,,,,,,,,,,,,,,,根本就没有办法平放在一个平面,,,,所以没有处理!<br/> <p>不知道楼主试过没有</p><p>用二维多段线实现的就是躺在XY平面或平行XY平面的,不知道楼主是不是要这种效果</p><p>而用三维多段线实现,还要旋转,太麻烦了</p><p></p>