Jump to content

Recommended Posts

Posted

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

Posted

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.

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

 

Posted

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

Posted

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

 

 

Posted

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

 

Posted

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

Posted

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

 

Posted (edited)

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
Posted

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

Posted

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.

Posted
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 "\">%"
                        )

 

Posted

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

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

Posted
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!

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