Lisp to join vertical lines with horizontal lines

Lisp to join vertical lines with horizontal lines

Anonymous
Not applicable
3,438 Views
15 Replies
Message 1 of 16

Lisp to join vertical lines with horizontal lines

Anonymous
Not applicable

 Hi guys..am searching a lisp code to join the vertical lines with horizontal lines.the length will vary for both horizontal and vertical.It should recognize the the lines and join the lines which contain same x vales.Have attached a pic of my requirement. Left is the input and right is the output. The lines in red is the one which the lisp should make.

0 Likes
Accepted solutions (1)
3,439 Views
15 Replies
Replies (15)
Message 2 of 16

salman_majgaonkar
Contributor
Contributor

Hello abilash,

 

check out with this sample code.

 

 

Command is "JVL" & "JHL"

 

Untitled.jpg

 

Salman M.

Message 3 of 16

Anonymous
Not applicable

hi bro....tried out this code...but it is not working...says bad argument type:numberp:nil

tried for separate JVL and together also as u mentioned in the command

 

0 Likes
Message 4 of 16

SeeMSixty7
Advisor
Advisor
Accepted solution

Try this. It looks like you may already have a solution, but here is my option for you.

 

(defun bldLineYPointList(lypl-ss)
 (setq lyplss-len (sslength lypl-ss)
    lyplss-cnt 0
    lypl-returnList (list)
 )
 (while (< lyplss-cnt lyplss-len)
  (setq lyplent (ssname lypl-ss lyplss-cnt)
     lypldata (entget lyplent)
     lyplpoint1 (cdr (assoc 10 lypldata))
     lyplpoint2 (cdr (assoc 11 lypldata))
     lyplss-cnt (1+ lyplss-cnt)
  )
  (if (/= (nth 1 lyplpoint1) (nth 1 lyplpoint2))
   (setq lypl-returnList (append lypl-returnList (list (list (rtos (nth 1 lyplpoint1) 2 8) lyplpoint1)))
      lypl-returnList (append lypl-returnList (list (list (rtos (nth 1 lyplpoint2) 2 8) lyplpoint2)))
   )
  )
 )
 lypl-returnList
)
(defun findMatchYCoord(fmyc-point fmyc-list / fmyc-returnPoint)
 (setq fmyc-match (assoc (rtos (cadr fmyc-point) 2 8) fmyc-list))
 (if (and fmyc-match (/= (car fmyc-point) (car (cadr fmyc-match))))
  (setq fmyc-returnPoint (cadr fmyc-match))
  (setq fmyc-returnPoint nil)
 )
 fmyc-returnPoint
)
(defun makeLine (ml-pt1 ml-pt2)
 (command "line" ml-pt1 ml-pt2 "")
)
(defun c:V2HLINES()
 (setq v2h-ss (ssget "X" '((0 . "LINE"))))
 (if v2h-ss
  (progn
   (setq v2h-pointList (bldLineYPointList v2h-ss)
      v2h-workList v2h-pointList
   )
   (foreach tpoint v2h-pointList
    (setq v2h-ycoord (car tpoint)
       v2h-point (cadr tpoint)
       v2h-workList (cdr v2h-workList)
       v2h-matchPoint (findMatchYCoord v2h-point v2h-workList)
    )
    (if v2h-matchPoint
     (makeLine v2h-point v2h-matchPoint)
    )
   )
  )
 )
)

0 Likes
Message 5 of 16

salman_majgaonkar
Contributor
Contributor

 

0 Likes
Message 6 of 16

SeeMSixty7
Advisor
Advisor

Nice Video!, grin. It definitely shows your code works. I think the v_p_abilash's issue is he may have selected something other than lines in his selection set.

 

v_p_abilash Try the command and keep your selection set to just LINES.

0 Likes
Message 7 of 16

Kent1Cooper
Consultant
Consultant

@SeeMSixty7 wrote:

.... I think the @Anonymous's issue is he may have selected something other than lines in his selection set.

 

@Anonymous Try the command and keep your selection set to just LINES.


If that's the problem, there could be two reasons for it:

1)  They selected some appropriate Lines but also some other things [such as in a Window selection];

 

2)  The "lines" are really single-segment Polylines.

 

If it's 1), you can restrict the selection to only Lines, no matter what else may be in the area, by changing both instances of

 

(ssget)

 

to

 

