Rounding polyline radii to nearest integer

jpCADconsulting
Advocate

Rounding polyline radii to nearest integer

jpCADconsulting
Advocate
Advocate

Hi folks,  been a while!

 

I have a client that wants to select a polyline (or multiple polylines) containing multiple curved segments and round all the radii of those segment to the nearest whole unit.

I've been looking around and have not found anything that addresses this specifically.  Any help would be greatly appreciated.

Thanks as always!

-JP

0 Likes
Reply
964 Views
17 Replies
Replies (17)

devitg
Advisor
Advisor

@jpCADconsulting , please upload your sample.dwg

0 Likes

ronjonp
Advisor
Advisor

@jpCADconsulting 

Plenty to read here on bulges.

jpCADconsulting
Advocate
Advocate
I don't have one but I can make an example I suppose. Any polyline with multiple curved segments would do.
0 Likes

Sea-Haven
Mentor
Mentor

This possibly contains a method but is line arc line. Using it redraws the arc so could set the radius.

 

(defun c:DyF (/ *error* _pnt AT:GetSel vl ov ent plst elst gr sp)
  ;; Dynamic Fillet
  ;; Alan J. Thompson, 03.07.11 / 03.09.11

  (vl-load-com)

  (defun *error* (msg)
    (redraw)
    (and vl (mapcar (function setvar) vl ov))
    (and elst (mapcar (function redraw) elst '(4 4)))
    (if (and msg (not (wcmatch (strcase msg) "*BREAK*,*CANCEL*,*QUIT*,")))
      (princ (strcat "\nError: " msg))
    )
  )

  (defun _pnt (p) (trans (list (car p) (cadr p)) 0 1))

  (defun AT:GetSel (meth msg fnc / ent)
    ;; meth - selection method (entsel, nentsel, nentselp)
    ;; msg - message to display (nil for default)
    ;; fnc - optional function to apply to selected object
    ;; Ex: (AT:GetSel entsel "\nSelect arc: " (lambda (x) (eq (cdr (assoc 0 (entget (car x)))) "ARC")))
    ;; Alan J. Thompson, 05.25.10
    (setvar 'ERRNO 0)
    (while
      (progn (setq ent (meth (cond (msg)
                                   ("\nSelect object: ")
                             )
                       )
             )
             (cond ((eq (getvar 'ERRNO) 7) (princ "\nMissed, try again."))
                   ((eq (type (car ent)) 'ENAME)
                    (if (and fnc (not (fnc ent)))
                      (princ "\nInvalid object!")
                    )
                   )
             )
      )
    )
    ent
  )

  (if (setq ent
             (car
               (AT:GetSel
                 entsel
                 "\nSelect arc: "
                 (lambda (x)
                   (if (eq "ARC" (cdr (assoc 0 (entget (car x)))))
                     (vl-every (function (lambda (p / ss)
                                           (if (setq ss (ssget "_C" p p '((0 . "LINE"))))
                                             (setq elst (cons (ssname ss 0) elst))
                                           )
                                         )
                               )
                               (setq plst (list (_pnt (vlax-curve-getStartPoint (car x)))
                                                (_pnt (vlax-curve-getEndPoint (car x)))
                                          )
                               )
                     )
                   )
                 )
               )
             )
      )
    (progn
      (setq ov (mapcar (function getvar) (setq vl '("CMDECHO" "FILLETRAD"))))
      (while
        (progn
          (setq gr (grread T 15 0))
          (cond
            ((eq 5 (car gr))
             (redraw)
             (grdraw (setq sp (trans (vlax-curve-getStartPoint ent) 0 1)) (cadr gr) 1 -1)
             (princ
               (strcat "\rFillet radius: "
                       (rtos (setvar 'FILLETRAD (distance sp (cadr gr))))
                       "      "
               )
             )
             (if (vl-cmdf "_.fillet" (list (car elst) (car plst)) (list (cadr elst) (cadr plst)))
               (progn (entdel ent) (setq ent (entlast)))
               T
             )
            )
          )
        )
      )
    )
  )
  (*error* nil)
  (princ)
)

  

0 Likes

john.uhden
Mentor
Mentor

@jpCADconsulting ,

Ditto what @ronjonp stated.

When you change the radius and retain the two segment endpoints, you have to change the radius point and delta, but the chord remains the same.  The bulge must change as well, which is the key to your computation (for a bulge /= 0):

(setq delta (* 4 (atan (abs bulge)))
          r (abs (/ chord 2 (sin (/ delta 2))))

)

You'll have to rearrange the formulas to compute the bulge from the radius.

Just be careful to keep the sign of the bulge the same.  That is all you are changing per segment.

John F. Uhden

0 Likes

Kent1Cooper
Consultant
Consultant

@john.uhden wrote:

....  When you change the radius and retain the two segment endpoints....


I certainly would not assume that part.  @jpCADconsulting , is that what you want?  Or do you want the adjacent line segments [I'm assuming the arc segments are flanked by line segments on both sides, but that's another question] to stay where they are path-wise but have their endpoints adjusted to suit the new radius, tangent to the adjusted arc segment, just as if you had used a FILLET command on them?  A kind of extreme case to illustrate the difference:

Kent1Cooper_0-1677550301762.png

[And it also raises the question of whether you're always dealing with arc segments that are tangent to the adjacent line segments, in Fillet-wise arrangement -- there are certainly lots of other possibilities.]

The difficulty is that AutoCAD does not store the radius of a Polyline arc segment as a piece of entity data.  It stores a bulge factor, and the vertex locations at either end can be a very challenging computation if the adjacent line segments are not perpendicular.  If you're talking about only rounded-corner 90° changes in direction, maybe not so difficult.

Kent Cooper, AIA

Sea-Haven
Mentor
Mentor

Fillet will change a pline radius but you need to work out the sequence is it, "segment arc segment" before applying. But like Kent this is a true tangent solution. Manually Fillet, pick the mid pt of the adjacent pline "line" segments.

 

Need to work out how read pline segment order say line arc line arc line line arc line.

 

 

((-1 . <Entity name: 659d51c0>) (0 . "LWPOLYLINE") (5 . "1DDD") (330 . <Entity name: 3d667520>) (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "0") (370 . -1) (100 . "AcDbPolyline") 
(90 . 6) ; 6 vertices
 (70 . 0)
 (43 . 0.0) 
 (38 . 0.0) 
 (39 . 0.0)
 (10 -290.0 126.0) ; 1st point
 (40 . 0.0) 
 (41 . 0.0) 
 (42 . 0.0) ; no bulge
 (91 . 0)
 (10 -256.667268683904 192.279044924515) ; 2nd point
 (40 . 0.0) 
 (41 . 0.0)
 (42 . -0.508204106875609) ; bulge value
 (91 . 0) 
 (10 -159.189832703418 208.454364385618) ; 3rd point
 (40 . 0.0)
 (41 . 0.0)
 (42 . 0.0)
 (91 . 0)
 (10 -147.001442474056 196.494429027982) 
 (40 . 0.0) 
 (41 . 0.0) 
 (42 . 0.431880954930485) ; bulge
 (91 . 0) 
 (10 -120.814586750271 197.527534827221) ; 5th point
 (40 . 0.0) 
 (41 . 0.0) 
 (42 . 0.0) 
 (91 . 0) 
 (10 -24.402170920898 308.345167019768) ; 6th point
 (40 . 0.0) 
 (41 . 0.0) 
 (42 . 0.0)
 (91 . 0) 
 (210 0.0 0.0 1.0)) 

 

 

0 Likes

3wood
Advisor
Advisor

In the scenario below it won't have a rounded radius number arc, if the line segments beside the arc are parallel.

3wood_0-1677562066615.png

 

0 Likes

john.uhden
Mentor
Mentor

@3wood 

I doubt that @jpCADconsulting was expecting to have the new radius be tangent at both ends.  I'm pretty sure that he meant exactly what he indicated... just to change the radius of the bulged segments:

johnuhden_0-1677621918142.png

I've been working on the code with help from Lee Mac.  The procedure is to solve for the bulge given the chord and desired radius.

@jpCADconsulting ,

Do you want the new radius applied to all bulged segments, or to operate separately on each segment?

What about existing straight segments?

 

John F. Uhden

0 Likes

Kent1Cooper
Consultant
Consultant

Those may not be exactly but certainly could be the same radius:

Kent1Cooper_0-1677638502984.png

What would be your criteria for making one as opposed to the other?

 

@jpCADconsulting , we really need to know which variety of adjustment of arc segments you're after, or there could be a lot of time wasted pursuing the wrong goal.

Kent Cooper, AIA
0 Likes

ronjonp
Advisor
Advisor

@jpCADconsulting , we really need to know which variety of adjustment of arc segments you're after, or there could be a lot of time wasted pursuing the wrong goal.


How much of the consulting fee do you get for your time ( wasted or not )?  😂

0 Likes

hak_vz
Advisor
Advisor

As @ronjonp stated in previous post we need a lot more data to jump into finding solution.

Generally, problem is solvable in case when you have combination line-arc-line polyline segments. One would extract all arc segments and adjoin line segments and redefine radii by finding new tangents points for nearest integer radii (circle TTR). this would redefine arc segment start and end point, bulging will stay unchanged. In case of arc-arc polyline segment I don't find correct solution. But lets wait for @jpCADconsulting  and his client. 

Miljenko Hatlak

EESignature

Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
0 Likes

komondormrex
Advisor
Advisor

it wasn't @ronjonp actually 😁

0 Likes

john.uhden
Mentor
Mentor

@jpCADconsulting ,

Out of curiosity I've been working on this challenge because I don't think I have ever had to compute the bulge from a radius, knowing only the chord distance as well.  I've got the trigonometry figured out, but only if retaining the vertex locations, which will remove any tangency with the previous and next segments.  Is that what you were hoping for, or must the vertices be moved to retain tangency?

John F. Uhden

0 Likes

john.uhden
Mentor
Mentor

@jpCADconsulting ,

Did you ever find a solution?

I have had the math all figured out for quite a while. Almost forgot about entirely.  Just need a little time to put it together, that is if you still need it.

While I'm at it (if I am) do you want to select polylines one at a time, or by multiple selection, or by layer?

BTW, my thanks to @hak_vz and @pendean for finding the thread for me.  I am historically challenged except that the Battle of Hastings was in 1066.

John F. Uhden

0 Likes

isaacrXZ7AD
Observer
Observer

So, is there any update on this? I need to change the radii of arcs in polylines while holding field located points... I am just creating a fit polyline, exploding it and labeling the radii's and a decurved polyline under it to snap as I redraw it utilizing snaps, whole numbers and creating new tangencies or compound curves... having a button to do the math would be nice.

0 Likes

Sea-Haven
Mentor
Mentor

Maybe this is useful.

(defun c:DyF (/ *error* _pnt AT:GetSel vl ov ent plst elst gr sp)
  ;; Dynamic Fillet
  ;; Alan J. Thompson, 03.07.11 / 03.09.11

  (vl-load-com)

  (defun *error* (msg)
    (redraw)
    (and vl (mapcar (function setvar) vl ov))
    (and elst (mapcar (function redraw) elst '(4 4)))
    (if (and msg (not (wcmatch (strcase msg) "*BREAK*,*CANCEL*,*QUIT*,")))
      (princ (strcat "\nError: " msg))
    )
  )

  (defun _pnt (p) (trans (list (car p) (cadr p)) 0 1))

  (defun AT:GetSel (meth msg fnc / ent)
    ;; meth - selection method (entsel, nentsel, nentselp)
    ;; msg - message to display (nil for default)
    ;; fnc - optional function to apply to selected object
    ;; Ex: (AT:GetSel entsel "\nSelect arc: " (lambda (x) (eq (cdr (assoc 0 (entget (car x)))) "ARC")))
    ;; Alan J. Thompson, 05.25.10
    (setvar 'ERRNO 0)
    (while
      (progn (setq ent (meth (cond (msg)
                                   ("\nSelect object: ")
                             )
                       )
             )
             (cond ((eq (getvar 'ERRNO) 7) (princ "\nMissed, try again."))
                   ((eq (type (car ent)) 'ENAME)
                    (if (and fnc (not (fnc ent)))
                      (princ "\nInvalid object!")
                    )
                   )
             )
      )
    )
    ent
  )

  (if (setq ent
             (car
               (AT:GetSel
                 entsel
                 "\nSelect arc: "
                 (lambda (x)
                   (if (eq "ARC" (cdr (assoc 0 (entget (car x)))))
                     (vl-every (function (lambda (p / ss)
                                           (if (setq ss (ssget "_C" p p '((0 . "LINE"))))
                                             (setq elst (cons (ssname ss 0) elst))
                                           )
                                         )
                               )
                               (setq plst (list (_pnt (vlax-curve-getStartPoint (car x)))
                                                (_pnt (vlax-curve-getEndPoint (car x)))
                                          )
                               )
                     )
                   )
                 )
               )
             )
      )
    (progn
      (setq ov (mapcar (function getvar) (setq vl '("CMDECHO" "FILLETRAD"))))
      (while
        (progn
          (setq gr (grread T 15 0))
          (cond
            ((eq 5 (car gr))
             (redraw)
             (grdraw (setq sp (trans (vlax-curve-getStartPoint ent) 0 1)) (cadr gr) 1 -1)
             (princ
               (strcat "\rFillet radius: "
                       (rtos (setvar 'FILLETRAD (distance sp (cadr gr))))
                       "      "
               )
             )
             (if (vl-cmdf "_.fillet" (list (car elst) (car plst)) (list (cadr elst) (cadr plst)))
               (progn (entdel ent) (setq ent (entlast)))
               T
             )
            )
          )
        )
      )
    )
  )
  (*error* nil)
  (princ)
)