samifox Posted March 2, 2013 Share Posted March 2, 2013 Hi using acad 2010 I want to draw a line and have a lisp to divide it equally but with a few restrictions 1. Each segment wont be less than 6 and/or more than 8 2. If the total length of theline cannot result 6-8, prompt and cancel Thanks Shay Quote Link to comment Share on other sites More sharing options...
marko_ribar Posted March 2, 2013 Share Posted March 2, 2013 (edited) (defun c:lindiv6-8 ( / ptst pten d n6 n8 n1 n2 n k stpt enpt ) (setq ptst (getpoint "\nStart point of line : ")) (setq pten (getpoint ptst "\nEnd point of line : ")) (setq ptst (trans ptst 1 0) pten (trans pten 1 0)) (setq d (distance ptst pten)) (setq n6 (/ d 6.0)) (setq n8 (/ d 8.0)) (cond ( (equal n6 (float (fix n6)) 1e-15) (setq n n6) ) ( (and (null n) (> n6 1.0)) (setq n1 (fix n8) n2 (+ (fix n6) 1)) (repeat (+ (- n2 n1) 1) (if (<= 6.0 (if (/= n1 0) (/ d (float n1)) 0.0) 8.0) (setq n n1) (if (null n) (setq n nil)) ) (setq n1 (1+ n1)) ) ) ( (< n6 1.0) (setq n nil) ) ) (if n (progn (setq k -1.0) (repeat (fix n) (setq stpt (mapcar '+ ptst (mapcar '* (mapcar '/ (mapcar '- pten ptst) (list n n n)) (list (setq k (1+ k)) k k)))) (setq enpt (mapcar '+ stpt (mapcar '/ (mapcar '- pten ptst) (list n n n)))) (entmake (list '(0 . "LINE") '(62 . 1) (cons 10 stpt) (cons 11 enpt) (list 210 0.0 0.0 1.0))) ) ) (prompt "\nOriginal line couldn't be divided into lines with 6-8 units lengths criteria") ) (princ) ) Edited March 2, 2013 by marko_ribar code changed - first condition in (cond...) Quote Link to comment Share on other sites More sharing options...
samifox Posted March 2, 2013 Author Share Posted March 2, 2013 (edited) :DAWSOME:D i actually cant use it without completly understanding it. i got lost in your last paragraph ;******************linediv68**************************************** ;variables ;ptst - start point of the line ;pten - end point of the line ;d - total length of the line ;n6 - devition by 6 ;n8 - devition by 8 (defun c:lindiv6-8 ( / ptst pten d n6 n8 n1 n2 n k stpt enpt ) ;getting the total length of the line (setq ptst (getpoint "\nStart point of line : ")) (setq pten (getpoint ptst "\nEnd point of line : ")) (setq ptst (trans ptst 1 0) pten (trans pten 1 0)) (setq d (distance ptst pten)) ;getiing unrestricted devition (setq n6 (/ d 6.0)) (setq n8 (/ d 8.0)) ;i got lost here (cond ( (equal n6 1.0 1e-15);what is 1e-15??? (setq n 1.0) ) ( (and (null n) (> n6 1.0)) (setq n1 (fix n8) n2 (+ (fix n6) 1)) (repeat (+ (- n2 n1) 1) (if (<= 6.0 (if (/= n1 0) (/ d (float n1)) 0.0) 8.0) (setq n n1) (if (null n) (setq n nil)) ) (setq n1 (1+ n1)) ) ) ( (< n6 1.0) (setq n nil) ) ) (if n (progn (setq k -1.0) (repeat (fix n) (setq stpt (mapcar '+ ptst (mapcar '* (mapcar '/ (mapcar '- pten ptst) (list n n n)) (list (setq k (1+ k)) k k)))) (setq enpt (mapcar '+ stpt (mapcar '/ (mapcar '- pten ptst) (list n n n)))) (entmake (list '(0 . "LINE") '(62 . 1) (cons 10 stpt) (cons 11 enpt) (list 210 0.0 0.0 1.0))) ) ) (prompt "\nOriginal line couldn't be divided into lines with 6-8 units lengths criteria") ) (princ) ) Thanks Shay Edited March 2, 2013 by samifox Quote Link to comment Share on other sites More sharing options...
marko_ribar Posted March 2, 2013 Share Posted March 2, 2013 I've changed exactly that condition that was confusing you - like you smell for an error... The mistake was in condition that n6 variable should be checked for any complete number (1,2,3,...) in first condition so if your original line had exactly length 18.0, it should divide it into 3 segments of 6.0 length as n6 would be exactly n6=3.0... 1e-15 is number (to be exact - very small number 0.000000000000001) that represents tolerance fuzz factor supplied to (equal) function for comparison of equality of 2 main argument numbers (equal number1 number2 fuzz)... If number1 is the same as number2 and difference between them is in range from 0.0 to 1e-15 (fuzz), then (equal number1 number2 fuzz) should return T... Note that when (equal) function is used with supplied 3rd fuzz argument - then fuzz argument must be in range from 0.0 to 1.0 for function (equal) to operate correctly... So, because fuzz argument is from 0.0 to 1.0 it is common that this small number is supplied in 1e-decimals behind 0.0 form... If you want to express very big number, than you should use 1e+decimal places in front of 0.0... M.R. Quote Link to comment Share on other sites More sharing options...
samifox Posted March 4, 2013 Author Share Posted March 4, 2013 hi marko just for you to know, i couldnt sleep tonight so i tryed to analyze the code line by line, after 2 hours i realize that (with my minor knowladge in lisp) i just cant. i wish i could ask more simple and less nasted or havy commanted version of the code... Thanks S Quote Link to comment Share on other sites More sharing options...
ReMark Posted March 4, 2013 Share Posted March 4, 2013 samifox: Did the lisp work or didn't it? Quote Link to comment Share on other sites More sharing options...
David Bethel Posted March 4, 2013 Share Posted March 4, 2013 Could the test be : (if (or (zerop (rem distance 8.)) (>= (rem distance 8.) 6.)) then do the math else alert) -David Quote Link to comment Share on other sites More sharing options...
samifox Posted March 4, 2013 Author Share Posted March 4, 2013 of course it did!!! its greate but i want to understand how it worked Quote Link to comment Share on other sites More sharing options...
paulmcz Posted March 4, 2013 Share Posted March 4, 2013 This also works. Take a look. (defun c:dx (/ a as b bs c d dv dvs u) ;(while (setq a (getpoint "\n Start point: ")) (setq b (getpoint a "\n Endpoint: ") d (distance a b) dv (fix (/ d ) dvs (/ d dv) ) (if (> dvs (setq dv (fix (/ d 7)) dvs (/ d dv) ) ) (if (> dvs (setq dv (fix (/ d 6)) dvs (/ d dv) ) ) (setq u (angle a b) as a bs (polar a u dvs) c 1 ) (cond ((< d 12.0) (alert "Line is smaller than 12 units")) ((> 18 d 16) (alert "Line can't be divided as required")) (t (repeat dv (entmake (list (cons 0 "line") (cons 10 as) (cons 11 bs) ;(cons 62 c) ) ) (setq c (+ 1 c) as bs bs (polar a u (* dvs c)) ) ) ) ) (princ) ) Quote Link to comment Share on other sites More sharing options...
samifox Posted March 4, 2013 Author Share Posted March 4, 2013 Would you mind explain the code? Quote Link to comment Share on other sites More sharing options...
paulmcz Posted March 4, 2013 Share Posted March 4, 2013 Well, this is very low-tech solution. I thought the code is so primitive, it wouldn't need any explanation. What specific part of the code you need help with? Quote Link to comment Share on other sites More sharing options...
paulmcz Posted March 5, 2013 Share Posted March 5, 2013 Here is the code explanation: (defun c:dx (/ a as b bs c d dv dvs u) ;(while [color="red"]; uncomment if needed, repeats dx function until pressing enter on "Start point" prompt[/color] (setq a (getpoint "\n Start point: ")) (setq b (getpoint a "\n Endpoint: ") d (distance a b)[color="red"]; line length[/color] dv (fix (/ d )[color="red"]; division integer = number of line segments to be drawn[/color] dvs (/ d dv)[color="red"]; line segment length[/color] ) (if (> dvs [color="red"]; if line segment>8 get shorter one[/color] (setq dv (fix (/ d 7))[color="red"]; division integer = number of line segments to[/color] [color="red"]be drawn[/color] dvs (/ d dv)[color="red"]; segment length[/color] ) ) (if (> dvs [color="red"]; if line segment>8 get shorter one[/color] (setq dv (fix (/ d 6))[color="red"]; division integer = number of line segments to be drawn[/color] dvs (/ d dv)[color="red"]; segment length[/color] ) ) (setq u (angle a b)[color="red"]; line segments angle[/color] as a [color="red"]; start point of first line segment[/color] bs (polar a u dvs)[color="red"]; end point of first line segment[/color] c 1 [color="red"]; counter, starting at 1[/color] ) [color="red"];;; first 2 conditions bellow are testing if line length is disqualified for required division, triggers alert, if it is[/color] (cond ((< d 12.0) (alert "Line is shorter than 12 units"))[color="red"]; line shorter than 12 can't be used[/color] ((> 18 d 16) (alert "Line can't be divided as required"))[color="red"]; line greater than 16 and shorter than 18 can't be used[/color] (t [color="red"]; true condition[/color] (repeat dv [color="red"]; repeat by above calculated number of segments[/color] (entmake (list (cons 0 "line")[color="red"]; entmake = drawing a line segment[/color] (cons 10 as)[color="red"]; entmake[/color] (cons 11 bs)[color="red"]; entmake[/color] )[color="red"]; entmake[/color] )[color="red"]; entmake > line segment has been drawn[/color] (setq c (+ 1 c)[color="red"]; counter increased by 1[/color] as bs [color="red"]; setting start point for the next line segment[/color] bs (polar a u (* dvs c))[color="red"]; setting end point for the next line segment[/color] ) )[color="red"]; end of repeat loop[/color] )[color="red"]; end of true condition[/color] ) [color="red"]; end of cond function[/color] [color="red"]; uncomment if needed, repeats dx function until pressing enter on "Start point" prompt[/color] (princ) ) Quote Link to comment Share on other sites More sharing options...
samifox Posted March 18, 2013 Author Share Posted March 18, 2013 hi im reediting the code to suite my program need (based on marko_ribar code). the first thing i thinking is how to reuse the code in other programs so i avoiding specific function. few question/problems since its gonna be 100's of centimeters ive change from decimal numbers to real. since than it yell an error. why? i need all variables to be global so i can access their value any time i need in the program life. i find myself defining local and global twice, what practice i should use in order to have those variables global but still have in mind that one day ill need those function in other program? (setq TotaLng 0) (setq minLng 600) (setq maxLng 800) (defun c:main () (setq totLng (getTotalLength)) (setq segLng (getSegmentLength)) (princ) ) (defun getTotalLength ( / ptst pten TotaLng minLng maxLng n1 n2 n k stpt enpt ) (princ "getting the total length of the line") (setq ptst (getpoint "\nStart point of line : ")) (setq pten (getpoint ptst "\nEnd point of line : ")) (setq ptst (trans ptst 1 0) pten (trans pten 1 0)) (setq TotaLng (distance ptst pten)) ) (defun getSegmentLength (/ totLng minLng maxLng ) ;getiing unrestricted devition (setq minLng (/ totLng minLng)) (setq maxLng (/ totLng maxLng)) (princ) ) Thanks Shay Quote Link to comment Share on other sites More sharing options...
samifox Posted March 20, 2013 Author Share Posted March 20, 2013 please make this code work over 600 and 800 restriction rather 6 8 Thanks Shay Quote Link to comment Share on other sites More sharing options...
samifox Posted April 14, 2013 Author Share Posted April 14, 2013 (defun c:lindiv6-8 ( / ptst pten d n6 n8 n1 n2 n k stpt enpt ) (setq ptst (getpoint "\nStart point of line : ")) (setq pten (getpoint ptst "\nEnd point of line : ")) (setq ptst (trans ptst 1 0) pten (trans pten 1 0)) (setq d (distance ptst pten)) (setq n6 (/ d 6.0)) (setq n8 (/ d 8.0)) (cond ( (equal n6 (float (fix n6)) 1e-15) (setq n n6) ) ( (and (null n) (> n6 1.0)) (setq n1 (fix n8) n2 (+ (fix n6) 1)) (repeat (+ (- n2 n1) 1) (if (<= 6.0 (if (/= n1 0) (/ d (float n1)) 0.0) 8.0) (setq n n1) (if (null n) (setq n nil)) ) (setq n1 (1+ n1)) ) ) ( (< n6 1.0) (setq n nil) ) ) (if n (progn (setq k -1.0) (repeat (fix n) (setq stpt (mapcar '+ ptst (mapcar '* (mapcar '/ (mapcar '- pten ptst) (list n n n)) (list (setq k (1+ k)) k k)))) (setq enpt (mapcar '+ stpt (mapcar '/ (mapcar '- pten ptst) (list n n n)))) (entmake (list '(0 . "LINE") '(62 . 1) (cons 10 stpt) (cons 11 enpt) (list 210 0.0 0.0 1.0))) ) ) (prompt "\nOriginal line couldn't be divided into lines with 6-8 units lengths criteria") ) (princ) ) Hi can please explain the code ill tell what i understand get start,end and calculate the distance devide the total distance by 6 and by 8 and than im lost hope you can make my day again! Shay Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.