Line Lisp

Line Lisp

christianbaileypaulsen1
Advocate Advocate
4,920 Views
20 Replies
Message 1 of 21

Line Lisp

christianbaileypaulsen1
Advocate
Advocate

Im trying to create a lisp that creates a line right angle polyline that is pretty much and 1/16 offset of a corner. The line needs to be 1/2 inch, turn 90 degrees, then another 1/2 inch. I then tried to insert a rotate command so i can orientate the right angle to match the original corner. I will insert my code and a picture example. The red line is what im trying to draw via lisp. Its a very simple line and i usually copy it and then rotate it the way i need, i thought a lisp might be quicker though. Thank you everyone

 (defun c:sqout (/ startpoint)
(setq startpoint (getpoint "Select Corner"))
(command "._line" startpoint (1/2,0,0))
(command "._line" startpoint (0,1/2,0))
(command "._rotate" startpoint)
)

SQout Example.PNG

 

0 Likes
Accepted solutions (1)
4,921 Views
20 Replies
Replies (20)
Message 2 of 21

Kent1Cooper
Consultant
Consultant
Accepted solution

Several things are off in the syntax there, Line commands are not completed, and there's no object selection for the Rotate command.  Try it something more like this way [minimally tested]:

 

(defun c:sqout (/ startpoint)
(setq startpoint (getpoint "Select Corner"))
(command
"_.pline" "_none" (polar startpoint 0 0.5) "_none" startpoint "_none" "@0,1/2" ""
"_.move" "_last" "" "1/16,1/16,0" ""
"_.rotate" "_last" "" "_none" startpoint
)
)

 

Kent Cooper, AIA
0 Likes
Message 3 of 21

Jonathan3891
Advisor
Advisor

Edit: Kent's is better, use that one Smiley Tongue

 

Try this

 (defun c:sqout  (/ spnt)
 (setq spnt (getpoint "Select Corner"))
 (command "line" spnt "@1/2,0" "")
 (command "line" spnt "@0,1/2" "")
 (command "._rotate" spnt)
) 

 


Jonathan Norton
Blog | Linkedin
0 Likes
Message 4 of 21

christianbaileypaulsen1
Advocate
Advocate

Dsm i never got to see what you posted originally but im sure it was great, thank you for your effort.

 

Kent yours worked great, exactly what i need. I might have to add onto it later because sometimes i do more complicated pieces but for now this will save me so much time. Thank you for helping me with this, and for helping on my other lisp as well. I haven't had time to mess with the other one today, itll have to wait till break but ill let you know how it works.

0 Likes
Message 5 of 21

Kent1Cooper
Consultant
Consultant

@christianbaileypaulsen1 wrote:

.... 

Kent yours worked great, exactly what i need. ....


Another way to do it would be to have that little L as a drawing, in some location where AutoCAD knows to look, with its insertion point defined at the offset from its corner, and do this:

(defun C:SQOUT ()
  (command "_.insert" "SQOUT" "_scale" 1); [whatever name you would use]
)

That would leave you at the point of dragging it to the insertion point, and you would finish with the rotation.  No variables needed.

 

If you put more than just a few of them in the same drawing, it would be a little bit of a memory saver, too.

Kent Cooper, AIA
0 Likes
Message 6 of 21

christianbaileypaulsen1
Advocate
Advocate

We have lots of people in our folders and people move files and change names all the time so i try not to use references if i can. If someone changes the file name itll break the reference and make a huge hassle to fix it.

0 Likes
Message 7 of 21

This might be overkill and i know rotating it isnt hard at all. Im trying to simplify our system here so id like to do it as best i can. Do you think theres any way for the new L shaped piece to match the rotation of the right angle that is preexisting without having to manually input it? Like you would click the vertice and would detect the angle and the new inserted piece could be set to that angle. So that all the workers would just have to enter the command and click? 

0 Likes
Message 8 of 21

christianbaileypaulsen1
Advocate
Advocate

I tried working on it some more but haven't made it work. If anyone else has some ideas ill test them out tomorrow morning.

0 Likes
Message 9 of 21

Kent1Cooper
Consultant
Consultant

@christianbaileypaulsen1 wrote:

We have lots of people in our folders and people move files and change names all the time so i try not to use references if i can. If someone changes the file name itll break the reference and make a huge hassle to fix it.


I wasn't talking about an XREF, just an Insert, after which it becomes just a Block within the drawing, and you can Insert more of them without its having to reach out to the source drawing file again.

Kent Cooper, AIA
0 Likes
Message 10 of 21

Kent1Cooper
Consultant
Consultant

@christianbaileypaulsen1 wrote:

.... Do you think theres any way for the new L shaped piece to match the rotation of the right angle that is preexisting without having to manually input it? .... 


That depends:  What are the pieces of which the corner is drawn?  If it's a Polyline, and that's all that's there, it could be fairly simple.  If it's two Lines, and/or if other things such as Dimension definition points might be at the corner, it gets more complicated, though it may still be possible.

Kent Cooper, AIA
0 Likes
Message 11 of 21

