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

0 Members and 1 Guest are viewing this topic.

kasmo

  • Newt
  • Posts: 28
Re: -={ Challenge }=- Enclose lines
« Reply #30 on: July 01, 2023, 08:21:28 AM »
Good enough for the sample dwg, hehe

are you sure?  :laugh:

Quote
Command: OUTLINE
Select objects: Specify opposite corner: 61 found
Select objects:
; error: no function definition: REMOVE

Not my fault you're using inferior CAD software  :wink:  I changed it now to vl-remove just for you  :-)
« Last Edit: July 01, 2023, 04:37:58 PM by kasmo »

JohnK

  • Administrator
  • Seagull
  • Posts: 10648
Re: -={ Challenge }=- Enclose lines
« Reply #31 on: July 01, 2023, 10:57:39 AM »
this is the first time i see a program that needs a full week to be tested :)
as for Saturdays - not working

Saturday here

Okay I fixed my code above (I had a paren misplaced). ...Hopefully I got it fixed so it could be tested on Saturday/Sunday. :)
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

VovKa

  • Water Moccasin
  • Posts: 1632
  • Ukraine
Re: -={ Challenge }=- Enclose lines
« Reply #32 on: July 01, 2023, 11:38:43 AM »
Okay I fixed my code above (I had a paren misplaced). ...Hopefully I got it fixed so it could be tested on Saturday/Sunday. :)
of course i fixed the misplaced paren myself before testing
https://imgur.com/a/0xKVC0z

zak26

  • Newt
  • Posts: 33
Re: -={ Challenge }=- Enclose lines
« Reply #33 on: July 01, 2023, 11:41:43 AM »
enl doesn't like this case
This didn't happened on my side, could you send me your test file to test it further?

Edit: Not needed, I found an example where it happens, working on it.
« Last Edit: July 01, 2023, 12:26:41 PM by zak26 »

JohnK

  • Administrator
  • Seagull
  • Posts: 10648
Re: -={ Challenge }=- Enclose lines
« Reply #34 on: July 01, 2023, 11:51:51 AM »
Okay I fixed my code above (I had a paren misplaced). ...Hopefully I got it fixed so it could be tested on Saturday/Sunday. :)
of course i fixed the misplaced paren myself before testing
https://imgur.com/a/0xKVC0z

Ugh! I’ll have to put one of the sort algorithms into my mock-up to handle a window selection. But what happens if you have the items preselected before the program is called (I imagine it wouldn’t make any difference at all)?
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

VovKa

  • Water Moccasin
  • Posts: 1632
  • Ukraine
Re: -={ Challenge }=- Enclose lines
« Reply #35 on: July 01, 2023, 12:18:04 PM »
But what happens if you have the items preselected before the program is called (I imagine it wouldn’t make any difference at all)?
it does not make any difference

zak26

  • Newt
  • Posts: 33
Re: -={ Challenge }=- Enclose lines
« Reply #36 on: July 01, 2023, 02:12:42 PM »
Still having this kind of problem, making it recursive did fix the mayor problems but this is still remaining on this kind of shapes (on the dwg)

Lee Mac

  • Seagull
  • Posts: 12915
  • London, England
Re: -={ Challenge }=- Enclose lines
« Reply #37 on: July 01, 2023, 05:59:15 PM »
Still having this kind of problem, making it recursive did fix the mayor problems but this is still remaining on this kind of shapes (on the dwg)

Will probably post my code next week - the algorithm isn't particularly clever though.


It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8723
  • AKA Daniel
Re: -={ Challenge }=- Enclose lines
« Reply #38 on: July 01, 2023, 11:17:15 PM »
another method, make some assumptions  :mrgreen:
Rotate each line seg to align with Y
Sort the line segs by X.
If needed, flip each seg so its kind of codirectional to Y
Build the pline halfs
Rotate it back

