Visual LISP, AutoLISP and General Customization

Reply
*Expert Elite*
pbejse
Posts: 2,406
Registered: ‎11-24-2009
Message 11 of 26 (428 Views)

Re: Line between two lines

02-19-2013 08:23 PM in reply to: smaher12

smaher12 wrote:

I thank all of you. Definitely more than one way to skin a cat. Very clever indeed. Thanks again.


Glad we could hep :smileyhappy:


hmsilva wrote:

pbejse,

the "_nonz" function,  simple and clean solution.  :smileyhappy:

 

Cheers

Henrique


Thank you for your kind words Henrique :smileyhappy:

 

*Expert Elite*
Kent1Cooper
Posts: 5,231
Registered: ‎09-13-2004
Message 12 of 26 (411 Views)

Re: Line between two lines

02-20-2013 05:49 AM in reply to: smaher12

If you can stand another approach [I kept daydreaming about it -- is there something wrong with me?]....

 

This one uses an undocumented (ssget) mode trick [the +.] that I think I learned from Lee Mac a while back, which keeps (ssget) in "point" mode [no going into Window/Crossing if picked in an empty area], making it easy to have it keep asking the User to select a Line until they actually do, without having to dig into entity data to check -- it asks again if they miss or if they pick some other object type.  And by using the (set) function, it can employ the same stretch of code to do this for both Lines, rather than spelling it out individually for each one as in _Tharwat's code in Message 3.  Also, it doesn't re-set any point locations if the Lines run in opposite directions, but simply uses the end of the second Line appropriate to the direction it runs relative to the first Line, right inside the calculations of the endpoints of the new Line.  The one thing I wish could be different is that (ssget) always uses the "Select objects: " prompt, in the plural, which you can't override, so I made a sort-of work-around, mostly so you can tell when you've successfully picked a first Line, because it's asking for Line 2.

 