christianbaileypaulsen1
Advocate
Advocate

If i put in the square outs before i do everything else (Like im suppose to, but i forget sometimes), then polylines are the only thing there and thats what i would select. Leaving work soon, but ill probably check back later tonight. Thanks so much for all your help man.

0 Likes
Message 12 of 21

christianbaileypaulsen1
Advocate
Advocate

Its a polyline where to lines meet at a vertice to create a 90 degree angle.

0 Likes
Message 13 of 21

Kent1Cooper
Consultant
Consultant

How 'bout this?

(defun C:SQOUT (/ plsel pl ver par angpre angpost corner)
  (if
    (and
      (setq plsel (entsel "\nSelect Polyline near 90-degree corner: "))
      (wcmatch (cdr (assoc 0 (entget (setq pl (car plsel))))) "*POLYLINE")
    ); and
    (progn ; then -- proceed
      (setq
        ver (osnap (cadr plsel) "_end")
        par (vlax-curve-getParamAtPoint pl ver)
        angpre
          (angle
            ver
            (vlax-curve-getPointAtParam pl
              (1- (if (= par 0.0) (vlax-curve-getEndParam pl) par))
                ; [if start/end corner of closed one, par = 0.0 -- no preceding vertex]
            ); ...getPoint...
          ); angle
        angpost (angle ver (vlax-curve-getPointAtParam pl (1+ par)))
        corner
          (polar
            ver
            (angle ver (mapcar '/ (mapcar '+ (polar ver angpre 1) (polar ver angpost 1)) '(2 2 2)))
            (* 0.0625 (sqrt 2));; could modify to work at other bend angles
          ); polar
      ); setq
      (command "_.pline"
        "_none" (polar corner angpre 0.5)
        "_none" corner
        "_none" (polar corner angpost 0.5)
        ""
      ); command
    ); progn
    (prompt "\nNothing selected, or not a Polyline."); else
  ); if
  (princ)
); defun

 

It actually works on other-than-90-degree angles, but the 1/16" offset will be off a little -- it could be made to do that correctly, if you need that.  It doesn't  check that the segments heading in both directions from the corner are both line  segments, or that the Polyline hasn't been PEDIT Fit- or Spline-curved, or that you picked at a corner  and not an open end [it will actually draw  something if you pick near the start  of an open-ended Polyline, though it gives an error if you pick near the downstream end ], but it could also be made to deal with all those possibilities.  And it could be made to repeat  automatically.

 

Consider also building in a setting of the Polyline width  to zero, whether in the PLINE command or via the PLINEWID System Variable.  And all the usual stuff [Osnap control in place of those "_none" calls, *error* handling if any System Variables are changed, command-echo suppression].

Kent Cooper, AIA
0 Likes
Message 14 of 21

christianbaileypaulsen1
Advocate
Advocate

I put in your code exactly how you typed it and get this error.

error.PNG

0 Likes
Message 15 of 21

Kent1Cooper
Consultant
Consultant

@christianbaileypaulsen1 wrote:

I put in your code exactly how you typed it and get this error.

 


Whoops -- that's an AutoLisp function name.  Change ver as a variable name to something else, like vert, wherever it occurs.  Funny that it didn't give me the same warning; maybe it's [coincidentally] VERsion-dependent whether it warns you about things like that.

Kent Cooper, AIA
0 Likes
Message 16 of 21

christianbaileypaulsen1
Advocate
Advocate

Hello,

 

I fixed the "ver" variable by changing it to "vert" and the command worked fine. I then added a "while" command so that it would repeat until ended by the escape key. It works perfectly for 90 degree angles. I tested this command with acute and obtuse angles and the 1/16" offset is off every time. Is there a way to fix this so that it is always a 1/16" offset.  The reason is that out router bit is 1/8" diameter, so we have to have our router bit radius distance from the actual piece being cut. Although 90 degree angles are typical, we do work with other angles. Having it work on any angle less than 180 degrees would be very useful. Angles beyond 180 degrees are considered outside cuts and the router bit can do them without having to be squared out. Please post your code if you can find a solution to this. Thank you so much.

(defun C:SQOUT (/ plsel pl vert par angpre angpost corner)
  (while (= 1 1)
    (if
      (and
	(setq
	  plsel	(entsel "\nSelect Polyline near 90-degree corner: ")
	)
	(wcmatch (cdr (assoc 0 (entget (setq pl (car plsel)))))
		 "*POLYLINE"
	)
      )					; and
       (progn				; then -- proceed
	 (setq
	   vert	   (osnap (cadr plsel) "_end")
	   par	   (vlax-curve-getParamAtPoint pl vert)
	   angpre
		   (angle
		     vert
		     (vlax-curve-getPointAtParam
		       pl
		       (1- (if (= par 0.0)
			     (vlax-curve-getEndParam pl)
			     par
			   )
		       )
					; [if start/end corner of closed one, par = 0.0 -- no preceding vertex]
		     )			; ...getPoint...
		   )			; angle
	   angpost (angle vert (vlax-curve-getPointAtParam pl (1+ par)))
	   corner
		   (polar
		     vert
		     (angle
		       vert
		       (mapcar
			 '/
			 (mapcar '+ (polar vert angpre 1) (polar vert angpost 1))
			 '(2 2 2)
		       )
		     )
		     (* 0.0625 (sqrt 2))
		     ;; could modify to work at other bend angles
		   )			; polar
	 )				; setq
	 (command "_.pline"
		  "_none"
		  (polar corner angpre 0.5)
		  "_none"
		  corner
		  "_none"
		  (polar corner angpost 0.5)
		  ""
	 )				; command
       )				; progn
       (prompt "\nNothing selected, or not a Polyline.") ; else
    )					; if
     (princ)
  )					;while
)					; defun
0 Likes
Message 17 of 21

Kent1Cooper
Consultant
Consultant

@christianbaileypaulsen1 wrote:

.... I tested this command with acute and obtuse angles and the 1/16" offset is off every time. Is there a way to fix this so that it is always a 1/16" offset.  ....

(defun C:SQOUT (/ plsel pl vert par angpre angpost corner)
  (while (= 1 1)
....
    )					; if
     (princ)
  )					;while
)					; defun

Yes, I "warned" about that offset difference right after the code in Post 13.  There are a couple of ways to account for that -- I'll have to think about the best way.  Complications arise, for instance, calculating the difference between directions when the 0-degree direction could fall in between.  But it's certainly possible.

 

By the way, using something in a (while) test expression that is always True may as well be simply:

 

  (while T

 

BUT that means that the only way to exit the command is with the ESCape key.  It can be done in a way that will exit that way or  by hitting Enter/space [and you can give it an <exit> default] or  by picking nothing.  When I decide how to deal with the offset-distance thing, I'll work one of those in.

 

And that (princ) should be after  the end of the (while) function, not inside it -- the last thing before the (defun)-ending right parenthesis.

Kent Cooper, AIA
0 Likes
Message 18 of 21

christianbaileypaulsen1
Advocate
Advocate

Okay let me know when you come up with something. Im sorry this started off as such a simple thing and i keep adding on. Im sure after this correction that'll be as implied as it could be and i couldn't add anything more even if i wanted to. You've been lots of help and i really appreciate it, thanks for sticking with me buddy.

0 Likes
Message 19 of 21

Kent1Cooper
Consultant
Consultant

Here's a way to do it.  This one ends with ESC or Enter/space or missing, but asks again if you pick something that isn't a Polyline.

 

(defun C:SQOUT (/ plsel pl vert par angpre angpost corner)
  (while
    (setq plsel (entsel "\nSelect Polyline near desired corner <exit>: "))
    (if (wcmatch (cdr (assoc 0 (entget (setq pl (car plsel))))) "*POLYLINE")
      (progn ; then -- proceed
        (setq
          vert (osnap (cadr plsel) "_end")
          par (vlax-curve-getParamAtPoint pl vert)
          angpre
            (angle
              vert
              (vlax-curve-getPointAtParam pl
                (1- (if (= par 0.0) (vlax-curve-getEndParam pl) par))
                  ; [if start/end corner of closed one, par = 0.0 -- no preceding vertex]
              ); ...getPoint...
            ); angle
          angpost (angle vert (vlax-curve-getPointAtParam pl (1+ par)))
          offpt
            (polar
              vert
              (angle vert (mapcar '/ (mapcar '+ (polar vert angpre 1) (polar vert angpost 1)) '(2 2 2)))
              0.1
            ); polar
        ); setq
        (command "_.offset" "1/16" vert offpt "")
        (setq corner (vlax-curve-getClosestPointTo (entlast) vert))
        (command
          "_.u" ; get rid of temporary Polyline(s)
          "_.pline"
          "_none" (polar corner angpre 0.5)
          "_none" corner
          "_none" (polar corner angpost 0.5)
          ""
        ); command
      ); progn
    ); if
    (prompt "\nSelected object is not a Polyline."); else
  ); while
  (princ)
); defun

It uses Offset to make a temporary Polyline to find the corner location for the marker, rather than run through a bunch of calculations to figure out where that should be.  Note that if the Polyline is of such a shape that Offsetting results in more than one  Polyline, it may sometimes draw the corner marker thingie in the wrong place, because it finds the point on the last object that's closest to your chosen corner, but that last object will not always be the one you want.  That could probably be overcome, if it's a situation that you would encounter, with additional code.  The routine does, however, get rid of however many temporary Polyline(s) resulted from the Offset [that's why I used a U command  rather than something like (entdel (entlast)), which would work reliably if  the result is always one  Polyline].

 

It also depends on the Polyline not being on a locked Layer, but that could also be overcome by giving in and finding the marker corner by calculation instead of the brute-force Offset way.

Kent Cooper, AIA
0 Likes
Message 20 of 21

christianbaileypaulsen1
Advocate
Advocate

It worked when i tried it. Do you mind if i use it for a couple of days and get back to you if any issues arise? That way i could put it under further testing and use it in many different applications. Again, thank you so much.

0 Likes