### Author Topic: -={ Challenge }=- Enclose lines  (Read 5726 times)

0 Members and 1 Guest are viewing this topic.

#### zak26

• Newt
• Posts: 33
##### Re: -={ Challenge }=- Enclose lines
« Reply #60 on: July 04, 2023, 12:38:41 PM »
It is worth noting that, for an arbitrary point list, the problem becomes this -

https://www.theswamp.org/index.php?topic=30434.0
You're right for arbritrary or Lbracket-Rbracket-shapes, the code I posted initially works pretty well and this includes a modified version of your solution on the link, but it just doesn't solve well the problem I had on just parallel lines, probably the other solutions posted by domenicomania or El Jefe or kasmo work much better
« Last Edit: July 04, 2023, 02:58:00 PM by zak26 »

#### Lee Mac

• Seagull
• Posts: 12912
• London, England
##### Re: -={ Challenge }=- Enclose lines
« Reply #61 on: July 04, 2023, 01:55:45 PM »
FWIW, this was my approach -

Code - Auto/Visual Lisp: [Select]
1. ;; Chain Points  -  Lee Mac
2. ;; Constructs an LWPolyline passing through all points in the supplied list
3. ;; lst - [lst] List of 2D points
4.
5. (defun LM:chainpoints ( lst / di1 di2 ent pt1 rtn tmp )
6.     (setq rtn (LM:convexhull lst)
7.           lst (vl-remove-if '(lambda ( a ) (vl-some '(lambda ( b ) (equal a b 1e-6)) rtn)) lst)
8.           ent
9.                 (list
10.                    '(000 . "LWPOLYLINE")
11.                    '(100 . "AcDbEntity")
12.                    '(100 . "AcDbPolyline")
13.                     (cons 090 (length rtn))
14.                    '(070 . 1)
15.                 )
16.                 (mapcar '(lambda ( x ) (cons 10 x)) rtn)
17.             )
18.         )
19.     )
20.             (setq pt1 (car lst))
21.             (while (and pt1 (equal 0.0 (setq di1 (distance pt1 (vlax-curve-getclosestpointto ent pt1))) 1e-6))
22.                 (setq lst (cdr lst)
23.                       pt1 (car lst)
24.                 )
25.             )
26.             pt1
27.         )
28.         (setq tmp nil)
29.         (foreach pt2 (cdr lst)
30.             (if (and (< (setq di2 (distance pt2 (vlax-curve-getclosestpointto ent pt2))) di1) (not (equal 0.0 di2 1e-6)))
31.                 (setq di1 di2
32.                       pt1 pt2
33.                 )
34.             )
35.         )
36.         (repeat (1+ (fix (+ (vlax-curve-getparamatpoint ent (vlax-curve-getclosestpointto ent pt1)) 1e-6)))
37.             (setq tmp (cons (car rtn) tmp)
38.                   rtn (cdr rtn)
39.             )
40.         )
41.         (setq rtn (append (reverse tmp) (list pt1) rtn)
42.               lst (vl-remove-if '(lambda ( x ) (equal x pt1 1e-6)) lst)
43.         )
44.                 (list
45.                     (cons -1 ent)
46.                    '(000 . "LWPOLYLINE")
47.                    '(100 . "AcDbEntity")
48.                    '(100 . "AcDbPolyline")
49.                     (cons 090 (length rtn))
50.                    '(070 . 1)
51.                 )
52.                 (mapcar '(lambda ( x ) (cons 10 x)) rtn)
53.             )
54.         )
55.     )
56. )
57.
58. ;; Convex Hull  -  Lee Mac
59. ;; Implements the Graham Scan Algorithm to return the Convex Hull of a list of points.
60. ;; lst - [lst] List of 2D points
61.
62. (defun LM:ConvexHull ( lst / 2pi hul pt0 )
63.     (cond
64.         (   (< (length lst) 4)
65.             lst
66.         )
67.         (   (setq 2pi (+ pi pi)
68.                   pt0 (car lst)
69.             )
70.             (foreach pt1 (cdr lst)
72.                         (and (equal (cadr pt1) (cadr pt0) 1e-8) (< (car pt1) (car pt0)))
73.                     )
74.                     (setq pt0 pt1)
75.                 )
76.             )
77.             (setq lst
78.                 (vl-sort lst
79.                         (lambda ( a b / c d )
80.                             (setq c (angle pt0 a)
81.                                   d (angle pt0 b)
82.                             )
83.                             (if (equal c 2pi 1e-6) (setq c 0.0))
84.                             (if (equal d 2pi 1e-6) (setq d 0.0))
85.                             (if (equal c d 1e-6)
86.                                 (< (distance pt0 a) (distance pt0 b))
87.                                 (< c d)
88.                             )
89.                         )
90.                     )
91.                 )
92.             )
93.             (setq hul (list (cadr lst) (car lst)))
94.             (foreach pt (cddr lst)
95.                 (setq hul (cons pt hul))
97.                     (setq hul (cons pt (cddr hul)))
98.                 )
99.             )
100.             hul
101.         )
102.     )
103. )
104.
105. ;; Clockwise-p  -  Lee Mac
106. ;; Returns T if p1,p2,p3 are clockwise oriented or collinear
107.
108. (defun LM:clockwise-p ( p1 p2 p3 )
109.     (<  (-  (* (- (car  p2) (car  p1)) (- (cadr p3) (cadr p1)))
110.             (* (- (cadr p2) (cadr p1)) (- (car  p3) (car  p1)))
111.         )
112.         1e-8
113.     )
114. )
115.