(defun C:LB (/ ss lin ed s1 e1 s2 e2 int); = Line Between
  (prompt "\nTo draw a Line halfway between two Lines,")
  (foreach num '(1 2)
    (prompt (strcat "\nFor Line " (itoa num) ","))
    (while
      (not (setq ss (ssget "_+.:E:smileyfrustrated:" '((0 . "LINE")))))
      (prompt (strcat "\nNothing selected, or not a Line.  For Line " (itoa num) ","))
    ); while
    (setq lin (ssname ss 0)); [line]
    (setq ed (entget lin)); [entity data]
    (set (read (strcat "s" (itoa num))) (cdr (assoc 10 ed))); s1 or s2 [start]
    (set (read (strcat "e" (itoa num))) (cdr (assoc 11 ed))); e1 or e2 [end]
  ); foreach
  (setq int (inters s1 s2 e1 e2)); T or nil -- opposite directions [assumes same plane]
  (entmake
    (list
      '(0 . "LINE")
      (cons 10 (mapcar '/ (mapcar '+ s1 (if int e2 s2)) '(2 2 2)))
      (cons 11 (mapcar '/ (mapcar '+ e1 (if int s2 e2)) '(2 2 2)))
    ); list
  ); entmake
); defun

Kent Cooper
*Expert Elite*
hmsilva
Posts: 2,639
Registered: ‎12-17-2004
Message 13 of 26 (395 Views)

Re: Line between two lines

02-20-2013 07:30 AM in reply to: Kent1Cooper

Kent1Cooper wrothe:
...
This one uses an undocumented (ssget) mode trick [the +.] that I think I learned from Lee Mac a while back, which keeps (ssget) in "point" mode [no going into Window/Crossing if picked in an empty area], making it easy to have it keep asking the User to select a Line until they actually do, without having to dig into entity data to check -- it asks again if they miss or if they pick some other object type.
...
The one thing I wish could be different is that (ssget) always uses the "Select objects: " prompt, in the plural, which you can't override, so I made a sort-of work-around, mostly so you can tell when you've successfully picked a first Line, because it's asking for Line 2.
...

Excellent way to use the "ssget", and be able to use a message during selection.


hmsilva wrothe:
...
@Tharwat
if the lines are 3D lines the inters function, will not find the interception, because,
in inters, if the four points arguments are 3D, inters checks for 3D intersection...

 

as I had written in message 5, the "inters" function gives an error if the points are 3D points...

 

 

Line between two lines.PNG

 

EDITED

image of the test with the last code.

 

Henrique

*Expert Elite*
Kent1Cooper
Posts: 5,231
Registered: ‎09-13-2004
Message 14 of 26 (380 Views)

Re: Line between two lines

02-20-2013 08:42 AM in reply to: hmsilva

hmsilva wrote:

.... 

as I had written in message 5, the "inters" function gives an error if the points are 3D points...

....


Yes, that's why I put [assumes same plane] in there -- I was focusing on other elements.  [It's not that (inters) gives an error, but just that it returns nil, so the routine assumes the Lines are running in the same direction when they are not, and it averages the locations between the wrong ends of the selected Lines.]  But this takes care of that, in limited testing, using a slightly different approach [(defun) rather than (setq)] to pbejse's _nonz function.  [And I'm putting it in a code window this time because of the colon-followed-by-S element, so it won't be a smiley for those who don't have those turned off.]  Also, it works without the :E I had in the (ssget) mode before.

 

(defun C:LB (/ noZ ss lin ed s1 e1 s2 e2 int); = Line Between
  (defun noZ (pt) (list (car pt) (cadr pt)))
  (prompt "\nTo draw a Line halfway between two Lines,")
  (foreach num '(1 2)
    (prompt (strcat "\nFor Line " (itoa num) ","))
    (while
      (not (setq ss (ssget "_+.:S" '((0 . "LINE")))))
      (prompt (strcat "\nNothing selected, or not a Line.  For Line " (itoa num) ","))
    ); while
    (setq lin (ssname ss 0)); [line]
    (setq ed (entget lin)); [entity data]
    (set (read (strcat "s" (itoa num))) (cdr (assoc 10 ed))); s1 or s2 [start]
    (set (read (strcat "e" (itoa num))) (cdr (assoc 11 ed))); e1 or e2 [end]
  ); foreach
  (setq int (inters (noZ s1) (noZ s2) (noZ e1) (noZ e2))); T or nil -- opposite directions
  (entmake
    (list
      '(0 . "LINE")
      (cons 10 (mapcar '/ (mapcar '+ s1 (if int e2 s2)) '(2 2 2)))
      (cons 11 (mapcar '/ (mapcar '+ e1 (if int s2 e2)) '(2 2 2)))
    ); list
  ); entmake
); defun

 

Kent Cooper
*Expert Elite*
hmsilva
Posts: 2,639
Registered: ‎12-17-2004
Message 15 of 26 (370 Views)

Re: Line between two lines

02-20-2013 09:14 AM in reply to: Kent1Cooper

Kent Cooper,
the mistake was mine, only after having placed the post, I read the [assumes same plane], my apologies.
One more thing, when I wrote, gives error, in relation to the "inters" function, what I meant was that the function looks for a true intersection if are given 3D points, as this case is just to test the direction the lines were created, gives error not finding the intersection, so to use the  "inters" function, in this case, we have to provide 2D points.

 


Henrique

*Expert Elite*
Kent1Cooper
Posts: 5,231
Registered: ‎09-13-2004
Message 16 of 26 (362 Views)

Re: Line between two lines

02-20-2013 11:01 AM in reply to: hmsilva

hmsilva wrote:

.... the function looks for a true intersection if are given 3D points, as this case is just to test the direction the lines were created, gives error not finding the intersection, so to use the  "inters" function, in this case, we have to provide 2D points.

....


It would, of course, work with 3D points, if they're all in a common plane.  I considered forcing them to be like that by including a Z component of 0 in each point for the (inters) test, that is, in place of doing this:

 

(defun noZ (pt) (list (car pt) (cadr pt)))

 

doing this instead:

 

(defun Z0 (pt) (list (car pt) (cadr pt) 0))

 

But I found that the X & Y components are enough, so I left it that way.

 

Then I played around and found some interesting things.  If I did a series of them, and then typed U, it undid everything back to the previous regular AutoCAD command [in this instance, the APPLOAD that brought in the command definition], meaning it took away all of the halfway-between Lines I had made, together.  So I added undo beginning and ending within the routine, so you can undo one at a time.  And because of that, I added error handling to make sure the undo ending happens, in case something goes wrong or you cancel it [e.g. hit Esc when it's asking for the second Line], so you won't be left with an undo beginning that doesn't have an ending.

 

I also found that it doesn't work quite as expected under some circumstances with Lines that intersect or if one overlaps their apparent/virtual intersection.  But I let that stand, because it could be impossible for the routine to determine what "should" be the expected result in a lot of situations.  See notes at the top of the attached.

Kent Cooper
*Expert Elite*
hmsilva
Posts: 2,639
Registered: ‎12-17-2004
Message 17 of 26 (358 Views)

Re: Line between two lines

02-20-2013 11:20 AM in reply to: Kent1Cooper

Kent Cooper,

as usual, a very good code!

 

Henrique

*Expert Elite*
Kent1Cooper
Posts: 5,231
Registered: ‎09-13-2004
Message 18 of 26 (354 Views)

Re: Line between two lines

02-20-2013 12:15 PM in reply to: hmsilva

hmsilva wrote:

Kent Cooper,

as usual, a very good code!

 

Henrique


Thank you.  I will sometimes "go all the way" like that with something if I think we'll have a use for it around here.  This one, maybe we won't have all that much use for, but we'll see -- just knowing it's available may reveal that a situation like that arises more often than I think.

Kent Cooper
*Expert Elite*
pbejse
Posts: 2,406
Registered: ‎11-24-2009
Message 19 of 26 (343 Views)

Re: Line between two lines

02-20-2013 07:30 PM in reply to: Kent1Cooper

Kent1Cooper wrote:

If you can stand another approach [I kept daydreaming about it -- is there something wrong with me?]....

 


:smileylol: I do that myself sometimes

 

 

Mentor
smaher12
Posts: 172
Registered: ‎11-20-2011
Message 20 of 26 (295 Views)

Re: Line between two lines

03-01-2013 10:49 AM in reply to: pbejse

 


Kent1Cooper wrote:

If you can stand another approach [I kept daydreaming about it -- is there something wrong with me?]....

 



I was just thinking, what if you wanted to include polylines???

You are not logged in.

Log into access your profile, ask and answer questions, share ideas and more. Haven't signed up yet? Register

Announcements
Are you familiar with the Autodesk Expert Elites? The Expert Elite program is made up of customers that help other customers by sharing knowledge and exemplifying an engaging style of collaboration. To learn more, please visit our Expert Elite website.

Need installation help?

Start with some of our most frequented solutions to get help installing your software.

Ask the Community