Jump to content
nimble87

Round up to multiple of 5

Recommended Posts

nimble87

Hi All,

 

I have a portion of code that provides a segment length, is there any way to round up the output length to the nearest 5? Is it possible using RTOS or will I need to include a separate roundup function? eg: Road Crossing actual length = 16.4m, i'd like it to output 20m.

 

(defun c:FX-ING ( / tr pref)
(setq tr "0CHK X-ING TRENCH ")
(setq pref (getstring CR "\nTRENCH DETAIL: "))
(command "_.Layer" "_Make" (strcat tr pref) "_Color" "210" "" "_TR" "30" "" "LType" "dashed" "" (COMMAND)) 
(setq prev (getvar "clayer"))
(setvar "clayer" (strcat tr pref))
(command ".pline")
(while (= (logand (getvar "cmdactive") 1) 1)(command pause))
(setq sg (ssget "L"))
(C:midl)
(C:SEGX-ING)
)

;; ROAD CROSSING Segment length

(defun c:SEGX-ING (/ ls4 tl4 n ent itm obj l)
	(setq ls4 (ssget "P" (list (cons 8 (strcat tr pref))))
        tl4 0
        n (1- (sslength ls4)))
  (while (>= n 0)
    (setq ent (entget (setq itm (ssname ls4 n)))
          obj (cdr (assoc 0 ent))
          l (cond
              ((= obj "LINE")
                (distance (cdr (assoc 10 ent))(cdr (assoc 11 ent))))
              ((= obj "ARC")
                (* (cdr (assoc 40 ent))
                   (if (minusp (setq l (- (cdr (assoc 51 ent))
                                          (cdr (assoc 50 ent)))))
                     (+ pi pi l) l)))
              ((or (= obj "CIRCLE")(= obj "SPLINE")(= obj "POLYLINE")
                   (= obj "LWPOLYLINE")(= obj "ELLIPSE"))
                (command "_.area" "_o" itm)
                (getvar "perimeter"))
              (T 0))
          tl4 (+ tl4 l)
          n (1- n)))
		  		  
  (alert (strcat "Last segment length of road crossing is " (rtos tl4)))
)

Thanks in advance

Share this post


Link to post
Share on other sites
BIGAL

That is a big roundup value would have thought a 1m would be more appropriate for Civil works. 

 

Lee-mac.com has a rounding function.

Share this post


Link to post
Share on other sites
nimble87
1 minute ago, BIGAL said:

That is a big roundup value would have thought a 1m would be more appropriate for Civil works. 

 

Lee-mac.com has a rounding function.

 

It is a large roundup, more so just for rough bill of quantities.

 

I've been trying to incorporate Lee Macs rounding function but had no luck getting it to work, found another thread where he assisted in rounding to the nearest 100, but couldn't get that to work either.

 

I've been trying the below, i'm just unsure where and how to include it in the code.

 

Thanks

 

(defun LM:roundm ( n m )
    (* m (atoi (rtos (/ n (float m)) 2 0)))
)

 

Share this post


Link to post
Share on other sites
nimble87

I think I've found the problem. It uses a version of Midlen, which Lee-Mac created some years ago (very handy thanks Lee), attached for reference.

 

This routine adds the polyline length to the midpoint of the polyline as a field. I may be wrong, but I'm thinking I need to apply the 5m roundup to the field formatting.

 

Would love some input if Midlen can be rounded up to the nearest 5m?

 

Thanks.

MidLenV1-0.lsp

Share this post


Link to post
Share on other sites
BIGAL

The code rounds up and rounds down using 1 would be best. 

 

Bit of a guess (fix (* 10.0 (lm:roundm (/ 16.4 10.0 ) 1))) you need to try

 

 

Share this post


Link to post
Share on other sites
lido

Try this:

(defun mult5 (nr / a b c s)
  (setq   a (itoa (fix (+ nr 0.5)))
          b (strlen a)
          c (atoi (substr a b))
          s (substr a 1 (1- b))
  )
  (atoi
    (cond 
      ( (vl-position c (quote (0 1 2)))
        (strcat s "0")
      )
      ( (vl-position c (quote (3 4 5 6 7)))
        (strcat s "5")
      )
      ( T
        (strcat (itoa (1+ (atoi s))) "0"))
    )
  )
) ;;mult5

 

Share this post


Link to post
Share on other sites
dlanorh

Try this oldish function by Doug Broad

 

(defun db:round ( val acc ) (* (abs acc) (fix (/ ((if (minusp val) - +) val (* (abs acc) 0.5)) (abs acc)))))

Example of use (db:round 123.456 5.0) "val" is the number you want to round "acc" is the accuracy. If accuracy is an integer it returns an integer if its a real it returns a real

Share this post


Link to post
Share on other sites
Lee Mac

My LM:roundm function may be used in the following way:

_$ (LM:roundm 12 5)
10
_$ (LM:roundm 13 5)
15

You can implement the same logic in field formatting using the ROUND formula function, by changing this:

                        (strcat
                            "%<\\AcObjProp Object(%<\\_ObjId " (LM:objectid (vlax-ename->vla-object ent)) ">%)."
                            (cond
                                (   (= "CIRCLE" typ) "Circumference")
                                (   (= "ARC"    typ) "ArcLength")
                                (   "Length"   )
                            )
                            " \\f \"" fmt "\">%"
                        )

