Message 1 of 23
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
Hello,
How can I get bounding box of such rotated polyline in below posted snapshot to get the red polyline ?
Thanks.
Solved! Go to Solution.
Hello,
How can I get bounding box of such rotated polyline in below posted snapshot to get the red polyline ?
Thanks.
Solved! Go to Solution.
You can at least get very close with SmallestRectangle.lsp, >here<. It goes in 1° increments of rotation, but you can reduce that. But it won't give you precisely the outline you want unless the original's angles fall on one of the rotational increments.
EDIT: Never mind that -- see Message 5.
With OFFSETGAPTYPE set to zero, Offset the original [white] outboard by a large distance relative to the size of the undulations. [In this case, the Offset distance is the shorter dimension of the enclosing rectangle.] That outward Offset gives the red result, which kills all the undulations. Offset that back inward by the same distance to get the yellow result.
Thank you all for your kind and quick replies.
I was thinking the same to rotate the polyline from the longest segment and this will take more codes from me to get that working but this deserves a try.
Kent, your offset idea seems good but I got the curves offset as well even with system variable set to zero and not like your example in snapshot.
@J-Rocks wrote:
.... your offset idea seems good but I got the curves offset as well even with system variable set to zero ....
That must mean, I think, that your original has slightly rounded corners. Does it work if you do Fillet, Radius zero, Polyline option on it first? If the corners are rounded with a single arc segment at each, that would square them off.
An actual drawing file with some real-life examples may be helpful.
I was thinking of setting the UCS to align with the Polyline under the Object option, then getting its bounding box, but I find the bounding box is returned in WCS values, even when in a different UCS.
@J-Rocks hi,
Check this command PBND - works? 😀
thank you Lee Mac for this (LM:ListDupes) function.
Moshe
;; List Duplicates - Lee Mac
;; Returns a list of items appearing more than once in a supplied list
(defun LM:ListDupes ( l )
(if l
(if (member (car l) (cdr l))
(cons (car l) (LM:ListDupes (vl-remove (car l) (cdr l))))
(LM:ListDupes (vl-remove (car l) (cdr l)))
)
)
)
(vl-load-com)
;; draw the boundary of zigzag pline based on angles
(defun c:pbnd (/ vertices angle_list _dtr _wcs2ucs
ss points^ angles^ AcDbPline p0 p1)
; return pline points
(defun vertices (ent)
(vl-remove-if
'not
(mapcar
'(lambda (itm)
(if (= (car itm) 10)
(cdr itm)
)
); lambda
(entget ent)
); mapcar
); vl-remove-if
); vertices
(defun angle_list (lst / qang)
(defun qang (a)
(angtos
(if (and (>= a (* pi 0.5)) (< a (* pi 1.5)))
a
(+ a pi)
)
0 4)
); qang
(mapcar
(function
(lambda (t0 t1)
(atof (qang (angle t0 t1)))
)
)
lst (append (cdr lst) (list (car lst)))
)
); angle_list
; anonymous functions
(setq _dtr (lambda (a) (* (/ a 360.0) 2 pi)))
(setq _wcs2ucs (lambda (p) (trans p 0 1)))
; here start c:pbnd
(setvar "cmdecho" 0)
(command "._undo" "_begin")
(if (setq ss (ssget '((0 . "lwpolyline,polyline") (70 . 129))))
(progn
(foreach ename (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss)))
(setq points^ (vertices ename))
(setq angles^ (vl-sort (LM:ListDupes (angle_list points^)) '>))
(setq AcDbPline (vla-copy (vlax-ename->vla-object ename)))
(vla-rotate AcDbPline (vlax-3d-point '(0.0 0.0 0.0)) (- (* pi 2) (+ (_dtr (car angles^)) pi)))
(vla-getBoundingBox AcDbPline 'p0 'p1)
(vla-delete AcDbPline)
(vlax-release-object AcDbPline)
(command "._rectangle" (_wcs2ucs (vlax-safearray->list p0)) (_wcs2ucs (vlax-safearray->list p1)))
(vla-rotate (vlax-ename->vla-object (entlast)) (vlax-3d-point '(0.0 0.0 0.0)) (+ (_dtr (car angles^)) pi))
); foreach
); progn
); if
(command "._undo" "_end")
(setvar "cmdecho" 1)
(princ)
); c:pbnd
Sorry, I did not mean by curves rounded but sharp angles, the fillet did not solve / fix the polyline to work around it with offset as suggested earlier by you.
I did also thought about changing the UCS but that is what I have not worked with before.
Please find an example drawing in this post below.
Thank you.
Offsetting outward and then back inward, by the distance across the end of the overall shape, worked for me in your sample drawing. Even though in this particular configuration the outward Offset included a bump in the left end [green]:
still, Offsetting back inward removed that, and gave the red result.
ok fixed
;; Count Items - Lee Mac
;; Returns a list of dotted pairs detailing the number of
;; occurrences of each item in a supplied list.
(defun LM:CountItems ( l / c x )
(if (setq x (car l))
(progn
(setq c (length l)
l (vl-remove x (cdr l))
)
(cons (cons x (- c (length l))) (LM:CountItems l))
)
)
)
(vl-load-com)
;; draw the boundary of zigzag pline based on angles
(defun c:pbnd (/ vertices angle_list _dtr _wcs2ucs
ss points^ angles^ AcDbPline p0 p1)
; return pline points
(defun vertices (ent)
(vl-remove-if
'not
(mapcar
'(lambda (itm)
(if (= (car itm) 10)
(cdr itm)
)
); lambda
(entget ent)
); mapcar
); vl-remove-if
); vertices
(defun angle_list (lst / qang)
(defun qang (a)
(angtos
(if (and (>= a (* pi 0.5)) (< a (* pi 1.5)))
a
(+ a pi)
)
0 4)
); qang
(mapcar
(function
(lambda (t0 t1)
(atof (qang (angle t0 t1)))
)
)
lst (append (cdr lst) (list (car lst)))
)
); angle_list
; anonymous functions
(setq _dtr (lambda (a) (* (/ a 360.0) 2 pi)))
(setq _wcs2ucs (lambda (p) (trans p 0 1)))
; here start c:pbnd
(setvar "cmdecho" 0)
(command "._undo" "_begin")
(if (setq ss (ssget '((0 . "lwpolyline,polyline"))))
(progn
(foreach ename (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss)))
(setq points^ (vertices ename))
(setq angles^ (vl-sort (LM:CountItems (angle_list points^)) '(lambda (e0 e1) (> (cdr e0) (cdr e1)))))
(setq AcDbPline (vla-copy (vlax-ename->vla-object ename)))
(vla-rotate AcDbPline (vlax-3d-point '(0.0 0.0 0.0)) (- (* pi 2) (+ (_dtr (caar angles^)) pi)))
(vla-getBoundingBox AcDbPline 'p0 'p1)
(vla-delete AcDbPline)
(vlax-release-object AcDbPline)
(command "._rectangle" (_wcs2ucs (vlax-safearray->list p0)) (_wcs2ucs (vlax-safearray->list p1)))
(vla-rotate (vlax-ename->vla-object (entlast)) (vlax-3d-point '(0.0 0.0 0.0)) (+ (_dtr (caar angles^)) pi))
); foreach
); progn
); if
(command "._undo" "_end")
(setvar "cmdecho" 1)
(princ)
); c:pbnd
@Kent1Cooper wrote:
Offsetting outward and then back inward, by the distance across the end of the overall shape, worked for me in your sample drawing. ....
Which can be automated in a fairly short routine:
(vl-load-com)
(defun C:CURE (/ sel rec UR start temp) ; = Clean Up Rectangle Edges
(if
(and
(setq sel (entsel "\nRectangle to Clean Up: "))
(wcmatch (cdr (assoc 0 (entget (setq rec (car sel))))) "*POLY*")
); and
(progn ; then
(vla-getboundingbox (vlax-ename->vla-object rec) 'minpt 'maxpt)
(command "_.offset"
(apply 'min (cdr (reverse (mapcar '- (setq UR (vlax-safearray->list maxpt)) (vlax-safearray->list minpt)))))
;; lesser XY dimension of bounding box for Offset distance
(setq start (vlax-curve-getStartPoint rec))
(polar UR 0 1); guaranteed outboard
""
); command
(setq temp (entlast))
(command
"_.zoom" "_object" temp "" ; [pick point must be visible on-screen]
"_.offset" "" (vlax-curve-getStartPoint temp) start ""
"_.zoom" "_previous"
); command
(entdel temp)
(entdel rec) ;;;;; OR NOT, if you want it to remain
); progn
); if
(prin1)
); defun
[It doesn't actually use the dimension across the end of the shape after all, but an easier-to-determine dimension that has the same effect.]
It could use some of the usual enhancements. It doesn't check that the Polyline is of the right kind of configuration, or closed, or on an unlocked Layer, etc. -- it's up to you to choose appropriate objects. [Some of those things can be checked easily enough, but the configuration type would be a real challenge, if even possible.]
hey,
if that routine has to deal with singular convex pline only as shown at first picture, then that code may be of help.
(defun c:pline_bounding_box (/ pline_ename vertex_list leftmost_vertex topmost_vertex rightmost_vertex bottommost_vertex bounding_box_pline)
(setq pline_ename (car (entsel))
vertex_list (mapcar 'cdr (vl-remove-if-not '(lambda (group) (= 10 (car group))) (entget pline_ename)))
leftmost_vertex (car (vl-sort vertex_list '(lambda (vertex_1 vertex_2) (< (car vertex_1) (car vertex_2)))))
topmost_vertex (car (vl-sort vertex_list '(lambda (vertex_1 vertex_2) (> (cadr vertex_1) (cadr vertex_2)))))
rightmost_vertex (car (vl-sort vertex_list '(lambda (vertex_1 vertex_2) (> (car vertex_1) (car vertex_2)))))
bottommost_vertex (car (vl-sort vertex_list '(lambda (vertex_1 vertex_2) (< (cadr vertex_1) (cadr vertex_2)))))
)
(vla-put-color
(setq bounding_box_pline (vla-addlightweightpolyline (vla-get-block (vla-get-activelayout (vla-get-activedocument (vlax-get-acad-object))))
(vlax-safearray-fill
(vlax-make-safearray vlax-vbdouble '(0 . 7))
(apply 'append (list leftmost_vertex topmost_vertex rightmost_vertex bottommost_vertex))
)
)
)
1
)
(vla-put-closed bounding_box_pline :vlax-true)
(vlax-release-object bounding_box_pline)
)
Just thought that I'd try this routine for fun.
Thanks for your efforts.
See below for what I got from using c:pline_bounding_box.
~thanks
))) well it wasn't obviously pretended to replace 'getboundingbox))) for orthogonally placed bitten rectangles