lilyachty Posted November 20, 2024 Posted November 20, 2024 I've seen offset LISPs, but none that does specifically what I'm looking for. Also, I tried the default offset function with the through setting, but it's not it. Like the default offset function, I would like one that offsets a line a certain distance in either a positive or negative direction depending on the user selection. However, I would like to go beyond that... For example, I would select the line I want to offset (line1) and then specify the distance by picking any two points in the drawing (pt2-pt1). Then, I would like to select another point (pt3) to get the next offset distance (pt3-pt1), and so forth. After or during selection, the function would offset the original line (line1) with the specified distances. Please help, thanks! Quote
EnM4st3r Posted November 20, 2024 Posted November 20, 2024 as long as the points you click are on the same direction as you want it to offset.. wouldnt that just be the nomal copy command? But yes, when the direction doesnt match copy wouldnt work Quote
Steven P Posted November 20, 2024 Posted November 20, 2024 (edited) Are you able to make a LISP to do all the selections, select a line, select point 1 and then a loop to select the subsequent points, working out the distances? If you use vla-offset you can specify direction with a =ve or -ve distance for example (vla-Offset (vlax-ename->vla-object (car (entsel))) 1000) will go one way 1000 units (vla-Offset (vlax-ename->vla-object (car (entsel))) -1000) will go the other way 1000 units For direction you can use the line end A and angle between that and the point Point end A: (cdr (assoc 10 (car (entsel)))) Angle between the points will be in radians, if radians is less than pi the offset is one direction, if it is more than pi it is the other (I think).. might need to work that one out, might be between pi / 2 and 3x pi / 2 one direction, the other 2 quadrants the other direction. Something like that. In the above you can replace (car(entsel)) with a variable and use that through the LISP There, probably confused you but have a go and see what you can make up EDIT Actually the angles might be dependent on the lines angle. BigAl might be about later, his favourite option is to select the line near one end or the other and offset in say a clockwise direction from that point each time Edited November 20, 2024 by Steven P Quote
pkenewell Posted November 20, 2024 Posted November 20, 2024 Here is a recent example - maybe not totally what you are looking for, but similar: Quote
lilyachty Posted November 20, 2024 Author Posted November 20, 2024 8 hours ago, EnM4st3r said: as long as the points you click are on the same direction as you want it to offset.. wouldnt that just be the nomal copy command? But yes, when the direction doesnt match copy wouldnt work Yes, I use it to draw elevations from plans. So from the plans I would get the offset from property line to edge of window or center of column, etc. in the y-direction and then offset the property line in the elevation view to said distance in the x-direction... so far I have been doing it one offset at a time or creating a block to mark my lines and rotating it on elevation view. Quote
lilyachty Posted November 21, 2024 Author Posted November 21, 2024 2 hours ago, pkenewell said: Here is a recent example - maybe not totally what you are looking for, but similar: This could be helpful if I would figure out a way to make a list of strings that gets the distance btwn a set of points. Can you help me write one or know of a similar code? Thanks! Quote
EnM4st3r Posted November 21, 2024 Posted November 21, 2024 i tried something simple. maybe this helps (defun c:foo (/ ent pt pt1 dist) (setq ent (car (entsel "\nSelect polyline to offset: ")) pt (getpoint "\nSelect side to offset: ") pt1 (getpoint "\nSelect startpoint:" ) ) (while (setq dist (getdist pt1 "\nOffset Distance: ")) (command "._offset" dist ent pt "") ) ) Quote
pkenewell Posted November 21, 2024 Posted November 21, 2024 @lilyachty Here is an update to my original program. It has 3 options: 1) "Through" - acts like the "through" option of the OFFSET command, but allows multiple through points. 2) "Absolute" - Loops for multiple distances either by a number or selecting 2 points; all distances are from the original object. 3) "Increment" - Loops for multiple distances either by a number or selecting 2 points; distances are additive to the previous. (defun c:moff (/ _Entsel ds ob op p1 pt s t1 t2 tl) (defun _Entsel (pr / ent) (setvar "errno" 0) (while (and (not (setq ent (entsel pr)))(= (getvar "errno") 7)) (princ "\nNo Object Selected. Try Again...\n") ) ent ) (if (setq s (_Entsel "\nSelect a curve to offset: ")) (progn (setq ob (vlax-ename->vla-object (car s)) p1 (cadr s) ) (if (vlax-method-applicable-p ob 'Offset) (progn (initget "Through Absolute Incremental Distance") (setq ai (getkword "\nSelect Distance Method [Through/Absolete/Incremental]: <Through>") ai (if ai ai "Through") ) (cond ((= ai "Through") (while (setq pt (getpoint (if pt pt p1) "\nSelect a Through Point: ")) (command "._Offset" "_t" s "_non" pt "") ) ) ((wcmatch ai "Absolute,Incremental,Distance") (while (setq ds (getdist "\nEnter a distance Value or Select Two Points: ")) (setq tl (append tl (list ds))) ) (if (and tl (setq op (getpoint p1 "\nSelect side to Offset: "))) (progn ;; Make sure the offset side point at the outside of the offset zone. (setq op (polar p1 (angle p1 op) (apply '+ tl)) inc 0.0) ;; iterate for each dist (foreach n tl (if (= ai "Incremental")(setq inc (+ inc n))(setq inc n)) (setq t1 (car (vlax-invoke ob 'offset inc)) t2 (car (vlax-invoke ob 'offset (- inc))) ) (if (< (distance op (vlax-curve-getclosestpointto t1 op)) (distance op (vlax-curve-getclosestpointto t2 op)) ) (vla-delete t2) (vla-delete t1) ) ) ) ) ) ) ) (princ "\nInvalid object for Offset. ") ) ) ) (princ) ) Quote
lilyachty Posted November 22, 2024 Author Posted November 22, 2024 20 hours ago, pkenewell said: @lilyachty Here is an update to my original program. It has 3 options: 1) "Through" - acts like the "through" option of the OFFSET command, but allows multiple through points. 2) "Absolute" - Loops for multiple distances either by a number or selecting 2 points; all distances are from the original object. 3) "Increment" - Loops for multiple distances either by a number or selecting 2 points; distances are additive to the previous. (defun c:moff (/ _Entsel ds ob op p1 pt s t1 t2 tl) (defun _Entsel (pr / ent) (setvar "errno" 0) (while (and (not (setq ent (entsel pr)))(= (getvar "errno") 7)) (princ "\nNo Object Selected. Try Again...\n") ) ent ) (if (setq s (_Entsel "\nSelect a curve to offset: ")) (progn (setq ob (vlax-ename->vla-object (car s)) p1 (cadr s) ) (if (vlax-method-applicable-p ob 'Offset) (progn (initget "Through Absolute Incremental Distance") (setq ai (getkword "\nSelect Distance Method [Through/Absolete/Incremental]: <Through>") ai (if ai ai "Through") ) (cond ((= ai "Through") (while (setq pt (getpoint (if pt pt p1) "\nSelect a Through Point: ")) (command "._Offset" "_t" s "_non" pt "") ) ) ((wcmatch ai "Absolute,Incremental,Distance") (while (setq ds (getdist "\nEnter a distance Value or Select Two Points: ")) (setq tl (append tl (list ds))) ) (if (and tl (setq op (getpoint p1 "\nSelect side to Offset: "))) (progn ;; Make sure the offset side point at the outside of the offset zone. (setq op (polar p1 (angle p1 op) (apply '+ tl)) inc 0.0) ;; iterate for each dist (foreach n tl (if (= ai "Incremental")(setq inc (+ inc n))(setq inc n)) (setq t1 (car (vlax-invoke ob 'offset inc)) t2 (car (vlax-invoke ob 'offset (- inc))) ) (if (< (distance op (vlax-curve-getclosestpointto t1 op)) (distance op (vlax-curve-getclosestpointto t2 op)) ) (vla-delete t2) (vla-delete t1) ) ) ) ) ) ) ) (princ "\nInvalid object for Offset. ") ) ) ) (princ) ) This works, however may I offer a suggestion? First, I see that there's a DISTANCE option included in the initget and cond functions but left out of the in the getkeyword function... Second, can you alter the code (either change existing functions or add another option) such that I only need to select 2 points the first time, [ptbase & pt1] then, the following times, I would only need to select 1 point [ptx] to get the offset distance from the original point [ptbase] to new point [ptx]. Also, having the program pick up my last selected entity (if applicable) would be nice rather than having to select my entity after entering the program. Thank you so much! Quote
pkenewell Posted November 22, 2024 Posted November 22, 2024 (edited) 1 hour ago, lilyachty said: First, I see that there's a DISTANCE option included in the initget and cond functions but left out of the in the getkeyword function... Second, can you alter the code (either change existing functions or add another option) such that I only need to select 2 points the first time, [ptbase & pt1] then, the following times, I would only need to select 1 point [ptx] to get the offset distance from the original point [ptbase] to new point [ptx]. Also, having the program pick up my last selected entity (if applicable) would be nice rather than having to select my entity after entering the program. Thank you so much! @lilyachty 1) Yeah, the "Distance option was something I was playing around with when re-writing and I forgot to remove. Corrected. 2) A distance from a base point is possible but it will not give you a "Through" point, if the point is not perpendicular to the selected offset segment. That is why I did a multiple "Through" option. If this is not a concern for you, then use the "Absolute" option in the updated version below (I made "Absolute" the default). NOTE: I left instructions in the comments on how to change the default option if you so desire. Also, the "Incremental" option does not have the basepoint added, because it would not make sense to do incrementals from a common base point. (defun c:moff (/ _Entsel ds ob op p1 p2 pt s t1 t2 tl) (defun _Entsel (pr / ent) (setvar "errno" 0) (while (and (not (setq ent (entsel pr)))(= (getvar "errno") 7)) (princ "\nNo Object Selected. Try Again...\n") ) ent ) (if (setq s (_Entsel "\nSelect a curve to offset: ")) (progn (setq ob (vlax-ename->vla-object (car s)) p1 (cadr s) ) (if (vlax-method-applicable-p ob 'Offset) (progn (initget "Through Absolute Incremental") ;; NOTE: to change the default, change the keyword value withing the <> of the prompt, and ;; then change the keyword value in the line just below it. (setq ai (getkword "\nSelect Distance Method [Through/Absolete/Incremental]: <Absolute> ") ai (if ai ai "Absolute") ) (cond ((= ai "Through") (while (setq pt (getpoint (if pt pt p1) "\nSelect a Through Point: ")) (command "._Offset" "_t" s "_non" pt "") ) ) ((wcmatch ai "Absolute,Incremental") (if (= ai "Absolute") (if (setq p2 (getpoint "Select Base point for Offset: ")) (while (setq ds (getdist p2 "\nEnter a distance Value or Select 2nd Point: ")) (setq tl (append tl (list ds))) ) ) (while (setq ds (getdist p1 "\nEnter a distance Value or Select Two Points: ")) (setq tl (append tl (list ds))) ) ) (if (and tl (setq op (getpoint p1 "\nSelect side to Offset: "))) (progn ;; Make sure the offset side point at the outside of the offset zone. (setq op (polar p1 (angle p1 op) (apply '+ tl)) inc 0.0) ;; iterate for each dist (foreach n tl (if (= ai "Incremental")(setq inc (+ inc n))(setq inc n)) (setq t1 (car (vlax-invoke ob 'offset inc)) t2 (car (vlax-invoke ob 'offset (- inc))) ) (if (< (distance op (vlax-curve-getclosestpointto t1 op)) (distance op (vlax-curve-getclosestpointto t2 op)) ) (vla-delete t2) (vla-delete t1) ) ) ) ) ) ) ) (princ "\nInvalid object for Offset. ") ) ) ) (princ) ) EDIT: I changed it so that the distance base is independent to the offset side base in the "Absolute" option. Edited November 22, 2024 by pkenewell 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.