MichaelAllfire Posted October 6, 2016 Posted October 6, 2016 Hi all, I am looking for help in accomplishing something way above my skill level. I have attached a sketch to make it easier to understand. What I am trying to do is the following ... I am trying to measure a distance between two points, P1 & P2 respectively, and divide that distance into equally spaced areas, separated by xlines. However, the distances from the 1st and last xlines to points P1 and P2 need to be HALF the distance between each of the xlines. To choose the number of spaces and lines required, I need to divide the P1,P2 distance by a value (eg 4200) and round that value up to the nearest whole number. This number will be the number of xlines required between the two points. The xlines need to run perpendicularly to the direction of the P1,P2 distance measured. Thanks in advance! Quote
marko_ribar Posted October 6, 2016 Posted October 6, 2016 To choose the number of spaces and lines required, I need to divide the P1,P2 distance by a value (eg 4200) and round that value up to the nearest whole number. This number will be the number of xlines required between the two points. Don't you just need to supply number of XLINEs (eg 4200) without any calculations? Measurement X can be then calculated from number of XLINEs : X = p1p2 / 4200 and then you have X/2 from ends... Quote
MichaelAllfire Posted October 6, 2016 Author Posted October 6, 2016 Don't you just need to supply number of XLINEs (eg 4200) without any calculations? Measurement X can be then calculated from number of XLINEs : X = p1p2 / 4200 and then you have X/2 from ends... Hi Marko, thanks for the reply! Sorry, I think I butchered my posts with a few deletes and edits, not used to posting on forums. Unfortunately I don't think it can be approached that way. The 4200 value is the maximum spacing I am allowed to have between two points (represented by the xlines). I divide the distance by this maximum spacing, and this gives me the EXACT number of points I will have (eg distance of 10,000mm divided by 4,200 gives 2.38 points). However, I can't have parts of a point, so I need to round up to 3. To work out the spacing normally, I would then divide the 10,000 by 3, and this would be the spacing between xlines, with half that value being on the ends to points P1 and P2. The rest of the command is drawing the xlines at those locations. If there is a way to do the first calculation as part of the command, it would speed up the process a fair bit. Quote
marko_ribar Posted October 6, 2016 Posted October 6, 2016 Now I don't understand... Test this quickly made version and let me know if that's it : (defun c:xlindistdiv ( / p1 p2 v n num x k p pl ) (setq p1 (getpoint "\nPick or specify first point : ")) (setq p2 (getpoint p1 "\nPick or specify second point : ")) (setq v (mapcar '- p2 p1)) (setq n (polar '(0.0 0.0) (+ (angle '(0.0 0.0) v) (* 0.5 pi)) 1.0)) (initget 7) (setq num (getint "\nSpecify number of XLINE entities for division of distance between two picked points : ")) (setq x (/ (distance p1 p2) num)) (setq k 0.5) (repeat num (setq p (polar p1 (angle p1 p2) (* k x))) (setq k (1+ k)) (setq pl (cons p pl)) ) (setq pl (reverse pl)) (foreach p pl (entmake (list '(0 . "XLINE") '(100 . "AcDbEntity") '(100 . "AcDbXline") (cons 10 p) (cons 11 n) ) ) ) (princ) ) M.R. Quote
MichaelAllfire Posted October 6, 2016 Author Posted October 6, 2016 Wow, that was quick! The command works well in that it correctly spaces the xlines with x and half x spacing. However, the part of the command that I am wanting to bypass is the "Specify number of xline entities ...." I would for the command to get the distance between the two points, divide that by 4200, round up to nearest whole number, and use that whole number for the "Specify nymber of xline entities .." part of the command. Does that make sense? The rest of the command works perfectly though Thanks so much for your time already! Quote
marko_ribar Posted October 6, 2016 Posted October 6, 2016 Maybe I am again missing something : Instead of Specify number of XLINEs, you want Specify X distance ? Quote
MichaelAllfire Posted October 6, 2016 Author Posted October 6, 2016 Sorry to be confusing! Trying to think of a way to explain it without being confusing. When it asks me to choose two points, I need that distance between the two points to be remembered, divided by 4200, and rounded up to the nearest whole number. I need this number to be remembered and then used. So using the command I would - Type xlindistdiv; Specify point 1 with a click Specify point 2 with a click The command would take the distance between those two points, divide by 4200, round up, and remember that rounded number. The command would then use this value for the "specify number of xlines" and draw the xlines in the same manner as before. I hope this makes a bit of sense. Let me know if it doesn't. Thanks again! Quote
marko_ribar Posted October 6, 2016 Posted October 6, 2016 Sorry to be confusing! Trying to think of a way to explain it without being confusing. When it asks me to choose two points, I need that distance between the two points to be remembered, divided by 4200, and rounded up to the nearest whole number. I need this number to be remembered and then used. So using the command I would - Type xlindistdiv; Specify point 1 with a click Specify point 2 with a click The command would take the distance between those two points, divide by 4200, round up, and remember that rounded number. The command would then use this value for the recalculating "specify number of xlines" and prompt that number as defalut number of xlines and draw the xlines in the same manner as before. I hope this makes a bit of sense. Let me know if it doesn't. Thanks again! Quote
MichaelAllfire Posted October 6, 2016 Author Posted October 6, 2016 Correct for the recalculation part. That would also work for the prompt part, although the prompt wouldn't be necessary I don't think. However, it would work either way, so all good! Quote
marko_ribar Posted October 6, 2016 Posted October 6, 2016 I could be wrong again, but this is how I understood : (defun c:xlindistdiv ( / p1 p2 x dnum v n num k p pl ) (setq p1 (getpoint "\nPick or specify first point : ")) (setq p2 (getpoint p1 "\nPick or specify second point : ")) (setq x (/ (distance p1 p2) 4200)) (setq dnum (* (fix (1+ x)) 4200)) (setq v (mapcar '- p2 p1)) (setq n (polar '(0.0 0.0) (+ (angle '(0.0 0.0) v) (* 0.5 pi)) 1.0)) (initget 6) (setq num (getint (strcat "\nSpecify number of XLINE entities for division of distance between two picked points <" (itoa dnum) "> : "))) (if (null num) (setq num dnum) ) (setq x (/ (distance p1 p2) num)) (setq k 0.5) (repeat num (setq p (polar p1 (angle p1 p2) (* k x))) (setq k (1+ k)) (setq pl (cons p pl)) ) (setq pl (reverse pl)) (foreach p pl (entmake (list '(0 . "XLINE") '(100 . "AcDbEntity") '(100 . "AcDbXline") (cons 10 p) (cons 11 n) ) ) ) (princ) ) HTH, M.R. P.S. Note that default number will be 4200, 8400 (2*4200), 12600 (3*4200), ... , depending of number rounded up when first division was made with number 4200... Quote
MichaelAllfire Posted October 6, 2016 Author Posted October 6, 2016 That is closer! The only thing that needs changing is that the default prompt value for "Specify number of XLINE entities ..." needs to be divided by 4200 to give a smaller number. EG default prompt of 16800 would become 4. I've done a test on a few different lengths, and this should work. I just don't know how to implement it. Quote
marko_ribar Posted October 6, 2016 Posted October 6, 2016 Maybe this : (defun c:xlindistdiv ( / p1 p2 x dx v n num k p pl ) (setq p1 (getpoint "\nPick or specify first point : ")) (setq p2 (getpoint p1 "\nPick or specify second point : ")) (setq dx (fix (1+ (/ (distance p1 p2) 4200)))) (setq v (mapcar '- p2 p1)) (setq n (polar '(0.0 0.0) (+ (angle '(0.0 0.0) v) (* 0.5 pi)) 1.0)) (initget 6) (setq x (getint (strcat "\nSpecify number of XLINE factor for division of distance between two picked points < " (itoa dx) " > : "))) (if (null x) (setq num (* dx 4200)) (setq num (* x 4200)) ) (setq x (/ (distance p1 p2) num)) (setq k 0.5) (repeat num (setq p (polar p1 (angle p1 p2) (* k x))) (setq k (1+ k)) (setq pl (cons p pl)) ) (setq pl (reverse pl)) (foreach p pl (entmake (list '(0 . "XLINE") '(100 . "AcDbEntity") '(100 . "AcDbXline") (cons 10 p) (cons 11 n) ) ) ) (alert (strcat "Created : " (itoa (length pl)) " XLINE entities... (WHEN you press ENTER or clik on OK...)")) (princ) ) Quote
MichaelAllfire Posted October 6, 2016 Author Posted October 6, 2016 The prompt was returning the correct value, but when confirming with enter, it drew way too many xlines for some reason. Worked fine when I entered in the same value myself. I have had some luck editing one of the previous code sections you sent me though! (defun c:xlindistdiv ( / p1 p2 x dnum v n num k p pl ) (setq p1 (getpoint "\nPick or specify first point : ")) (setq p2 (getpoint p1 "\nPick or specify second point : ")) (setq x (/ (distance p1 p2) 4200)) (setq dnum (* (fix (1+ x)))) (setq v (mapcar '- p2 p1)) (setq n (polar '(0.0 0.0) (+ (angle '(0.0 0.0) v) (* 0.5 pi)) 1.0)) (initget 6) (setq num (getint (strcat "\nSpecify number of XLINE entities for division of distance between two picked points <" (itoa dnum) "> : "))) (if (null num) (setq num dnum) ) (setq x (/ (distance p1 p2) num)) (setq k 0.5) (repeat num (setq p (polar p1 (angle p1 p2) (* k x))) (setq k (1+ k)) (setq pl (cons p pl)) ) (setq pl (reverse pl)) (foreach p pl (entmake (list '(0 . "XLINE") '(100 . "AcDbEntity") '(100 . "AcDbXline") (cons 10 p) (cons 11 n) ) ) ) (princ) ) Quote
marko_ribar Posted October 6, 2016 Posted October 6, 2016 I see what you wanted now... Glad it worked finally for you... Regards, M.R. Quote
MichaelAllfire Posted October 6, 2016 Author Posted October 6, 2016 Thanks very much Marko for your help! Wish I could buy you a beer or something! Quote
MichaelAllfire Posted October 6, 2016 Author Posted October 6, 2016 Hi again Marko, I am trying to expand upon what I have learnt from your code, and have an additional command/feature I'm trying to work out. Basically, I would like to run the command a second time after the xlines are drawn, but in a different direction. Additionally, instead of using 4200 as the required distance, I need to use the distance between xlines from the first run of the command. If I understand correctly, I believe you used x for the value between xlines. I thought about adding a separate (defun ... ) to the bottom of the code, but wasn't sure how to pull the x value (dist between xlines) from the existing code to replace the 4200 value. Otherwise, I would like for another prompt of "Pick or specify first point ..." to appear immediately after the first xlines appear, and then run through the whole procedure again, except using the dist between xlines instead of 4200. Did I explain clearly enough? It could be a bit confusing. Quote
Aftertouch Posted October 6, 2016 Posted October 6, 2016 I have been following this thread too, since i could use this LISP also. I was just wondering... Is it possible to get an extra option that makes you SELECT an existing line / PLINEsegment, instead of picking two points? Like when i enter the command, by default i get the option to select a line, but when i enter 'P' i can select two points, and when i enter O again, i get to select an object (line / Pline segment). Quote
marko_ribar Posted October 6, 2016 Posted October 6, 2016 (edited) For MichaelAllfire (if I understood correctly) : (defun c:xlindistdiv ( / p1 p2 x dnum v n num xd k p pl ) (while (setq p1 (if (null p1) (getpoint "\nPick or specify first point : ") p2)) (setq p2 (getpoint p1 "\nPick or specify second point - ENTER TO FINISH : ")) (if (and p1 p2) (progn (if (null x) (setq x (/ (distance p1 p2) 4200)) ) (if (null dnum) (setq dnum (fix (1+ x))) (setq dnum (fix (1+ (/ (distance p1 p2) xd)))) ) (setq v (mapcar '- p2 p1)) (setq n (polar '(0.0 0.0) (+ (angle '(0.0 0.0) v) (* 0.5 pi)) 1.0)) (initget 6) (setq num (getint (strcat "\nSpecify number of XLINE entities for division of distance between two picked points <" (itoa dnum) "> : "))) (if (null num) (setq num dnum) ) (setq xd (/ (distance p1 p2) num)) (setq k 0.5) (repeat num (setq p (polar p1 (angle p1 p2) (* k xd))) (setq k (1+ k)) (setq pl (cons p pl)) ) (setq pl (reverse pl)) (foreach p pl (entmake (list '(0 . "XLINE") '(100 . "AcDbEntity") '(100 . "AcDbXline") (cons 10 p) (cons 11 n) ) ) ) (setq pl nil) ) ) ) (princ) ) For Aftertouch : (defun c:xlindistdiv ( / points object ch p1 p2 x v n num k p pl ) (defun points nil (setq p1 (getpoint "\nPick or specify first point : ")) (setq p2 (getpoint p1 "\nPick or specify second point : ")) ) (defun object ( / es ) (vl-load-com) (setq es (entsel "\nPick straight segment of LWPOLYLINE or LINE entity...")) (if (not (wcmatch (cdr (assoc 0 (entget (car es)))) "LINE,LWPOLYLINE")) (progn (prompt "\nPicked wrong entity type... Quitting...") (exit) ) (if (= (cdr (assoc 0 (entget (car es)))) "LWPOLYLINE") (progn (setq p1 (vlax-curve-getpointatparam (car es) (fix (vlax-curve-getparamatpoint (car es) (vlax-curve-getclosestpointto (car es) (trans (cadr es) 1 0)))))) (setq p2 (vlax-curve-getpointatparam (car es) (1+ (fix (vlax-curve-getparamatpoint (car es) (vlax-curve-getclosestpointto (car es) (trans (cadr es) 1 0))))))) ) (progn (setq p1 (vlax-curve-getstartpoint (car es))) (setq p2 (vlax-curve-getendpoint (car es))) ) ) ) ) (initget 1 "points object") (setq ch (getkword "\nChoose an option [points/object] : ")) (prompt "\nChoosen option : \"")(prompt ch)(prompt "\"") (while (= (getstring t "\nSwitch <ENTER-Yes> ; Accept <space+ENTER> : ") "") (cond ( (= ch "points") (setq ch "object") ) ( (= ch "object") (setq ch "points") ) ) (prompt "\nChoosen option : \"")(prompt ch)(prompt "\"") ) (if (= ch "points") (points) (object) ) (if (and p1 p2) (progn (setq v (mapcar '- p2 p1)) (setq n (polar '(0.0 0.0) (+ (angle '(0.0 0.0) v) (* 0.5 pi)) 1.0)) (initget 7) (setq num (getint "\nSpecify number of XLINE entities for division of distance between two picked points : ")) (setq x (/ (distance p1 p2) num)) (setq k 0.5) (repeat num (setq p (polar p1 (angle p1 p2) (* k x))) (setq k (1+ k)) (setq pl (cons p pl)) ) (setq pl (reverse pl)) (foreach p pl (entmake (list '(0 . "XLINE") '(100 . "AcDbEntity") '(100 . "AcDbXline") (cons 10 p) (cons 11 n) ) ) ) ) ) (princ) ) Regards, M.R. Edited October 6, 2016 by marko_ribar Quote
MichaelAllfire Posted October 7, 2016 Author Posted October 7, 2016 Hi again Marko! That is, again, pretty damn close to what I want to do. One thing, is it possible for the prompt for the second direction to be "specify FIRST point"? It would be more suitable for my purposes to pick a new starting point as opposed to continuing off from the second point of the first direction. I missed a few things when explaining before, whoops! When determining the number of xlines for the second direction, it needs to do the following (I have used letter variables for this explanation only) ... VarA will be the distance between existing xlines in the first direction. VarB will be 12000/VarA VarC will be VarB x 1000 This VarC value will be the value used in place of 4200 for the second direction. It will follow the same process as the first run, and will need to be rounded up to the nearest whole once divided into the second direction's distance. This whole number will give us the needed number of xlines for the second direction. I hope this makes sense. You have been a great help so far! 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.