Author Topic: Is there a way to turn close lines into closed polylines?  (Read 294 times)

0 Members and 1 Guest are viewing this topic.

dussla

  • Bull Frog
  • Posts: 273
Is there a way to turn close lines into closed polylines?
« on: April 07, 2021, 05:36:31 AM »
Hello
No matter how much I use my hair, I can’t find a good way
Sorry to ask you a question

I want to make close lines into closed polylines
Sorry, but may you please review the attached CAD file

Stefan

  • Bull Frog
  • Posts: 252
Re: Is there a way to turn close lines into closed polylines?
« Reply #1 on: April 07, 2021, 06:45:41 AM »
Try this

Code - Auto/Visual Lisp: [Select]
  1. ;Join parallel lines
  2. ;Stefan M - 07.04.2021
  3. (defun c:ljoin ( / *error* acDoc ss d i en el p1 p2 a y p l p3 p4)
  4.  
  5.   (if (= 8 (logand 8 (getvar 'undoctl))) (vla-endundomark acDoc))
  6.  
  7.  
  8.   (defun *error* (msg)
  9.     (and
  10.       msg
  11.       (not (wcmatch (strcase msg) "*CANCEL*,*QUIT*,*EXIT*"))
  12.       (princ (strcat "\nError: " msg))
  13.     )
  14.     (if (= 8 (logand 8 (getvar 'undoctl))) (vla-endundomark acDoc))
  15.     (princ)
  16.   )
  17.   (if
  18.     (and
  19.       (or
  20.         (setq ss (ssget "_I" '((0 . "LINE"))))
  21.         (setq ss (ssget '((0 . "LINE"))))
  22.       )
  23.       (progn
  24.         (initget 6)
  25.         (setq d (getdist "\nSpecify maximum gap: "))
  26.       )
  27.     )
  28.     (progn
  29.       (sssetfirst nil nil)
  30.       (setq d (+ d 1e-8))
  31.       (repeat (setq i (sslength ss))
  32.         (setq en (ssname ss (setq i (1- i)))
  33.               el (entget en)
  34.               p1 (cdr (assoc 10 el))
  35.               p2 (cdr (assoc 11 el))
  36.               a  (angle p1 p2)
  37.               a  (atan (/ (sin a) (cos a)))
  38.               a  (if (equal a (/ pi -2) 1e-5) (/ pi 2) a)
  39.               y  (apply '- (mapcar '* (list (sin a) (cos a)) p1))
  40.         )
  41.         (if
  42.           (setq p (vl-some
  43.                    '(lambda (x)
  44.                       (if
  45.                         (and
  46.                           (equal (car x) a 1e-3)
  47.                           (equal (cadr x) y d)
  48.                         )
  49.                         x
  50.                       )
  51.                     )
  52.                     l
  53.                  )
  54.           )
  55.           (progn
  56.             (setq l (vl-remove p l)
  57.                   p3 (caddr p)
  58.                   p4 (cadddr p)
  59.             )
  60.             (if
  61.               (< (distance p1 p3) (distance p1 p4))
  62.               (mapcar 'set '(p3 p4) (list p4 p3))
  63.             )
  64.             (entmakex
  65.               (list
  66.                 '(0 . "LWPOLYLINE")
  67.                 '(100 . "AcDbEntity")
  68.                 '(100 . "AcDbPolyline")
  69.                 '(90 . 4)
  70.                 '(70 . 1)
  71.                 (cons 10 p1)
  72.                 (cons 10 p2)
  73.                 (cons 10 p3)
  74.                 (cons 10 p4)
  75.               )
  76.             )
  77.           )
  78.           (setq l (cons (list a y p1 p2 en) l))
  79.         )
  80.       )
  81.       (if l
  82.         (progn
  83.           (setq ss (ssadd))
  84.           (foreach x l (ssadd (nth 4 x) ss))
  85.           (sssetfirst nil ss)
  86.           (princ "\nSelected lines not joined.")
  87.         )
  88.       )
  89.     )
  90.   )
  91.   (*error* nil)
  92.   (princ)
  93. )
  94.  
« Last Edit: April 08, 2021, 06:51:21 AM by Stefan »

dussla

  • Bull Frog
  • Posts: 273
Re: Is there a way to turn close lines into closed polylines?
« Reply #2 on: April 07, 2021, 09:11:02 AM »
Wow it's the best
I really needed this routine
Thank you so much for making it so fast
Thank you, thank you and thank you very much.

Lee Mac

  • Seagull
  • Posts: 12458
  • London, England
Re: Is there a way to turn close lines into closed polylines?
« Reply #3 on: April 07, 2021, 04:49:08 PM »
Try this

Excellent solution Stefan :-)

I may be overlooking something obvious, but whilst studying your solution I struggled to understand how the following two expressions determine that the two lines are within the given proximity, independent of the end point used:
Code - Auto/Visual Lisp: [Select]
  1. y (apply '- (mapcar '* (list (sin a) (cos a)) p1))
  2. ...
  3. (equal (cadr x) y d)

Could you shed some light please?

Stefan

  • Bull Frog
  • Posts: 252
Re: Is there a way to turn close lines into closed polylines?
« Reply #4 on: April 07, 2021, 05:46:50 PM »
Try this

Excellent solution Stefan :-)

I may be overlooking something obvious, but whilst studying your solution I struggled to understand how the following two expressions determine that the two lines are within the given proximity, independent of the end point used:
Code - Auto/Visual Lisp: [Select]
  1. y (apply '- (mapcar '* (list (sin a) (cos a)) p1))
  2. ...
  3. (equal (cadr x) y d)

Could you shed some light please?
Sure
Each line is defined by an angle a and the distance y (signed) from origin.
Angle a is normalized in range -pi/2...pi/2 in order to match a and a+pi.
The distance from origin y can be calculated analytically given the 2 points defining the line, but I think is to complicated in lisp. For that reason, I uses the Y component of the rotational formula.
Basically, I rotated the line around 0,0 to get a horizontal line, then I got the Y position. Well, you don't need to rotate the entire line, one point is enough because Y is constant in a horizontal line. It could be p2 as well,
The rotational formula, for a point x,y and angle a, counterclockwise (trigonometric), is:
X = x cos(a) - y sin (a)
Y = x sin(a) + y cos (a)
To complicate the things a little bit, the rotation needed is -a; sin (-a) = -sin (a), cos (-a) = cos (a), so Y = - x sin (a) + y cos (a). So it's negative of what I used (to avoid reversing some lists), but it doesn't matter.
The equal function is obvious, it just pairs up 2 lines within a gap d.




Lee Mac

  • Seagull
  • Posts: 12458
  • London, England
Re: Is there a way to turn close lines into closed polylines?
« Reply #5 on: April 07, 2021, 06:22:15 PM »
Basically, I rotated the line around 0,0 to get a horizontal line, then I got the Y position.

This is what I was missing - many thanks indeed Stefan for taking the time to explain your method here, I greatly appreciate it. It's unfortunate that collinear lines could spoil the elegance of this solution - perhaps (equal (cadr x) y d) could be replaced with something like (< 1e-8 (abs (- (cadr x) y)) d) to account for this before we must resort to sorting the entire set...

Stefan

  • Bull Frog
  • Posts: 252
Re: Is there a way to turn close lines into closed polylines?
« Reply #6 on: April 07, 2021, 06:52:00 PM »
Basically, I rotated the line around 0,0 to get a horizontal line, then I got the Y position.

This is what I was missing - many thanks indeed Stefan for taking the time to explain your method here, I greatly appreciate it. It's unfortunate that collinear lines could spoil the elegance of this solution - perhaps (equal (cadr x) y d) could be replaced with something like (< 1e-8 (abs (- (cadr x) y)) d) to account for this before we must resort to sorting the entire set...
Based on OP's clean and clear sample, I decided that is not worth investigating further :)
A solution for collinear lines could be a min and a max gap. OP whould be happy, but someone else might not.
I'm sure there are more exceptions.
This one would require a lot more conditions than my lisp (pairing 1-3 and 2-4):
                   ----------------- 1
----------------- 2
               ----------------- 3
-------------------- 4

Lee Mac

  • Seagull
  • Posts: 12458
  • London, England
Re: Is there a way to turn close lines into closed polylines?
« Reply #7 on: April 07, 2021, 07:07:37 PM »
Based on OP's clean and clear sample, I decided that is not worth investigating further :)

Agreed - I should add that it wasn't a criticism of your code by any means - just thinking through the consequences of the method employed.

Stefan

  • Bull Frog
  • Posts: 252
Re: Is there a way to turn close lines into closed polylines?
« Reply #8 on: April 07, 2021, 08:25:18 PM »
Oh, don't worry, man, you could even criticize, in a technical forum it's just a discussion.
If I sound too serious it's the language barrier, I cannot say whatever I want.
This is why I used a smile... Is that a smile? I admit it doesn't look too happy... Maybe this   :lol:

dussla

  • Bull Frog
  • Posts: 273
Re: Is there a way to turn close lines into closed polylines?
« Reply #9 on: April 08, 2021, 12:02:30 AM »
Stefan

Sorry and sorry
Sorry to have one question, but I would like to ask you a question.
The code is really good

Can you see the attached file?
I'm sorry, but can you see the error part?


ps: Please understand that there is an error because I use a translation program to write.

Stefan

  • Bull Frog
  • Posts: 252
Re: Is there a way to turn close lines into closed polylines?
« Reply #10 on: April 08, 2021, 07:06:26 AM »
Stefan

Sorry and sorry
Sorry to have one question, but I would like to ask you a question.
The code is really good

Can you see the attached file?
I'm sorry, but can you see the error part?


ps: Please understand that there is an error because I use a translation program to write.

Your lines are not perfectly vertical. Here is a random pair of failing lines:
Code - Auto/Visual Lisp: [Select]
  1. 15788.30727083201 Start X
  2. 15788.30727095122 End X
  3. -1.570796326732154 Angle
  4.  
  5. 15838.3072707128 Start X
  6. 15838.30727083201 End X
  7. 1.570796326732154 Angle

Best I can offer is a fuzz factor to correct this position error.
See my first post.

dussla

  • Bull Frog
  • Posts: 273
Re: Is there a way to turn close lines into closed polylines?
« Reply #11 on: April 08, 2021, 08:44:52 AM »
The code works perfectly
I like it so much

Despite being busy, thank you so much for modifying the code
Thank you
Thank you again
Thank you again and again