Jump to content

Looping in Lisp...


brawleyman

Recommended Posts

I have this routine that allows me to measure distances between devices in X and Y coordinates and adds a drop and rise to the total. It is also set up to be able to keep track of the number of devices I select while within the routine. My problem is that when I push enter to get the distance, it ends the command. I want to be able to push enter or right click and it give me the distance to the first object, but then I can start picking my points to the next device and then right click and get the distance to that device from the last one and so on. After the last device on a circuit, I want to be able to right click twice, once to get the distance to that device from the previous one and again to give me the total distance of the whole circuit. What do I need to include to be able to do this? Thanks!

 

 
(defun c:dis ()
   (setvar "CMDECHO" 0)
   (setq num 1) ;set starting segment value
   (setq drop (getint "\nEnter drop distance to add to total length: ")) ;get drop distance
   (setq drop (* 12 drop)) ;convert drop to feet
   (setq pt (getpoint "\nSelect path to next device:")) ;get starting point
   (setq x1 (car pt)) ;extract X value
   (setq y1 (cadr pt)) ;extract Y value
   (setq lensum 0)
   (while 
     (setq pt (getpoint pt)) ;get next point
     (setq x2 (car pt)) ;extract 2nd point X value
     (setq y2 (cadr pt)) ;extract 2nd point Y value
     (setq xdiff (abs (- x1 x2)))          ;calculate X plane distance
     (setq ydiff (abs (- y1 y2)))          ;calculate Y plane distance
     (setq len (+ xdiff ydiff))                 ;add X and Y to get total segment length
     (setq lensum (+ len lensum drop))               ;add drop distance and variable to display running sum of segment lengths
   )
     (setq dist (strcat "------------------------: DEVICE " (itoa num) " DISTANCE: " (rtos (/ lensum 12) 2 0)))  ;create output text string
     (princ "\n")(princ dist)                            ;print the output string
     (setq x1 x2)(setq y1 y2) ;set next segment X,Y starting point to end of last segment
     (setq num (1+ num)) ;incriment segment number value
(princ)
)

Link to comment
Share on other sites

Haven't really got much time, but this may help you along;

 


(defun c:dis (/ drop pt1 lensum num pt2 len)
   (setq drop (getreal "\nEnter drop distance to add to total length: "))
   (setq drop (* 12 drop))
   (setq pt1 (getpoint "\nSelect First Point: "))
   (setq num 0)
   (while
   (setq pt2 (getpoint "\nSelect Second Point: "))
      (setq len (distance pt1 pt2))
      (setq lensum (+ len drop))
      (princ (strcat "\nDevice " (itoa num) " Distance: " (rtos (/ lensum 12) 2 0)))
      (setq num (1+ num))
   ) ;_  end while
   (princ)
) ;_  end defun

 

Just an edit of your original post

Link to comment
Share on other sites

Thanks LeeMac, but that doesn't quite fulfill what I am trying to accomplish. Sometimes, when I am measuring the path from one device to the next, there are several bends in the conduit, so I cannot just go straight from one device to the next. I have to select several points along the path before I can get the total distance to the one device.

 

Basically, I want the routine to gather the info, but only display it when I press enter or right-click, but then continue selecting my points to the next device, then right-click again to get the distance to that device and so on. I know there has to be a way to do it, but I haven't been able to find a straight answer to it cruising around the net. I want the right-click to display the result without ending the routine.

Link to comment
Share on other sites

I have removed the "drop", as I don't fully understand it, but it could be easily modified.

 

But this concept:

 

(defun c:dis (/ pt1 num pt2 len)
   (while
   (setq pt1 (getpoint "\nSelect First Point: "))
      (setq num 0)
      (setq len 0)
      (while
          (setq pt2 (getpoint "\nSelect Second Point: "))
         (setq len (+ (distance pt1 pt2) len))
         (setq pt1 pt2)
      ) ;_  end while
      (princ (strcat "\nDevice " (itoa num) " Distance: " (rtos len)))
      (setq num (1+ num))
      (princ)
   ) ;_  end while
) ;_  end defun

Link to comment
Share on other sites

That is closer to what I need. The "drop" that I have included is the drop and rise distance because the conduit runs in the ceiling, but then has to drop to the devices throughout the building, so I usually add 10 feet per device, 5ft. down and 5ft. back up to the conduit. Also, I am extracting the X and Y coordinates because the conduit only runs in those directions, so that is why that is in there.

 

Okay, after playing with the code a little bit, I have it almost exactly the way I want it. Now, all I need it to do is after I right click to get the distance for the last device, I want it to automatically pick up from the last spot I selected without me having to click the last point again.

 

 
(defun c:dis ()
(setvar "CMDECHO" 0)
(setq num 1) ;set starting segment value
(setq drop (getint "\nEnter drop distance to add to total length:"))
(setq drop (* 12 drop))
(setq lensum 0)
(princ "\nSelect path to next device:")
 (while
   (setq pt (getpoint))
   (setq x1 (car pt)) ;extract X value
   (setq y1 (cadr pt)) ;extract Y value
     (while
       (setq pt (getpoint pt))
       (setq x2 (car pt))
       (setq y2 (cadr pt))
       (setq xdiff (abs (- x1 x2)))
       (setq ydiff (abs (- y1 y2)))
       (setq len (+ xdiff ydiff))
       (setq lensum (+ len drop))
     )
   (setq dist (strcat "---> DEVICE " (itoa num) " DISTANCE: " (rtos (/ lensum 12) 2 0)))
   (princ "\n")(princ dist)
   (setq num (1+ num))
   (setq x1 x2)(setq y1 y2)
 )
(princ setq total (strcat "---> TOTAL LENGTH: " (rtos dist 4 0)))
(setq x1 x2)(setq y1 y2)
(princ)
)

 

I am almost there, just this little last push and it will be perfect. I have it set up so that at the end, it is supposed to show the total of the previous setq "dist" values, but I just cannot get it to work properly. I get...

 

"; error: bad argument type: numberp: "---> DEVICE 2 DISTANCE: 21"

 

What am I missing?

Link to comment
Share on other sites

A way to loop

 

(setq x 1)

(while (= x 1)

 

(if (= x1 x2) (exit) )

pick same point twice and test if yes then exit, yes exit does exactly that or x =2 will stop also.

code here

) end while

 

 

the other thing I use is pick object but to exit pick nothing and test for object = nil

Link to comment
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
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...