And a program to test:
Code - Auto/Visual Lisp: [Select]
1. (defun c:test ( / enx idx lst sel )
2.     (if (setq sel (ssget '((0 . "LINE"))))
3.             (repeat (setq idx (sslength sel))
4.                 (setq idx (1- idx)
5.                       enx (entget (ssname sel idx))
6.                       lst (consunique (cdr (assoc 10 enx)) lst)
7.                       lst (consunique (cdr (assoc 11 enx)) lst)
8.                 )
9.             )
10.             (LM:chainpoints lst)
11.         )
12.     )
13.     (princ)
14. )
15.
16. (defun consunique ( pnt lst )
17.     (if (vl-some '(lambda ( x ) (equal x pnt 1e-6)) lst) lst (cons pnt lst))
18. )
19.

Essentially: start with the convex hull and consecutively add the nearest points until the point list is exhausted or the point already lies on the generated polyline.

However, this approach will fail for some concave shapes containing vertices whose inside angle is less than 90 degrees (e.g. crescent shapes).

#### zak26

• Newt
• Posts: 33
##### Re: -={ Challenge }=- Enclose lines
« Reply #62 on: July 04, 2023, 02:55:01 PM »
it is a very complicated task
It seem that you were right Vovka, because there is no code that can take into account all the possible cases.

I want to thank all the participants that have posted codes and their knoledge to solve this problem, also as the critics, I found it very interesting and pretty good for learning.
« Last Edit: July 04, 2023, 02:59:43 PM by zak26 »

#### kdub_nz

• Mesozoic keyThumper
• SuperMod
• Water Moccasin
• Posts: 2132
• class keyThumper<T>:ILazy<T>
##### Re: -={ Challenge }=- Enclose lines
« Reply #63 on: July 04, 2023, 04:51:17 PM »
I just noticed something I thought interesting in the first post.

Almost all the corners have been chamfered in the 'new' boundary

. . . so any boundary created from the 'lines' will not replicate the original boundary.

Is the original surrounding geometry still available in the drawing ?

Called Kerry in my other life
Retired; but they dragged me back in !

I live at UTC + 13.00

---
Sometimes the question is more important than the answer.

#### zak26

• Newt
• Posts: 33
##### Re: -={ Challenge }=- Enclose lines
« Reply #64 on: July 04, 2023, 05:29:49 PM »
. . . so any boundary created from the 'lines' will not replicate the original boundary.
You're right the 'boundary' will follow up to the extents of the limits the lines had, so most of the time will be chamfered

Is the original surrounding geometry still available in the drawing ?
No, as in the problem I had when I had to solve it (like in january of this year) there is no known boundary, just supposed. I created new ones and deleted them just for the examples. but they're all irregular shapes anyone can create.

#### ribarm

• Gator
• Posts: 3255
• Marko Ribar, architect
##### Re: -={ Challenge }=- Enclose lines
« Reply #65 on: July 05, 2023, 10:40:08 AM »
Here is my humble version for test1.dwg...

Code - Auto/Visual Lisp: [Select]
1. (defun c:MR-connect-hatch-lines ( / next collinear-p ss idx li lix p1 p2 lil pts pp rtn p ipli )
2.
3.   (defun next ( p pts )
4.     (car (vl-sort (vl-remove p pts) '(lambda ( a b ) (< (distance a p) (distance b p)))))
5.   )
6.
7.   (defun collinear-p ( p1 p p2 )
8.     (equal (distance p1 p2) (+ (distance p1 p) (distance p p2)) 1e-6)
9.   )
10.
11.   (if (setq ss (ssget '((0 . "LINE"))))
12.       (repeat (setq idx (sslength ss))
13.         (setq li (ssname ss (setq idx (1- idx))))
14.         (setq p1 (cdr (assoc 10 (setq lix (entget li)))))
15.         (setq p2 (cdr (assoc 11 lix)))
16.         (setq lil (cons (list p1 p2) lil))
17.       )
18.       (setq p (car (vl-sort (apply 'append lil) '(lambda ( a b ) (if (= (cadr a) (cadr b)) (< (car a) (car b)) (< (cadr a) (cadr b)))))))
19.       (setq pts (apply 'append lil))
20.       (setq rtn (cons p rtn))
21.       (while (and (setq pp (next p pts)) (not (equal p pp 1e-6)))
22.         (setq lil (vl-sort lil '(lambda ( a b ) (or (< (distance (car a) p) (distance (car b) p)) (< (distance (cadr a) p) (distance (cadr b) p))))))
23.         (foreach li (reverse lil)
24.           (if
25.             (and
26.               (setq ip (inters (car li) (cadr li) p pp nil))
27.               (not (equal ip (car li) 1e-6))
28.               (not (equal ip (cadr li) 1e-6))
29.               (not (equal ip p 1e-6))
30.               (not (equal ip pp 1e-6))
31.               (setq ipli (list ip li))
32.               (collinear-p p (car ipli) pp)
33.             )
34.             (setq pp (car (vl-sort (cadr ipli) '(lambda ( a b ) (< (distance p a) (distance p b))))))
35.           )
36.         )
37.         (if pp
38.           (setq rtn (cons pp rtn))
39.         )
40.         (setq pts (vl-remove p pts))
41.         (setq p pp)
42.         (setq ipli nil)
43.         (if (> (length rtn) 2)
45.             (setq rtn (vl-remove (cadr rtn) rtn))
46.           )
47.         )
48.       )
49.           (list
50.             (cons 0 "LWPOLYLINE")
51.             (cons 100 "AcDbEntity")
52.             (cons 100 "AcDbPolyline")
53.             (cons 90 (length rtn))
54.             (cons 70 (1+ (* 128 (getvar 'plinegen))))
55.             (cons 38 0.0)
56.           )
57.           (mapcar '(lambda ( p ) (cons 10 p)) rtn)
58.           (list (list 210 0.0 0.0 1.0))
59.         )
60.       )
61.     )
62.   )
63.   (princ)
64. )
65.

Regards, M.R.
« Last Edit: July 07, 2023, 10:02:22 AM by ribarm »
Marko Ribar, d.i.a. (graduated engineer of architecture)

#### ScottMC

• Newt
• Posts: 191
##### Re: -={ Challenge }=- Enclose lines
« Reply #66 on: July 05, 2023, 10:12:00 PM »
Excellant Marco! It does so well.

#### liuhe

• Mosquito
• Posts: 8
##### Re: -={ Challenge }=- Enclose lines
« Reply #67 on: July 07, 2023, 03:33:24 AM »
MY CODE  FOR TEST1.DWG

If it is test2, it will become complex

Code - Auto/Visual Lisp: [Select]
1.
2. (DEFUN C:TT (/ SS I LST1 E ANG P10 P11 ANG1 PC PP ELST LST2 LST3 LST4)
3.   (SETQ SS (SSGET '((0 . "*LINE"))))
4.   (IF (NOT SS)
5.   )
6.   (SETQ I    0
7.         LST1 NIL
8.         E    (SSNAME SS I)
9.   )
10.   (REPEAT (SSLENGTH SS)
11.     (SETQ E    (SSNAME SS I)
12.           P10  (vlax-curve-getStartPoint E)
13.           P11  (vlax-curve-getEndPoint E)
14.           ANG1 (ANGLE P10 P11)
15.           PC   (MID P10 P11)
16.     )
17.     (IF (NOT (EQUAL ANG ANG1 1E-8))
18.         (SETQ PP  P10
19.               P10 P11
20.               P11 PP
21.         )
22.       )
23.     )
24.     (SETQ ELST (LIST PC P10 P11)
25.           LST1 (CONS ELST LST1)
26.           I    (1+ I)
27.     )
28.   )
29.   (SETQ LST1 (vl-sort LST1
30.                       (function (lambda (e1 e2)
31.                                   (< (CAR (car e1)) (CAR (car e2)))
32.                                 )
33.                       )
34.              )
35.         LST2 (MAPCAR (FUNCTION (LAMBDA (X) (CADR X))) LST1)
36.         LST3 (MAPCAR (FUNCTION (LAMBDA (X) (CADDR X))) LST1)
37.         LST4 (APPEND LST2 (REVERSE LST3) (LIST (CAR LST2)))
38.         E    (Make-LWPOLYLINE lst4)
39.   )
40.   (PRINC)
41. )
42.
43. (defun Make-LWPOLYLINE (lst / PT)
44.       (list '(0 . "LWPOLYLINE")
45.             '(100 . "AcDbEntity")
46.             '(100 . "AcDbPolyline")
47.             (cons 90 (length lst))
48.       )
49.       (mapcar '(lambda (pt) (cons 10 pt)) lst)
50.     )
51.   )
52. )
53.
54.
55. (defun MID (po1 po2)
56.   (setq po (MAPCAR '(lambda (X Y) (* (+ X Y) 0.5)) po1 po2))
57. )
58.
59.

#### ribarm

• Gator
• Posts: 3255
• Marko Ribar, architect
##### Re: -={ Challenge }=- Enclose lines
« Reply #68 on: July 07, 2023, 10:01:30 AM »
Your test2.dwg is somewhat corrupted... To get normal LINES you'll have to explode them all firstly... Then, only then will greedy algorithm work...
Here is greedy :

Code - Auto/Visual Lisp: [Select]
1. (defun c:MR-connect-hatch-lines-greedy ( / next collinear-p ss idx li lix p1 p2 lil pts pp rtn p )
2.
3.   (defun next ( lst cmp / rtn ) ;;; (next) = (car-sort) ;;;
4.     (setq rtn (car lst))
5.     (foreach itm (cdr lst)
6.       (if (apply cmp (list itm rtn))
7.         (setq rtn itm)
8.       )
9.     )
10.     rtn
11.   )
12.
13.   (defun collinear-p ( p1 p p2 )
14.     (equal (distance p1 p2) (+ (distance p1 p) (distance p p2)) 1e-6)
15.   )
16.
17.   (if (setq ss (ssget '((0 . "LINE"))))
18.       (repeat (setq idx (sslength ss))
19.         (setq li (ssname ss (setq idx (1- idx))))
20.         (setq p1 (cdr (assoc 10 (setq lix (entget li)))))
21.         (setq p2 (cdr (assoc 11 lix)))
22.         (setq lil (cons (list p1 p2) lil))
23.       )
24.       (setq p (next (setq pts (apply 'append lil)) '(lambda ( a b ) (if (= (cadr a) (cadr b)) (< (car a) (car b)) (< (cadr a) (cadr b))))))
25.       (setq rtn (cons p rtn))
26.       (while (and (setq pp (next (setq pts (vl-remove p pts)) '(lambda ( a b ) (< (distance a p) (distance b p))))) (not (equal p pp 1e-6)))
27.         (if (and pp (not (vl-position pp rtn)))
28.           (setq rtn (cons pp rtn))
29.         )
30.         (if (> (length rtn) 2)
32.             (setq rtn (vl-remove (cadr rtn) rtn))
33.           )
34.         )
35.         (setq pts (vl-remove p pts))
36.         (setq p pp)
37.       )
38.           (list
39.             (cons 0 "LWPOLYLINE")
40.             (cons 100 "AcDbEntity")
41.             (cons 100 "AcDbPolyline")
42.             (cons 90 (length rtn))
43.             (cons 70 (1+ (* 128 (getvar 'plinegen))))
44.             (cons 38 0.0)
45.           )
46.           (mapcar '(lambda ( p ) (cons 10 p)) rtn)
47.           (list (list 210 0.0 0.0 1.0))
48.         )
49.       )
50.     )
51.   )
52.   (princ)
53. )
54.

HTH., M.R.
Marko Ribar, d.i.a. (graduated engineer of architecture)