EQUAL SPACE ARRAY

Discussion in 'AutoCAD' started by jbrazier, Feb 9, 2005.

  1. jbrazier

    jbrazier Guest

    I have a LISP routine written several years ago. The idea is to pick a distance and enter a maximum spacing. The result arrays the entity with spaces not to exceed the maximum spacing. The problem we are seeing is if the distance is exactly divisable by the spacing the routine adds one additional space. Example: dist=30'-0 max. spa. = 3'-0 should give 10 spaces at 3'-0 but the program gives me 11 spaces at 2'-8 3/4. I'm guessing that this has something to do with rounding the numbers. The routine is included here, any help would be appreciated (I have 4 of these - up, down, right, left). I know that someone probably has one routine that does this in any direction, not just orthogonal, if you want to send me that I would appreciate it.


    (defun c:arrup(/ dist1 xx num1 disp1 num2 obj dist2 dist3)
    (setq DIST1 (getdist "Length of Array: "))
    (setq XX (getstring "Maximum Spacing: "))
    (setq NUM1 (distof XX 4))
    (setq DISP1 (/ DIST1 NUM1))
    (setq NUM2 (- DISP1 (fix DISP1)))
    (if (> 0 NUM)(setq NUM2 (+ (fix DISP1) 1)))
    (prompt "Objects to Array: ")(terpri)
    (setq OBJ (ssget))(terpri)
    (setq DIST2 (/ DIST1 NUM2))
    (command "ARRAY" OBJ "" "R" NUM2 "" DIST2)
    (princ)
    )
    Thanks,
    Jon Brazier
     
    jbrazier, Feb 9, 2005
    #1
  2. jbrazier

    T.Willey Guest

    See how this works. If you don't have this one:
    (defun DTR (a) ;Degrees to radians conversion
    (* pi (/ a 180.0)))
    You will need it.

    Tim

    (defun c:Copy@Dist (/ Amount Dist LgDist Ang ss tmpPt1 tmpPt2 tmpNum)

    (if
    (and
    (setq Dist (getdist "\n Enter total distance: "))
    (setq LgDist (getdist "\n Enter greatest distance between objects: "))
    (setq Ang (getangle "\n Enter angle: "))
    (setq ss (ssget))
    )
    (progn
    (setq tmpPt1 (polar '(0 0 0) Ang 0.01))
    (setq tmpPt2 (polar '(0 0 0) (+ (DTR 90) Ang) 0.01))
    (command "_.ucs" "_3" '(0 0 0) tmpPt1 tmpPt2)
    (setq tmpNum (/ Dist LgDist))
    (setq Amount (atoi (rtos tmpNum 2 0)))
    (while (> (* Amount LgDist) Dist)
    (setq Amount (1- Amount))
    )
    (setq tmpNum (/ Dist Amount))
    (command "_.array" ss "" "_r" "1" Amount tmpNum)
    (command "_.ucs" "_p")
    )
    )
    )
     
    T.Willey, Feb 9, 2005
    #2
  3. jbrazier

    jbrazier Guest

    Tim - I really appreciate yor help with this but there is a problem. The atoi is rounding either up or down. When it rounds up, everything works fine. But when it rounds down it creates one less space and the spacing exceeds the maximum input spacing. Is there a way to "force" the rounding up all of the time? I've attached the latest version of the routine that I've modified so that the angle is calculated in the routine rather than input. Any help would be great...

    (defun c:arrayjb (/ PNT1 PNT2 Amount Dist LgDist Ang ss tmpPt1 tmpPt2 tmpNum)
    (if
    (and
    (setq PNT1 (getpoint "\n Start of Array: "))
    (setq PNT2 (getpoint pnt1 "\n End of Array: "))
    (setq Dist (distance pnt1 pnt2))
    (setq Ang (rtd 3.017))
    (setq Ang (angle pnt1 pnt2))
    (setq LgDist (getdist "\n Maximum Spacing: "))
    (setq ss (ssget))
    )
    (progn
    (setq tmpPt1 (polar '(0 0 0) Ang 0.01))
    (setq tmpPt2 (polar '(0 0 0) (+ (DTR 90) Ang) 0.01))
    (command "_.ucs" "_3" '(0 0 0) tmpPt1 tmpPt2)
    (setq tmpNum (/ Dist LgDist))
    (setq Amount (atoi (rtos tmpNum 2 0)))
    (while (> (* Amount LgDist) Dist)
    (setq Amount (1- Amount))
    )
    (setq tmpNum (/ Dist Amount))
    (command "ucsicon" "on")
    (command "_.array" ss "" "_r" "1" Amount tmpNum)
    (command "_.ucs" "_p")
    (command "ucsicon" "off")
    )
    )
    )


    Jon
     
    jbrazier, Feb 23, 2005
    #3
  4. jbrazier

    T.Willey Guest

    After you get "tmpNum" set it again like
    (setq tmpNum (+ 0.49999 tmpNum))
    This should work as way to make sure that the number will get rounded up all the time.

    Tim
     
    T.Willey, Feb 23, 2005
    #4
  5. You could also do this:

    (setq Amount (atoi (rtos tmpNum 2))) +
    (if (> (rem Dist LgDist) 0) (setq Amount (1+ Amount)))

    That's the approach I use in a routine that calculates the number of risers
    in a stair, dividing the floor-to-floor height by the maximum riser height.
    Since it's a maximum height, it also needs to be rounded up to the next
    higher integer number of steps if it doesn't divide exactly.
    --
    Kent Cooper


    ......
     
    Kent Cooper, AIA, Feb 23, 2005
    #5
  6. jbrazier

    T.Willey Guest

    Good idea Kent. I like it.

    Tim
     
    T.Willey, Feb 23, 2005
    #6
  7. jbrazier

    T.Willey Guest

    Or you could use
    (setq Amount (fix tmpNum))
    It will round down up to 15 decimal places.

    From the command line in Acad.
    Command: (fix 2.999999999999999)
    2

    Command: (fix 2.9999999999999999)
    3

    Tim
     
    T.Willey, Feb 23, 2005
    #7
  8. jbrazier

    T.Willey Guest

    Oops, you wanted to round up right. So then use
    (setq Amount (1+ (fix tmpNum)))

    Tim
     
    T.Willey, Feb 23, 2005
    #8
  9. But I think you want to test whether it divides exactly first (my check for
    remainder) -- if it does, you don't want to increase it by one.
     
    Kent Cooper, AIA, Feb 23, 2005
    #9
  10. jbrazier

    T.Willey Guest

    True. After I posted, I was thinking that your way was most likely better. Seems more fool proof.

    Tim
     
    T.Willey, Feb 23, 2005
    #10
Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.