Jump to content

surround points with boundary or polyline


Tomislav

Recommended Posts

Hello.

Does anyone has a lisp similar to @Lee Mac Outline objects lisp but that does it with points. It's too complicated for me to write it so maybe someone has it.

So the purpose would be to select some points and the lisp would draw a closed polyline surrounding those points by connecting "outside" points.

I've attached dwg so you can see what I mean.

Drawing2.dwg

Link to comment
Share on other sites

2 hours ago, Tomislav said:

Hello.

Does anyone has a lisp similar to @Lee Mac Outline objects lisp but that does it with points. It's too complicated for me to write it so maybe someone has it.

So the purpose would be to select some points and the lisp would draw a closed polyline surrounding those points by connecting "outside" points.

I've attached dwg so you can see what I mean.

Drawing2.dwg 109.64 kB · 1 download

 

Try this. It's not foolproof, as points have no boundary. It calculates the convex hull for the points, finds the minimum distance between the closest two points and uses this as the maximum distance to search for points from the convex hull.

 

(defun gc:clockwise-p ( p1 p2 p3 ) (< (sin (- (angle p1 p3) (angle p1 p2))) -1e-14))

;;Based on Convex Hull by Lee Mac
(defun rh:gsch (pt_lst / pt_0 c_lst rtn)
  (cond ( (< (length pt_lst) 4) (setq rtn pt_lst))
        (
          (setq pt_0 (car (vl-sort pt_lst '(lambda (x y) (cond ( (= (cadr x) (cadr y)) (< (car x) (car y))) ( (< (cadr x) (cadr y)))))))
                pt_lst (vl-sort pt_lst '(lambda ( a b / c d ) (if (equal (setq c (angle pt_0 a)) (setq d (angle pt_0 b)) 1e-8) (< (distance pt_0 a) (distance pt_0 b)) (< c d))))
                c_lst (list (caddr pt_lst) (cadr pt_lst) (car pt_lst))
          );end_setq
          (foreach pt (cdddr pt_lst)
            (setq c_lst (cons pt c_lst))
            (while (and (caddr c_lst) (gc:clockwise-p (caddr c_lst) (cadr c_lst) pt))
              (setq c_lst (cons pt (cddr c_lst)))
            );end_while
          );end_foreach
          (setq rtn c_lst)
        );end_sub_cond (>= pt_lst 4)
  );end_cond
);end_defun

(defun rh:mind (l / m p1 p2) (setq m 1.0e99) (while (> (length l) 1) (setq p1 (car l) l (cdr l)) (foreach p l (if (< (setq p2 (distance p1 p)) m) (setq m p2)))) m)

(defun c:test ( / maxd cnt lst ss ch_lst nent plst obj)
  (cond ( (setq ss (ssget '((0 . "POINT"))))
          (repeat (setq cnt (sslength ss))
            (setq lst (cons (reverse (cdr (reverse (cdr (assoc 10 (entget (ssname ss (setq cnt (1- cnt))))))))) lst))
          )
          (setq ch_lst (rh:gsch lst))
          (setq nent (entmakex (append (list '(000 . "LWPOLYLINE") '(100 . "AcDbEntity") '(100 . "AcDbPolyline") (cons 90 (length ch_lst)) '(70 . 1))
                                        (mapcar '(lambda ( x ) (cons 10 x)) (reverse ch_lst))
                                )
                     )
                maxd (fix (rh:mind lst))
          );end_setq
          
          (foreach pt lst
            (cond ( (vlax-curve-getparamatpoint nent pt) (setq plst (cons (list (vlax-curve-getdistatpoint nent pt) pt) plst)))
                  ( (< (distance pt (setq cpt (vlax-curve-getclosestpointto nent pt))) maxd) (setq plst (cons (list (vlax-curve-getdistatpoint nent cpt) pt) plst)))
            );end_cond
          );end_foreach
          (setq plst (apply 'append (mapcar 'cdr (vl-sort plst '(lambda (x y) (< (car x) (car y))))))
                obj (vlax-ename->vla-object nent)
          )
          (vlax-put obj 'coordinates (apply 'append plst))
        )
  )
  (princ)
)

 

Link to comment
Share on other sites

great stuff dlanorh, it more or less works but only on smaller groups, on longer distances(like points along road) in curves it tends to cut the curve and also when the points are more irregular and it skips some points without connecting them...see attached dwg

Drawing1.dwg

Link to comment
Share on other sites

As I said, It's not foolproof as It relies of a convex hull calculation (this is what causes it to cut curves). If the distance of a "boundary" point from the convex hull is greater than the minimum distance between any two popints selected, it will not adjust. This is to avoid the boundary line adjusting to points that should be inside the boundary. 

Link to comment
Share on other sites

Auto boundary has been asked a number of times and the convex hull is a good approximation, there is LINEworkShrinkwrap if you have CIV3d. Simplest is to shrink wrap the triangles. Note though you have to delete long tri's or inside triangles on curves. In other software have delete long triangles.

 

There is a commercial product that an takes objects and find a boundary just google not hard to find.

 

Link to comment
Share on other sites

Thank you all for responses, I've also tried in friends Civil that LINEworkShrinkwrap and it's not working..must keep on looking

Link to comment
Share on other sites

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...