To:

                        (strcat
                            "%<\\AcExpr (ROUND(%<\\AcObjProp Object(%<\\_ObjId " (LM:objectid (vlax-ename->vla-object ent)) ">%)."
                            (cond
                                (   (= "CIRCLE" typ) "Circumference")
                                (   (= "ARC"    typ) "ArcLength")
                                (   "Length"   )
                            )
                            ">%/5.0)*5.0) \\f \"" fmt "\">%"
                        )

 

  • Like 1

Share this post


Link to post
Share on other sites
nimble87
3 hours ago, Lee Mac said:

My LM:roundm function may be used in the following way:


_$ (LM:roundm 12 5)
10
_$ (LM:roundm 13 5)
15

You can implement the same logic in field formatting using the ROUND formula function, by changing this:


                        (strcat
                            "%<\\AcObjProp Object(%<\\_ObjId " (LM:objectid (vlax-ename->vla-object ent)) ">%)."
                            (cond
                                (   (= "CIRCLE" typ) "Circumference")
                                (   (= "ARC"    typ) "ArcLength")
                                (   "Length"   )
                            )
                            " \\f \"" fmt "\">%"
                        )

To:


                        (strcat
                            "%<\\AcExpr (ROUND(%<\\AcObjProp Object(%<\\_ObjId " (LM:objectid (vlax-ename->vla-object ent)) ">%)."
                            (cond
                                (   (= "CIRCLE" typ) "Circumference")
                                (   (= "ARC"    typ) "ArcLength")
                                (   "Length"   )
                            )
                            ">%/5.0)*5.0) \\f \"" fmt "\">%"
                        )

 

Thanks to all for their input, the help is greatly appreciated.

 

Lee, your solution worked without hitch, thank you. Visually the length is rounded to the nearest multiple of 5, but the dialog box still provides the exact measurement, which is perfect for our application.

 

Thanks again.

 

Share this post


Link to post
Share on other sites
nimble87

I've done a bit more testing and it appears the above solution works by rounding to the nearest 5, is it possible to tweak it to round up to the next 5?

 

Rounding down will cause a few issues with quantities.

 

** edit: also trying to incorporate the copy to clipboard code from here--> https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/need-lisp-surface-angle-with-4-points/td-p/4595101/page/2 

 

I'd like to copy the rounded up to 5 value to clipboard to allow pasting to excel after each command, possible? I can get them to work separately, but can't get copy to clipboard to use the rounded midlen value.

 

Thanks.

Edited by nimble87

Share this post


Link to post
Share on other sites
BIGAL

About to say the rounding down is a problem you would need a If answer < original add 2 * rounding.  Still think 5 is way to much a different way may be to look at decimal if > 0.1 then add 1 to integer value. This way set a minimum value like 0.1 that can be dropped.

 

I have personally tape measured meters of kerbing as there was a dispute about lengths. You don't want to over pay the contractor. 5's will add very quick extra in their pocket. 

  • Like 1

Share this post


Link to post
Share on other sites
nimble87
2 minutes ago, BIGAL said:

About to say the rounding down is a problem you would need a If answer < original add 2 * rounding.  Still think 5 is way to much a different way may be to look at decimal if > 0.1 then add 1 to integer value. This way set a minimum value like 0.1 that can be dropped.

 

I have personally tape measured meters of kerbing as there was a dispute about lengths. You don't want to over pay the contractor. 5's will add very quick extra in their pocket. 

 

Thanks BigAl, i'll have a play with your suggestion and see if I can make it work.

 

I agree 5m round up does sound like a lot. I work in elec utility design, the 5m round up covers the conduit bends and also the distance to travel from buried depth to surface as we're only measuring the 2D distance. also leaves a little in the kitty to avoid contractors variations during construction due to being short on material.

Share this post


Link to post
Share on other sites
BIGAL

Its probably easier divide the integer length by 10 then look at 1st decimal then can do a cond adding correct amount. 16.4 = 16 = 1.6 if .6 add .4 * 10.

Share this post


Link to post
Share on other sites
Lee Mac
20 hours ago, nimble87 said:

I've done a bit more testing and it appears the above solution works by rounding to the nearest 5, is it possible to tweak it to round up to the next 5?

 

You can round up using the TRUNC function, e.g.:

                        (strcat
                            "%<\\AcExpr (TRUNC((%<\\AcObjProp Object(%<\\_ObjId " (LM:objectid (vlax-ename->vla-object ent)) ">%)."
                            (cond
                                (   (= "CIRCLE" typ) "Circumference")
                                (   (= "ARC"    typ) "ArcLength")
                                (   "Length"   )
                            )
                            ">%+4.9999999)/5.0)*5.0) \\f \"" fmt "\">%"
                        )

 

Share this post


Link to post
Share on other sites
nimble87

TRUNC is the winner, thanks again Lee and to Bigal, Lido and Dlanorh for your assistance as well.

Share this post


Link to post
Share on other sites
Lee Mac
21 hours ago, nimble87 said:

TRUNC is the winner, thanks again Lee and to Bigal, Lido and Dlanorh for your assistance as well.

 

You're most welcome - note that there is more to the solution than replacing ROUND with TRUNC however, as these two functions operate in very different ways.

Share this post


Link to post
Share on other sites
nimble87
2 hours ago, Lee Mac said:

 

You're most welcome - note that there is more to the solution than replacing ROUND with TRUNC however, as these two functions operate in very different ways.

I always separate your answers and try to manipulate them to see how they work. Thanks again, did some good testing with the program with other users, works perfect.

 

I'm sure you'll see me back when I run into the next wall!

Share this post


Link to post
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
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

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