Code - Python: [Select]
  1. import PyRx as Rx
  2. import PyGe as Ge
  3. import PyGi as Gi
  4. import PyDb as Db
  5. import PyAp as Ap
  6. import PyEd as Ed
  7. from functools import cmp_to_key
  8.  
  9. def segCmp(segL, segR):
  10.     pl = segL.midPoint()
  11.     pr = segR.midPoint()
  12.     if pl.x < pr.x:
  13.         return -1
  14.     elif pl.x > pr.x:
  15.         return 1
  16.     else:
  17.         return 0
  18.  
  19. def PyRxCmd_pydoit():
  20.     try:
  21.         filter = [(Db.DxfCode.kDxfStart, "LINE,LWPOLYLINE")]
  22.         ssres = Ed.Editor.select(filter)
  23.         if ssres[0] != Ed.PromptStatus.eNormal:
  24.             return
  25.        
  26.         ss = ssres[1].toList()
  27.         dir = None
  28.         segs = []
  29.  
  30.         for id in ss:
  31.             if id.isDerivedFrom(Db.Curve.desc()):
  32.                 curve = Db.Curve(id)
  33.                 segs.append(Ge.LineSeg3d(
  34.                     curve.getStartPoint(), curve.getEndPoint()))
  35.                 if dir == None:
  36.                     dir = curve.getEndPoint() - curve.getStartPoint()
  37.  
  38.         dir.normalize()
  39.         xform = Ge.Matrix3d()
  40.         xform.setToRotation(dir.angleTo(
  41.             Ge.Vector3d.kYAxis, Ge.Vector3d.kZAxis), Ge.Vector3d.kZAxis, Ge.Point3d.kOrigin)
  42.  
  43.         for seg in segs:
  44.             seg.transformBy(xform)
  45.  
  46.         segs.sort(key=cmp_to_key(segCmp))
  47.  
  48.         for seg in segs:
  49.             if seg.getStartPoint().y > seg.getEndPoint().y:
  50.                 seg.reverseParam()
  51.  
  52.         pline = Db.Polyline(len(segs) * 2)
  53.  
  54.         n = 0
  55.         for ind in range(0, len(segs)):
  56.             p = segs[ind].getStartPoint()
  57.             pline.addVertexAt(n, Ge.Point2d(p.x, p.y))
  58.             n += 1
  59.  
  60.         n = len(segs)
  61.         for ind in reversed(range(0, len(segs))):
  62.             p = segs[ind].getEndPoint()
  63.             pline.addVertexAt(n, Ge.Point2d(p.x, p.y))
  64.             n += 1
  65.  
  66.         pline.setClosed(True)
  67.         pline.setColorIndex(1)
  68.         pline.transformBy(xform.invert())
  69.        
  70.         db = Db.HostApplicationServices().workingDatabase()
  71.         model = Db.BlockTableRecord(db.modelSpaceId(), Db.OpenMode.ForWrite)
  72.         model.appendAcDbEntity(pline)
  73.  
  74.     except Exception as err:
  75.         print(err)
  76.  
« Last Edit: July 02, 2023, 01:13:51 AM by El Jefe »

kasmo

  • Newt
  • Posts: 28
