viviancarvalho Posted December 20, 2009 Posted December 20, 2009 Hello Everybody I wanna create a lisp routine which will ask for the user to pick a line & then draw an object on the same line (on the same angle of the picked line). Say the object is an rectangle. Though the object actually is not only a rectangle. I can manage the rest. I just dont know how to obtain the angle of the picked line & draw over. I just require a start up for this routine. It could be a very small job for many of the Lisp champs here. Waiting for some good soul to solve this problem of mine. Thank you in advance. Vivian Quote
Lee Mac Posted December 20, 2009 Posted December 20, 2009 Two ways: (defun c:test1 (/ ent elst) (if (setq ent (car (entsel "\nSelect Line: "))) (progn (setq elst (entget ent)) (print (angle (cdr (assoc 10 elst)) (cdr (assoc 11 elst)))))) (princ)) (defun c:test2 (/ ent pt) (if (setq ent (entsel "\nSelect Line: ")) (progn (setq pt (cadr ent) ent (car ent)) (print (angle '(0 0 0) (vlax-curve-getFirstDeriv ent (vlax-curve-getParamatPoint ent (vlax-curve-getClosestPointto ent pt))))))) (princ)) The first is applicable only to LINE's, and uses the angle between the start and end Points. The second is applicable to all Curve Objects (Lines, Splines, Arcs, Ellipses etc), and uses the First Derivative at the point selected. Hope this helps, Lee Quote
David Bethel Posted December 20, 2009 Posted December 20, 2009 Another approach: [b][color=BLACK]([/color][/b]defun c:ldef [b][color=FUCHSIA]([/color][/b]/ ss en ed p10 p11 lan[b][color=FUCHSIA])[/color][/b] [b][color=FUCHSIA]([/color][/b]while [b][color=NAVY]([/color][/b]or [b][color=MAROON]([/color][/b]not ss[b][color=MAROON])[/color][/b] [b][color=MAROON]([/color][/b]> [b][color=GREEN]([/color][/b]sslength ss[b][color=GREEN])[/color][/b] 1[b][color=MAROON])[/color][/b][b][color=NAVY])[/color][/b] [b][color=NAVY]([/color][/b]princ [color=#2f4f4f]"\nSelect 1 Line To Work With: "[/color][b][color=NAVY])[/color][/b] [b][color=NAVY]([/color][/b]setq ss [b][color=MAROON]([/color][/b]ssget [b][color=GREEN]([/color][/b]list [b][color=BLUE]([/color][/b]cons 0 [color=#2f4f4f]"LINE"[/color][b][color=BLUE])[/color][/b][b][color=GREEN])[/color][/b][b][color=MAROON])[/color][/b][b][color=NAVY])[/color][/b][b][color=FUCHSIA])[/color][/b] [b][color=FUCHSIA]([/color][/b]setq en [b][color=NAVY]([/color][/b]ssname ss 0[b][color=NAVY])[/color][/b] [color=#8b4513]; Entity Name[/color] ed [b][color=NAVY]([/color][/b]entget en[b][color=NAVY])[/color][/b] [color=#8b4513]; Entity Definition[/color] p10 [b][color=NAVY]([/color][/b]cdr [b][color=MAROON]([/color][/b]assoc 10 ed[b][color=MAROON])[/color][/b][b][color=NAVY])[/color][/b] [color=#8b4513]; 1st End Point[/color] p11 [b][color=NAVY]([/color][/b]cdr [b][color=MAROON]([/color][/b]assoc 11 ed[b][color=MAROON])[/color][/b][b][color=NAVY])[/color][/b] [color=#8b4513]; 2nd End Point[/color] lan [b][color=NAVY]([/color][/b]angle p10 p11[b][color=NAVY])[/color][/b][b][color=FUCHSIA])[/color][/b] [color=#8b4513]; Angle In Radians[/color] lan[b][color=BLACK])[/color][/b] I like using ( ssget ) because it allows Last/Prev/Crossing and selection filtering etc inputs. -David Quote
viviancarvalho Posted December 21, 2009 Author Posted December 21, 2009 Thanks Lee mac & David Wish you Merry Christmas & Happy new year. Quote
Lee Mac Posted December 21, 2009 Posted December 21, 2009 Thanks Lee mac & David Wish you Merry Christmas & Happy new year. You're welcome, Merry Christmas to you too Quote
viviancarvalho Posted December 28, 2009 Author Posted December 28, 2009 Hey guys i got stuck again i also want to get the length of this line so i can use it ahead. can you help me please (defun c:as (/ ss en ed p10 p11 lan) (setq osm (getvar "osmode")) (setvar "osmode" 0) (while (or (not ss) (> (sslength ss) 1)) (princ "\nSelect 1 Line To Work With: ") (setq ss (ssget (list (cons 0 "LINE"))))) (setq en (ssname ss 0) ; Entity Name ed (entget en) ; Entity Definition p10(cdr (assoc 10 ed)) ; 1st End Point p11(cdr (assoc 11 ed)) ; 2nd End Point lan(angle p10 p11) ; Angle In Radians lth(car (distance p10 p11))) (alert (strcat (rtos lth) "is the length of this line")) (setvar "osmode" osm)) Quote
fixo Posted December 28, 2009 Posted December 28, 2009 Hey guys i got stuck againi also want to get the length of this line so i can use it ahead. can you help me please (defun c:as (/ ss en ed p10 p11 lan) (setq osm (getvar "osmode")) (setvar "osmode" 0) (while (or (not ss) (> (sslength ss) 1)) (princ "\nSelect 1 Line To Work With: ") (setq ss (ssget (list (cons 0 "LINE"))))) (setq en (ssname ss 0) ; Entity Name ed (entget en) ; Entity Definition p10(cdr (assoc 10 ed)) ; 1st End Point p11(cdr (assoc 11 ed)) ; 2nd End Point lan(angle p10 p11) ; Angle In Radians lth(car (distance p10 p11))) (alert (strcat (rtos lth) "is the length of this line")) (setvar "osmode" osm)) Just change this line: lth(car (distance p10 p11))) on lth (distance p10 p11)) ~'J'~ Quote
Lee Mac Posted December 28, 2009 Posted December 28, 2009 Vivian, If you aren't already, make sure you check out the Visual LISP Help files - they will give you the correct syntax and format of the majority of LISP functions that you will need. And I would recommend creating your code using the Visual LISP Editor, or perhaps Notepad++/Vim etc.. Lee Quote
David Bethel Posted December 28, 2009 Posted December 28, 2009 Another gotcha is that (distance) returns the true distance in 3D. (angle) is a 2D value and that each plane angle can be extracted: [b][color=BLACK]([/color][/b]setq p10 '[b][color=FUCHSIA]([/color][/b]1 4 2[b][color=FUCHSIA])[/color][/b] p11 '[b][color=FUCHSIA]([/color][/b]3 7 5[b][color=FUCHSIA])[/color][/b][b][color=BLACK])[/color][/b] [b][color=BLACK]([/color][/b]setq XY [b][color=FUCHSIA]([/color][/b]angle [b][color=NAVY]([/color][/b]list [b][color=MAROON]([/color][/b]nth 0 p10[b][color=MAROON])[/color][/b] [b][color=MAROON]([/color][/b]nth 1 p10[b][color=MAROON])[/color][/b][b][color=NAVY])[/color][/b] [b][color=NAVY]([/color][/b]list [b][color=MAROON]([/color][/b]nth 0 p11[b][color=MAROON])[/color][/b] [b][color=MAROON]([/color][/b]nth 1 p11[b][color=MAROON])[/color][/b][b][color=NAVY])[/color][/b][b][color=FUCHSIA])[/color][/b] XZ [b][color=FUCHSIA]([/color][/b]angle [b][color=NAVY]([/color][/b]list [b][color=MAROON]([/color][/b]nth 0 p10[b][color=MAROON])[/color][/b] [b][color=MAROON]([/color][/b]nth 2 p10[b][color=MAROON])[/color][/b][b][color=NAVY])[/color][/b] [b][color=NAVY]([/color][/b]list [b][color=MAROON]([/color][/b]nth 0 p11[b][color=MAROON])[/color][/b] [b][color=MAROON]([/color][/b]nth 2 p11[b][color=MAROON])[/color][/b][b][color=NAVY])[/color][/b][b][color=FUCHSIA])[/color][/b] YZ [b][color=FUCHSIA]([/color][/b]angle [b][color=NAVY]([/color][/b]list [b][color=MAROON]([/color][/b]nth 1 p10[b][color=MAROON])[/color][/b] [b][color=MAROON]([/color][/b]nth 2 p10[b][color=MAROON])[/color][/b][b][color=NAVY])[/color][/b] [b][color=NAVY]([/color][/b]list [b][color=MAROON]([/color][/b]nth 1 p11[b][color=MAROON])[/color][/b] [b][color=MAROON]([/color][/b]nth 2 p11[b][color=MAROON])[/color][/b][b][color=NAVY])[/color][/b][b][color=FUCHSIA])[/color][/b] [b][color=BLACK])[/color][/b] -David Quote
flowerrobot Posted January 1, 2010 Posted January 1, 2010 Another possible sollution, which i use alot (defun c:UO nil(command "_.Ucs" "_Object" pause)) (defun c:UU nil (command "_.Ucs" "_world")) Quote
viviancarvalho Posted January 4, 2010 Author Posted January 4, 2010 Thanks guys With your support i am successful in creating the program. But now i am facing a strange problem. I run the lisp in Autocad 2008 , it does things exactly as i want it to for the first three times. The fourth time i run it, it gives me an error message. FATAL ERROR: Commands may not be nested more than 4 deep. When i run the same program in Autocad 2010 it works very fine without any errors. Can anyone please tell me where am i going wrong. I know there is a lot of room for improvement in this lisp but i just want to know whats wrong in this one. I am not that good at making lisps but with what i know & a little help from this site i get my work done. I am attaching the code here but be sure you do not use it for the 4th time if you are using Autocad 2008 or lower version. 0SALD.LSP Quote
Lee Mac Posted January 4, 2010 Posted January 4, 2010 I can't immediately see where the error is occurring, but a few things that I would advise: When using "command" calls, prefix commands with "_." to allow for all languages and to revert to the original command definition if the command has been redefined. see http://www.cadforum.cz/cadforum_en/qaID.asp?tip=2425for more info. Avoid using "command" calls where you can - take a look at using the entmake function - it is much quicker, and more reliable, giving you much more control, (but don't worry too much, as you are just starting, just a tip for the future). Lee Quote
David Bethel Posted January 4, 2010 Posted January 4, 2010 Can you use the ALIGN in a ( command ) call? It is an EXRXSUB in 2000 -David Quote
Lee Mac Posted January 4, 2010 Posted January 4, 2010 Ahh, true - missed that! EXRXSUBR in 2010 :wink: Quote
The Buzzard Posted January 4, 2010 Posted January 4, 2010 Thanks guysWith your support i am successful in creating the program. But now i am facing a strange problem. I run the lisp in Autocad 2008 , it does things exactly as i want it to for the first three times. The fourth time i run it, it gives me an error message. FATAL ERROR: Commands may not be nested more than 4 deep. When i run the same program in Autocad 2010 it works very fine without any errors. Can anyone please tell me where am i going wrong. I know there is a lot of room for improvement in this lisp but i just want to know whats wrong in this one. I am not that good at making lisps but with what i know & a little help from this site i get my work done. I am attaching the code here but be sure you do not use it for the 4th time if you are using Autocad 2008 or lower version. Viv, I looked at the code this morning and found when I comment this line out (command "erase" en "") the problem does not occur. My guess is it is somewhere in this part of the code if it helps any. (while (or (not ss) (> (sslength ss) 1)) (princ "\nSelect 1 Line To Work With: ") (setq ss (ssget (list (cons 0 "LINE"))))) (setq en (ssname ss 0) ; Entity Name ed (entget en) ; Entity Definition p10 (cdr (assoc 10 ed)) ; 1st End Point p11 (cdr (assoc 11 ed)) ; 2nd End Point lan (angle p10 p11) ; Angle In Radians lth (- (distance p10 p11) 50) nos (getint "\nENTER THE NUMBER OF SLOTS (2,3,4) : ") plen (getint "\nENTER THE LENGTH OF PLENUM : ") p1 (cdr (assoc 10 (entget en))) Maybe you should double check this area. The variable en I think is where the problem is or something connected to it. Its a start anyway. Quote
viviancarvalho Posted January 4, 2010 Author Posted January 4, 2010 Thanks David, Lee & Buzzard I agree to you all. But how is it that the same lisp works smoothly in Autocad 2010 ?? Hi Buzzard Nice to see your post after a long time.How r u keeping? Thanks & regards Vivian Quote
The Buzzard Posted January 4, 2010 Posted January 4, 2010 Thanks David, Lee & BuzzardI agree to you all. But how is it that the same lisp works smoothly in Autocad 2010 ?? Hi Buzzard Nice to see your post after a long time.How r u keeping? Thanks & regards Vivian Hey Viv, As I mentioned, I am not exactly sure as to what is going on there. Lee would be a better teacher in that area. Just the same all indicators seem to point in the direction of the selection set. Why this is happening on older versions has me at a loss. As far as myself is concerned, I have been caught up with the typical seasonal illnesses, But nothing to serious. Take care and good luck. Quote
David Bethel Posted January 4, 2010 Posted January 4, 2010 You can try adding this after you have set your mode etc. It can help debugging: (defun debughelp () (setq *error* nil) (setvar "CMDECHO" 1) (trace c:lsd) (vl-load-com) (vl-bt)) (debughelp) -David Quote
Lee Mac Posted January 4, 2010 Posted January 4, 2010 Vivian, Its difficult to see from your code what you want to create, but I shall help you in any way that I can. I would avoid using align and erase, and just create that which is necessary, and in the correct place. I have written a quick "shell" that you could build your program around - this should give you a good foundation that is error free. I have provided you with a few sub-functions that should ease the creation of your poylines: (defun c:lsd (/ *error* [b][color=Blue]Make_Layer[/color][/b] [color=Red][b]Make_Polyline[/b][/color] vl ov ss nos plen) (defun *error* (msg) (and ov (mapcar 'setvar vl ov)) (or (wcmatch (strcase msg) "*BREAK,*CANCEL*,*EXIT*") (princ (strcat "\n** Error: " msg " **"))) (princ)) [b][color=Blue] (defun Make_Layer (lay col) (or (tblsearch "LAYER" lay) (command "_.-layer" "_M" lay "_C" col lay "")))[/color][/b] [color=Red][b] (defun Make_Polyline (pts cls) (entmakex (append (list (cons 0 "LWPOLYLINE") (cons 100 "AcDbEntity") (cons 100 "AcDbPolyline") (cons 90 (length pts)) (cons 70 cls)) (mapcar (function (lambda (x) (cons 10 x))) pts))))[/b][/color] (setq vl '("CLAYER" "CMDECHO" "OSMODE") ov (mapcar 'getvar vl)) (if (and (setq ss (ssget "_:S" '((0 . "LINE")))) (setq nos (getint "\nEnter Number of Slots: ")) (setq plen (getdist "\nEnter Length of Plenum: "))) (progn (mapcar 'Make_Layer '("GRILLE" "DUCTING") '(30 6)) (mapcar 'setvar (cdr vl) '(0 0 0)) [color=SeaGreen][b];< Draw Stuff Here>[/b][/color] ) ; End Progn ) ; End IF (mapcar 'setvar vl ov) (princ)) Notice the two sub-functions shown in blue and red. With the Make_layer sub, you can supply it with a layer name and colour, and it will create your layers for you, as shown above. With the Make_Polyline sub, you can supply it with a list of points, and a bit-code as to whether you want a closed poly or open (1 or 0). For Example: _$ (Make_Polyline (list '(1 2 0) '(3 10 0) '(5 6 0)) 1) <Entity name: 7ef036b8> Will return the entity name of the closed polyline created through 1,2,0 3,10,0 and 5,6,0. I hope this helps, Lee 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.