Jump to content

Recommended Posts

Posted

Dear All,

 

I would to to convert the some polylines to region, but one of them can't make it. After checking with is polyline, I found that the polyline cross itself. Is it possible to check this kind of polyline by lisp because it is very small in the corner? Thanks!

 

(defun c:test ()
(setq cset (ssget "_A" (list '(0 . "lwpolyline") (cons 410 (getvar "CTAB")) )))
(setq ctr 0 sobj 0 oobj 0)
(repeat (sslength cset)
 (setq item (ssname cset ctr))
 (if (= (vlax-property-available-p (vlax-ename->vla-object item ) "closed" T) T)
 (progn
  (setq lastitem (entlast))
  (command "region" item "")
     (setq drawitem (entlast))
  (if (not (equal lastitem drawitem))
     (progn
   (alert "object converted to region")
    (setq sobj (1+ sobj))
  )progn
  (progn 
  (alert "This object unable convert to region")
  (setq oobj (1+ oobj))
  )prgon
 )if 
 );progn 
 (alert "All object can't convert to region")
  );if
 (setq ctr (1+ ctr))
);repeat
)

 

cross.jpg

Posted

Try this ....

 

(defun c:test (/ spc selectionset)
;;; Tharwat 08. Dec. 2011 ;;;
 (vl-load-com)
 (cond ((not acdoc)
        (setq acdoc (vla-get-activedocument (vlax-get-acad-object)))
       )
 )
 (setq spc (if (> (vla-get-activespace acdoc) 0)
             (vla-get-modelspace acdoc)
             (vla-get-paperspace acdoc)
           )
 )
 (if (setq ss (ssget "_:L"
                     (list '(0 . "LWPOLYLINE")
                           '(-4 . "&=")
                           '(70 . 1)
                           (cons 410 (getvar "CTAB"))
                     )
              )
     )
   (progn
     (vlax-for obj
               (setq selectionset (vla-get-ActiveSelectionSet acdoc))
       (vlax-invoke spc 'addregion (list obj))
     )
     (vla-delete selectionset)
   )
   (princ)
 )
 (princ)
)

Posted

The following function will return points of self-intersection of an LWPolyline, else nil if the LWPolyline does not intersect itself.

[color=GREEN];; Get Self-Intersections  -  Lee Mac  -  2011  -  www.lee-mac.com[/color]
[color=GREEN];; Returns a list of self-intersections points of an LWPolyline.[/color]

([color=BLUE]defun[/color] _GetSelfIntersections ( obj [color=BLUE]/[/color] _LWVertices _Group3D )

   ([color=BLUE]defun[/color] _LWVertices ( l z )
       ([color=BLUE]if[/color] l ([color=BLUE]cons[/color] ([color=BLUE]list[/color] ([color=BLUE]car[/color] l) ([color=BLUE]cadr[/color] l) z) (_LWVertices ([color=BLUE]cddr[/color] l) z)))
   )
   ([color=BLUE]defun[/color] _Group3D ( l )
       ([color=BLUE]if[/color] l ([color=BLUE]cons[/color] ([color=BLUE]list[/color] ([color=BLUE]car[/color] l) ([color=BLUE]cadr[/color] l) ([color=BLUE]caddr[/color] l)) (_Group3D ([color=BLUE]cdddr[/color] l))))
   )
   (
       ([color=BLUE]lambda[/color] ( l )
           ([color=BLUE]vl-remove-if[/color]
               ([color=BLUE]function[/color]
                   ([color=BLUE]lambda[/color] ( a )
                       ([color=BLUE]vl-some[/color] ([color=BLUE]function[/color] ([color=BLUE]lambda[/color] ( b ) ([color=BLUE]equal[/color] a b 1e-)) l)
                   )
               )
               (_Group3D ([color=BLUE]vlax-invoke[/color] obj 'intersectwith obj [color=BLUE]acextendnone[/color]))
           )
       )
       (_LWVertices ([color=BLUE]vlax-get[/color] obj 'coordinates) ([color=BLUE]vlax-get[/color] obj 'elevation))
   )
)

 

The above will fail for points of self-intersection which lie directly on LWPolyline vertices.

Posted (edited)

This one will check also old 2dpolylines and 3dpolylines and append overlapping vertexes to list with intersecting points... Based on Lee's code and my contribution for vertexes lists of all *POLYLINE objects... Code updated to support vertexes that lie on polyline and intersect it by its position that have real, not fixed parameter.

 

[EDIT] : Also note that with this code you can check if pline has been correctly generated...

If there are no self-intersections and this code returns nil, then pline was correctly generated (if closed with "C" - close option)... If it reports points, pline is self-crossing or has duplicate vertexes on the same location... My next code - posted below in post #7 won't notify these verexes, just those that self-intersects or location of point that is intersection of plines segments self-crossings...

 

(defun _GetSelfIntersections ( obj / _Vertices _Group3D )

   (vl-load-com)

   (defun _Vertices ( pl / nvert pt ptlst n )
       (if (eq 1 (logand 1 (cdr (assoc 70 (entget (vlax-vla-object->ename pl))))))
           (setq nvert (fix (vlax-curve-getendparam pl)))
           (setq nvert (+ (fix (vlax-curve-getendparam pl)) 1))
       )
       (setq n 0.0)
       (repeat nvert
           (setq pt (vlax-curve-getpointatparam pl n))
           (setq ptlst (cons pt ptlst))
           (setq n (+ n 1.0))
       )
       (setq ptlst (reverse ptlst))
       ptlst
   )

   (defun _Group3D ( l )
       (if l (cons (list (car l) (cadr l) (caddr l)) (_Group3D (cdddr l))))
   )

   (defun _Duplicates ( l / lst lstrem )
       (setq lstrem (acet-list-remove-duplicates (setq lst l) 1e-6))
       (foreach el lstrem
           (if (not 
                   (vl-member-if 
                      '(lambda ( x )
                         (equal el x 1e-6)
                       )
                       (cdr
                           (vl-member-if
                              '(lambda ( x )
                                 (equal el x 1e-6)
                               )
                               lst
                           )
                       )
                   )
               )
               (setq lst (vl-remove-if
                            '(lambda ( x )
                               (equal el x 1e-6)
                             )
                             lst
                         )
               )
           )
       )
       lst
   )

   (append
       (
           (lambda ( l )
               (vl-remove-if
                   (function
                       (lambda ( a )
                           (vl-some (function (lambda ( b ) (equal a b 1e-)) l)
                       )
                   )
                   (_Group3D (vlax-invoke obj 'intersectwith obj acextendnone))
               )
           )
           (_Vertices obj)
       )
       (if (_Duplicates (_Vertices obj)) (acet-list-remove-duplicates (_Duplicates (_Vertices obj)) 1e-6))
   )
)

Test :

(_GetSelfIntersections (vlax-ename->vla-object (ssname (ssget "_+.:E:S:L" '((0 . "*POLYLINE"))) 0)))

M.R.

Edited by marko_ribar
code changed
Posted

Thanks for Tharwat , Lee Mac and Marko_ribar of your program code, I will test it.

Posted (edited)

If you want to do checks on POLYLINE only for region creation, you don't need to check for overlapping vertexes that are in pline creation array, only for those that intersects with other ones... In that case this will return list of points that intersect, and if it returns nil, region is possible to create...

 

[EDIT]: Code updated to include open/closed spline entities

 

(defun _GetSelfIntersections ( obj / _Vertices _Group3D )

   (vl-load-com)

   (defun _Vertices ( pl / nvert pt ptlst n )
       (if (eq 1 (logand 1 (cdr (assoc 70 (entget (vlax-vla-object->ename pl))))))
           (setq nvert (fix (vlax-curve-getendparam pl)))
           (setq nvert (+ (fix (vlax-curve-getendparam pl)) 1))
       )
       (setq n 0.0)
       (repeat nvert
           (setq pt (vlax-curve-getpointatparam pl n))
           (setq ptlst (cons pt ptlst))
           (setq n (+ n 1.0))
       )
       (setq ptlst (reverse ptlst))
       ([highlight]acet-list-remove-adjacent-dups[/highlight] ptlst)
   )

   (defun _Group3D ( l )
       (if l (cons (list (car l) (cadr l) (caddr l)) (_Group3D (cdddr l))))
   )

   (defun _Duplicates ( l / lst lstrem )
       (setq lstrem (acet-list-remove-duplicates (setq lst l) 1e-6))
       (foreach el lstrem
           (if (not 
                   (vl-member-if 
                      '(lambda ( x )
                         (equal el x 1e-6)
                       )
                       (cdr
                           (vl-member-if
                              '(lambda ( x )
                                 (equal el x 1e-6)
                               )
                               lst
                           )
                       )
                   )
               )
               (setq lst (vl-remove-if
                            '(lambda ( x )
                               (equal el x 1e-6)
                             )
                             lst
                         )
               )
           )
       )
       lst
   )

   (append
       (
           (lambda ( l )
               (vl-remove-if
                   (function
                       (lambda ( a )
                           (vl-some (function (lambda ( b ) (equal a b 1e-)) l)
                       )
                   )
                   (_Group3D (vlax-invoke obj 'intersectwith obj acextendnone))
               )
           )
           (_Vertices obj)
       )
       (if (_Duplicates (_Vertices obj)) (acet-list-remove-duplicates (_Duplicates (_Vertices obj)) 1e-6))
   )
)

Test :

(_GetSelfIntersections (vlax-ename->vla-object (car (entsel))))

M.R.

Edited by marko_ribar
Code changed
Posted
The following function will return points of self-intersection of an LWPolyline, else nil if the LWPolyline does not intersect itself.

[color=GREEN];; Get Self-Intersections  -  Lee Mac  -  2011  -  www.lee-mac.com[/color]
[color=GREEN];; Returns a list of self-intersections points of an LWPolyline.[/color]

([color=BLUE]defun[/color] _GetSelfIntersections ( obj [color=BLUE]/[/color] _LWVertices _Group3D )

   ([color=BLUE]defun[/color] _LWVertices ( l z )
       ([color=BLUE]if[/color] l ([color=BLUE]cons[/color] ([color=BLUE]list[/color] ([color=BLUE]car[/color] l) ([color=BLUE]cadr[/color] l) z) (_LWVertices ([color=BLUE]cddr[/color] l) z)))
   )
   ([color=BLUE]defun[/color] _Group3D ( l )
       ([color=BLUE]if[/color] l ([color=BLUE]cons[/color] ([color=BLUE]list[/color] ([color=BLUE]car[/color] l) ([color=BLUE]cadr[/color] l) ([color=BLUE]caddr[/color] l)) (_Group3D ([color=BLUE]cdddr[/color] l))))
   )
   (
       ([color=BLUE]lambda[/color] ( l )
           ([color=BLUE]vl-remove-if[/color]
               ([color=BLUE]function[/color]
                   ([color=BLUE]lambda[/color] ( a )
                       ([color=BLUE]vl-some[/color] ([color=BLUE]function[/color] ([color=BLUE]lambda[/color] ( b ) ([color=BLUE]equal[/color] a b 1e-)) l)
                   )
               )
               (_Group3D ([color=BLUE]vlax-invoke[/color] obj 'intersectwith obj [color=BLUE]acextendnone[/color]))
           )
       )
       (_LWVertices ([color=BLUE]vlax-get[/color] obj 'coordinates) ([color=BLUE]vlax-get[/color] obj 'elevation))
   )
)

 

The above will fail for points of self-intersection which lie directly on LWPolyline vertices.

 

Fantastic result .:shock:

 

Would you please re-write the code in another way without the use of lambda ( maybe repeat function works in this case ) if that not bothering ??

 

Thank you .

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...