Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Rounding polyline radii to nearest integer

17 REPLIES 17
Reply
Message 1 of 18
jpCADconsulting
851 Views, 17 Replies

Rounding polyline radii to nearest integer

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

17 REPLIES 17
Message 2 of 18
devitg
in reply to: jpCADconsulting

@jpCADconsulting , please upload your sample.dwg

Message 3 of 18
ronjonp
in reply to: jpCADconsulting

@jpCADconsulting 

Plenty to read here on bulges.

Message 4 of 18
jpCADconsulting
in reply to: devitg

I don't have one but I can make an example I suppose. Any polyline with multiple curved segments would do.
Message 5 of 18
Sea-Haven
in reply to: jpCADconsulting

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

  

Message 6 of 18
john.uhden
in reply to: ronjonp

@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

Message 7 of 18
Kent1Cooper
in reply to: john.uhden


@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
Message 8 of 18
Sea-Haven
in reply to: jpCADconsulting

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

 

 

Message 9 of 18
3wood
in reply to: jpCADconsulting

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

 

Message 10 of 18
john.uhden
in reply to: 3wood

@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

Message 11 of 18
Kent1Cooper
in reply to: john.uhden

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
Message 12 of 18
ronjonp
in reply to: Kent1Cooper


@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 )?  😂

Message 13 of 18
hak_vz
in reply to: jpCADconsulting

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.
Message 14 of 18

it wasn't @ronjonp actually 😁

Message 15 of 18

@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

Message 16 of 18

@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

Message 17 of 18
isaacrXZ7AD
in reply to: john.uhden

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.

Message 18 of 18
Sea-Haven
in reply to: jpCADconsulting

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

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

AutoCAD Inside the Factory


Autodesk Design & Make Report