(ssget '((0 . "LINE")))

 

and it won't "see" any other kind of entity in the selection.

 

If it's 2), you can allow Polylines in addition to Lines [even a combination of both types], by changing the above to:

 

(ssget '((0 . "LINE,LWPOLYLINE")))

 

and changing these lines in both commands:

 

(setq ha6 (cdr (assoc 10 (entget (ssname ha1 ha2)))))
(setq ha7 (cdr (assoc 11 (entget (ssname ha1 ha2)))))

 

to these instead:

 

(setq ha6 (vlax-curve-getStartPoint (ssname ha1 ha2)))
(setq ha7 (vlax-curve-getEndPoint (ssname ha1 ha2)))

 

and if necessary, adding

 

(vl-load-com)

 

somewhere.  In that case, it may be worth adding some other checks, such as whether any Polylines selected are made of one line segment only.

Kent Cooper, AIA
0 Likes
Message 8 of 16

Anonymous
Not applicable

hey guys...it is working.,....it was a gr8 help..thx...as u mentioned it was in polylines...so i changed it to normal lines and tried it and it worked

 

0 Likes
Message 9 of 16

alanjt_
Collaborator
Collaborator

This seemed like an interesting exercise, so I thought I'd contribute...

 

(defun c:test (/ ss i e lst)
  ;; http://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/lisp-to-join-vertical-lines-with-horizontal-lines/td-p/6583601

  (if (and (setq ss (ssget '((-4 . "<OR")
                             (0 . "LINE")
                             (-4 . "<AND")
                             (0 . "LWPOLYLINE")
                             (90 . 2)
                             (-4 . "AND>")
                             (-4 . "OR>")
                            )
                    )
           )
           (>= (setq i (sslength ss)) 2)
      )
    (progn
      (repeat i
        (setq e   (ssname ss (setq i (1- i)))
              lst (cons (vlax-curve-getStartPoint e) (cons (vlax-curve-getEndPoint e) lst))
        )
      )

      (mapcar (function (lambda (a b) (entmakex (list '(0 . "LINE") (cons 10 a) (cons 11 b)))))
              (cdr (setq lst (vl-sort lst (function (lambda (a b) (< (car a) (car b)))))))
              (cddr lst)
      )
    )
  )

  (princ)
)
(vl-load-com)
(princ)
0 Likes
Message 10 of 16

Kent1Cooper
Consultant
Consultant

@alanjt_ wrote:

.... 

.... (ssget '(....
                             (0 . "LWPOLYLINE")
                             (90 . 2)
....

Just in case it should ever be necessary to make the distinction [perhaps not in the OP's circumstances], those criteria could sometimes find unwanted things.  A single-arc-segment Polyline would fit them, as well as any closed Polyline of 2 segments, whether they are both arc segments [such as DONUT makes, or a tiny REVCLOUD], a line and an arc, or even two line segments on top of each other.  In the last case, it would look like what you want, but its StartPoint and EndPoint would be at the same place, so the routine would be thrown off.

 

It's more complicated to filter for only open Polylines in (ssget), because the same (assoc 70) entry that has the 1 bit in it if it's closed also has the 128 bit if linetype generation is enabled.  It takes entries like this:

 

(-4 . "<NOT")

  (-4 . "&") (70 . 1); [1 bit included if closed]

(-4  . "NOT>")

 

I'm not sure you can filter out arc segments in (ssget) for certain [no (assoc 42) entry with other-than-zero value], since there will be more than one (assoc 42) entry even for a single-segment Polyline.  [I haven't experimented.]  But if not, and if you need to avoid those, it can certainly be done by stepping through the resulting selection and checking for that in each one.

Kent Cooper, AIA
0 Likes
Message 11 of 16

alanjt_
Collaborator
Collaborator

I must admit, I didn't consider filtering out closed single segment lwpolylines. I didn't even realize one could do such a thing. Which leads me to a question of why in the world would you draw a closed single segment lwpolyline?

No, arcs haven't been filtered out either, but for that matter, neither are non-vertical lines. 

 

 

 

0 Likes
Message 12 of 16

Kent1Cooper
Consultant
Consultant

@alanjt_ wrote:

... I didn't consider filtering out closed single segment lwpolylines. I didn't even realize one could do such a thing. Which leads me to a question of why in the world would you draw a closed single segment lwpolyline?

... 


Really a closed two-vertex, rather than single-segment, Polyline [it can't be closed if it has only one segment], with two segments lying on top of each other.  Accidentally would be the primary "why" for such a thing, I imagine -- somehow hitting C in ending the command.

Kent Cooper, AIA
0 Likes
Message 13 of 16

Anonymous
Not applicable

hi...this code seems to work perfect for me...but there seems to be some glitches in the layout which am working.am not able to attach the dwg file  over here. so have took a snapshot of it..

0 Likes
Message 14 of 16

SeeMSixty7
Advisor
Advisor

I'm glad to hear the code works for you.

 

Try again to attach the drawing file, that way I can test better.

 

A couple of things to try. Are there other layers in the drawing that are off or frozen? If so they could be providing additional points that cause issues. Also make sure OSNAPS are off, other wise your new lines may be grabbing osnap points to be created.

 

Let me know if that helps.

0 Likes
Message 15 of 16

Anonymous
Not applicable

hi...the osnap setting i have set off and there are many other layers, but i have switched off all the unwanted layers. So technically there is only one layer which is required to be joined.

How am i supposed to attach a dwg file in this??...am trying to do it but not able to...

0 Likes
Message 16 of 16

SeeMSixty7
Advisor
Advisor

the ssget function does not care if layers are off or frozen. That's why I asked. It might be useful to add a filter to use the current layer then that would isolate to just using the current layer for lines instead of all layers.

 

Change the following line

 (setq v2h-ss (ssget "X" '((0 . "LINE"))))

 

to

 

 (setq v2h-ss (ssget "X" (list (cons 0 "LINE") (cons 8 (getvar "CLAYER")))))

 

good luck

0 Likes