tsotzo Posted March 11, 2017 Posted March 11, 2017 (edited) Hello, I made the following: (defun c:MC () (setq au* (getvar "aunits")) (setq osm* (getvar "osmode")) (setvar "aunits" 3) (setvar "osmode" 0) (setq pt1 (getpoint)) (setq pt2 (getpoint pt1)) (defun MdatDst () (setq dsC (/ (distance pt1 pt2) 2)) (setq angC (+ (angle pt1 pt2) (/ pi 2))) (setq ptC (polar pt1 (angle pt1 pt2) dsC)) (command "pline" pt1 pt2 "" "-text" "J" "MC" (polar ptC angC 5.5) 7.2 (angle pt1 pt2) (fix (distance pt1 pt2))) ) (MdatDst) (setvar "aunits" au*) (setvar "osmode" osm*) ) Is there a better way to apply this function to given couples of points (about 100) inside a bigger routine, than to write the same formula again and again? Thank you, Kostas Edited March 21, 2017 by SLW210 Added Tags Quote
SLW210 Posted March 13, 2017 Posted March 13, 2017 Please read the Code Posting Guidelines and edit your Code to be included in Code Tags.[NOPARSE] Your Code Here[/NOPARSE] = Your Code Here Quote
tsotzo Posted March 13, 2017 Author Posted March 13, 2017 Thank you SLW, you are right! So I post it again: (defun c:MC () (setq au* (getvar "aunits")) (setq osm* (getvar "osmode")) (setvar "aunits" 3) (setvar "osmode" 0) (setq pt1 (getpoint)) (setq pt2 (getpoint pt1)) (defun MdatDst () (setq dsC (/ (distance pt1 pt2) 2)) (setq angC (+ (angle pt1 pt2) (/ pi 2))) (setq ptC (polar pt1 (angle pt1 pt2) dsC)) (command "pline" pt1 pt2 "" "-text" "J" "MC" (polar ptC angC 5.5) 7.2 (angle pt1 pt2) (fix (+ 0.5 (distance pt1 pt2)) ) ) ) (MdatDst) (setvar "aunits" au*) (setvar "osmode" osm*) ) Is there a better way to apply this function to given couples of points (about 100) inside a bigger routine, than to write the same formula again and again? Kostas Quote
Lee Mac Posted March 13, 2017 Posted March 13, 2017 Given an arbitrary point set, how would the program determine how to pair up the points? Quote
tsotzo Posted March 13, 2017 Author Posted March 13, 2017 Given an arbitrary point set, how would the program determine how to pair up the points? We know the pairs of points from before, and we give their order. For example we have the pair (pt1 pt2), then we have (pt3 pt4), (pt5 pt6) and so on. In our case we take the first pair, pt1 and pt2, and we find their distance, then draw a line from one to the other and write above their midpoint their distance. For doing that we write some lines of code. Now, we want apply the same code lines to pt3 and pt4, pt5 and pt6 and so on. So the question is, instead of writing again and again the same code lines (for every different pair of points) is there a more efficient way to do that? (I am sure there is but I just don't know it ). And another question that relate to the above. How could we apply a lisp routine inside another lisp routine? Thanks. Quote
Grrr Posted March 13, 2017 Posted March 13, 2017 Your problem reminds me of this thread. Simply construct assoc list of point pairs, like: '((pt1 pt2) (pt2 pt3) (pt3 pt4) (pt4 pt5) (pt5 pt6) ....) Quote
Lee Mac Posted March 13, 2017 Posted March 13, 2017 We know the pairs of points from before, and we give their order. For example we have the pair (pt1 pt2), then we have (pt3 pt4), (pt5 pt6) and so on. You will need to post the format of your data in order for us to advise an appropriate function structure. I'm assuming you have a list containing sub-lists of length 2, themselves containing lists representing 2D or 3D points? i.e. (((x y z) (x y z)) ((x y z) (x y z)) ... ) Quote
hanhphuc Posted March 14, 2017 Posted March 14, 2017 We know the pairs of points from before, and we give their order. For example we have the pair (pt1 pt2), then we have (pt3 pt4), (pt5 pt6) and so on.In our case we take the first pair, pt1 and pt2, and we find their distance, then draw a line from one to the other and write above their midpoint their distance. For doing that we write some lines of code. Now, we want apply the same code lines to pt3 and pt4, pt5 and pt6 and so on. So the question is, instead of writing again and again the same code lines (for every different pair of points) is there a more efficient way to do that? (I am sure there is but I just don't know it ). And another question that relate to the above. How could we apply a lisp routine inside another lisp routine? Thanks. not sure if OP means picking pairs manually? perhaps a "while" function (setq pt1 (getpoint)) ([color="blue"]while[/color] (and pt1 (setq pt2 (getpoint pt1))) (MdatDst) (setq pt1 pt2) ) Quote
BIGAL Posted March 14, 2017 Posted March 14, 2017 (edited) Also you have a defun inside a defun, make it seperate (defun MdatDst (pt pt2 / dsc angc ptc ) (setq dsC (/ (distance pt1 pt2) 2)) (setq angC (+ (angle pt1 pt2) (/ pi 2))) (setq ptC (polar pt1 (angle pt1 pt2) dsC)) (command "pline" pt1 pt2 "" "-text" "J" "MC" (polar ptC angC 5.5) 7.2 (angle pt1 pt2) (fix (+ 0.5 (distance pt1 pt2)) ) ) ) (defun c:MC () (setq au* (getvar "aunits")) (setq osm* (getvar "osmode")) (setvar "aunits" 3) (setvar "osmode" 0) (setq lst (list (list 0 0)(list 30 50)(list 70 40)(list 90 80))) (setq x 0) (repeat (/ (length lst) 2) (setq pt1 (nth x lst)) (setq pt2 (nth (+ x 1)lst)) (MdatDst pt1 pt2 ) (setq x (+ x 2)) ) (setvar "aunits" au*) (setvar "osmode" osm*) (princ) ) Edited March 15, 2017 by BIGAL version 2 Quote
tsotzo Posted March 14, 2017 Author Posted March 14, 2017 Thank you all, for your answers!... but maybe my poor english cannot make it clear. Let's say we have pt1=0,0 pt2=30,50 pt3=70,40 and pt4=90,80. (defun c:MC () (setq au* (getvar "aunits")) (setq osm* (getvar "osmode")) (setvar "aunits" 3) (setvar "osmode" 0) (setq pt1 (list 0 0)) (setq pt2 (list 30 50)) (setq dsC (/ (distance pt1 pt2) 2)) (setq angC (+ (angle pt1 pt2) (/ pi 2))) (setq ptC (polar pt1 (angle pt1 pt2) dsC)) (command "pline" pt1 pt2 "" "-text" "J" "MC" (polar ptC angC 5.5) 7.2 (angle pt1 pt2) (fix (+ 0.5 (distance pt1 pt2)) ) ) (setq pt3 (list 70 40)) (setq dsC (/ (distance pt2 pt3) 2)) (setq angC (+ (angle pt2 pt3) (/ pi 2))) (setq ptC (polar pt2 (angle pt2 pt3) dsC)) (command "pline" pt2 pt3 "" "-text" "J" "MC" (polar ptC angC 5.5) 7.2 (angle pt2 pt3) (fix (+ 0.5 (distance pt2 pt3)) ) ) (setq pt4 (list 90 80)) (setq dsC (/ (distance pt3 pt4) 2)) (setq angC (+ (angle pt3 pt4) (/ pi 2))) (setq ptC (polar pt3 (angle pt3 pt4) dsC)) (command "pline" pt3 pt4 "" "-text" "J" "MC" (polar ptC angC 5.5) 7.2 (angle pt3 pt4) (fix (+ 0.5 (distance pt3 pt4)) ) ) (setvar "aunits" au*) (setvar "osmode" osm*) (princ) ) It's 3 times the same routine with different points. How could we make it more efficiently? Thank you. Quote
Lee Mac Posted March 15, 2017 Posted March 15, 2017 Consider the following: (defun c:mc ( / lst ) (mapcar 'midtxt (setq lst '((0 0)(30 50)(70 40)(90 80))) (cdr lst)) (princ) ) (defun midtxt ( pt1 pt2 / ang ins ) (setq ang (angle pt1 pt2) ins (polar (mapcar '(lambda ( a b ) (/ (+ a b) 2.0)) pt1 pt2) (+ ang (/ pi 2.0)) 5.5) ) (entmake (list '(000 . "LWPOLYLINE") '(100 . "AcDbEntity") '(100 . "AcDbPolyline") '(090 . 2) '(070 . 0) (cons 010 pt1) (cons 010 pt2) ) ) (entmake (list '(000 . "TEXT") '(040 . 7.2) '(072 . 1) '(073 . 2) (cons 010 ins) (cons 011 ins) (cons 050 ang) (cons 001 (itoa (fix (+ 0.5 (distance pt1 pt2))))) ) ) ) Quote
tsotzo Posted March 15, 2017 Author Posted March 15, 2017 Thanks Bigal! Yes this is working very good! I just made 2 changes: instead of (repeat (/ (length lst) 2) I have put (repeat (- (length lst) 1) and instead of (setq x (+ x 2)) ==> (setq x (+ x 1)) And now is working perfectly. Thank you! Quote
tsotzo Posted March 15, 2017 Author Posted March 15, 2017 Thank you Lee Mac! Your code just blew my mind!! ( ) and it's a matter of study for me, to have a better understanding of how mapcar and lambda are working! It is also look so "clean" to create entities without using "command". Thank you so much! Quote
Lee Mac Posted March 16, 2017 Posted March 16, 2017 You're welcome! - Feel free to ask if you are unsure of the code. Quote
tsotzo Posted March 17, 2017 Author Posted March 17, 2017 You're welcome! - Feel free to ask if you are unsure of the code. Thank you Lee Mac! I appreciate that! Quote
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.