Re: -={ Challenge }=- Enclose lines
« Reply #39 on: July 02, 2023, 04:16:33 AM »
Still having this kind of problem, making it recursive did fix the mayor problems but this is still remaining on this kind of shapes (on the dwg)
Assuming the lines were drawn in order works well in this case.
Code - Auto/Visual Lisp: [Select]
  1. (defun c:ol ( / l l2 eg )
  2.   (foreach x (vl-remove-if 'listp (mapcar 'cadr (ssnamex (ssget "_:L"))))
  3.     (setq l2 (append l2 (list (vlax-curve-getendpoint x))))
  4.   )
  5.   (entmakex (append (list '(0 . "LWPOLYLINE")
  6.                           '(100 . "AcDbEntity")
  7.                           '(100 . "AcDbPolyline")
  8.                           (cons 90 (+ (length l) (length l2)))
  9.                           '(70 . 1))
  10.                           (mapcar '(lambda (x) (cons 10 x)) (append l (reverse l2))))
  11.   )
  12. )
  13.  
Running multiple functions with different approaches and returning the outline with something like the lowest average vertex length would probably yield the best results.
« Last Edit: July 02, 2023, 04:27:17 AM by kasmo »

domenicomaria

  • Swamp Rat
  • Posts: 725
Re: -={ Challenge }=- Enclose lines
« Reply #40 on: July 02, 2023, 03:04:54 PM »
Code - Auto/Visual Lisp: [Select]
  1. (defun :LWP-EMK-V-LST   (v-lst)
  2.    (entmake
  3.       (append
  4.             (list   '(0 . "LWPOLYLINE")   '(100 . "AcDbEntity")   '(100 . "AcDbPolyline")   (cons 90 (length v-lst) ) )
  5.             (apply 'append    (mapcar '(lambda (i) (list (cons 10 i ) ) )  v-lst) )
  6.       )
  7.    )
  8. )
  9.  
  10. (defun :SS>OBJECT-LIST (ss / ind l)
  11.    (setq ind 0)
  12.    (repeat (sslength ss)
  13.       (setq l (cons (vlax-ename->vla-object (ssname ss ind) ) l) )      (setq ind (+ 1 ind) )
  14.    )
  15.    (reverse l)
  16. )
  17.  
  18.  
  19. (defun C:PARALLEL-PLINES-SHAPE (
  20.                                    /
  21.                                    -base-ang -base-ang-90 base-ang e-pt i i-pt-0 i-pt-1 o o-e-pt o-s-pt o-x-ang
  22.                                    p0 s-pt sorted-lst sp-ep-xp-lst ss ss-obj-lst v-lst x-ang x-dst x-ep
  23.                                    x-int x-obj x-sp
  24.                                )
  25.    (setvar 'nomutt 1)  (princ "\nnselect  objects :")
  26.    (setq ss (ssget '( (0 . "LWPOLYLINE"))))
  27.    (setvar 'nomutt 0)
  28.  
  29.    (setq ss-obj-lst    (:SS>OBJECT-LIST    ss ) )
  30.    
  31.  
  32.    (setq x-obj       (car ss-obj-lst)
  33.          s-pt        (vlax-curve-getStartPoint x-obj)
  34.          e-pt        (vlax-curve-getEndPoint   x-obj)
  35.          base-ang    (angle s-pt e-pt)
  36.          -base-ang   (angle e-pt s-pt )
  37.          -base-ang-90 (- base-ang (/ pi 2.0) )
  38.          i-pt-0       s-pt
  39.          i-pt-1      (polar i-pt-0 (+ base-ang (/ pi 2.0) ) (distance s-pt e-pt) )
  40.    )
  41.  
  42.    (setq sp-ep-xp-lst
  43.       (mapcar   '(lambda (o)  
  44.                    (setq o-s-pt     (vlax-curve-getStartPoint o)
  45.                         o-e-pt     (vlax-curve-getEndPoint   o)
  46.                         o-x-ang    (angle o-s-pt o-e-pt)
  47.                   )
  48.                   (cond
  49.                      ( (equal o-x-ang  base-ang 1e-6) (list o-s-pt o-e-pt  (inters i-pt-0 i-pt-1 o-s-pt o-e-pt nil) ) )
  50.                      ( (equal o-x-ang -base-ang 1e-6) (list o-e-pt o-s-pt  (inters i-pt-0 i-pt-1 o-s-pt o-e-pt nil) ) )
  51.                      (t (progn (princ "pline is not parallel to the others one !") nil) )
  52.                   )
  53.                )
  54.                ss-obj-lst
  55.       )
  56.    )
  57.  
  58.    (setq sp-ep-xp-lst (vl-remove nil sp-ep-xp-lst) )
  59.  
  60.    
  61.    (setq p0 (caddr (car sp-ep-xp-lst) )  )
  62.    
  63.    (setq sorted-lst   (vl-sort   (mapcar '(lambda (i)
  64.                                           (setq x-sp (car i) x-ep (cadr i) x-int (caddr i)
  65.                                                 x-ang (angle p0 x-int )  x-dst (distance x-int p0)
  66.                                           )
  67.                                           (if(equal x-ang -base-ang-90 1e-6) (setq x-dst (* x-dst -1.0) ) )
  68.                                           (list x-sp x-ep x-dst)
  69.                                        )
  70.                                        sp-ep-xp-lst
  71.                               )
  72.                               '(lambda (j k) (< (caddr j) (caddr k) ) )
  73.                      )
  74.    )
  75.  
  76.    (setq v-lst (append (mapcar 'car sorted-lst)   (reverse (mapcar 'cadr sorted-lst) ) ) )
  77.    (setq v-lst (append v-lst (list (car v-lst) ) ) )
  78.    (setvar "cecolor" "240")
  79.    (:LWP-EMK-V-LST v-lst)
  80. )
  81.  
  82.  
  83. (defun c:PPS () (C:PARALLEL-PLINES-SHAPE) )
  84.    

If PLINES are PARALLEL,
even if they were NOT DRAWN in SEQUENCE
and even if they have OPPOSITE DIRECTIONS,
this one seems to work well !

https://drive.google.com/file/d/19WI-iLc1_uHEaddjnA9NJpXMqYz-tbrk/view?usp=sharing

« Last Edit: July 02, 2023, 04:16:37 PM by domenicomaria »

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8723
  • AKA Daniel
Re: -={ Challenge }=- Enclose lines
« Reply #41 on: July 02, 2023, 06:06:26 PM »

kdub_nz

  • Mesozoic keyThumper
  • SuperMod
  • Water Moccasin
  • Posts: 2141
  • class keyThumper<T>:ILazy<T>
Re: -={ Challenge }=- Enclose lines
« Reply #42 on: July 02, 2023, 06:19:18 PM »
This may be an edge case :
What happens with a bow-tie shape drawn with non-sequential multi-directional parallel lines with a deep v notch.
A wavy edge where the distance between the ends exceeds twice the line spacing may also fail some algorithms.

Because of the stipulation for parallel lines my intuition would be to make a temporary ucs with X aligled with the collection elements.

Sort the collection bottom to top in Y direction.

Build a points collection by iteration up then down the collection

Build the closed boundary using the points

It would need a bit of translation between ucs <-> world but no complex math.

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

I live at UTC + 13.00

---
some people complain about loading the dishwasher.
Sometimes the question is more important than the answer.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8723
  • AKA Daniel
Re: -={ Challenge }=- Enclose lines
« Reply #43 on: July 02, 2023, 06:43:10 PM »
my last one fails if the lines are greater than 90.
maybe calculate an average

domenicomaria

  • Swamp Rat
  • Posts: 725
Re: -={ Challenge }=- Enclose lines
« Reply #44 on: July 03, 2023, 05:22:55 AM »
the first problem is: "what is the problem?"

is this maybe ?

"given a set of lines in the XY plane,
however oriented and of any length,
determine the smallest polygon
containing them"