Pick two Points to get Downslope in percents, prompted in CommandLine

Pick two Points to get Downslope in percents, prompted in CommandLine

Anonymous
Not applicable
1,057 Views
25 Replies
Message 1 of 26

Pick two Points to get Downslope in percents, prompted in CommandLine

Anonymous
Not applicable

Hello,

I wrote a lisp which calculates the downslope in percents and returns this downslope's value to CommandLine.

Here it is:

 

; DSE = DownSlopE
; DOWNSLOPE
(defun c:DOWNSLOPE
 (/ ptL1 ptL2 Len_X Len_Y Len Ang DownslopePercents)
 (setvar "cmdecho" 0)
 (setq ptL1 (getpoint "\nSpecify First Point to calculate Downslope: "))
 (setq ptL2 (getpoint "\nSpecify Second Point to calculate Downslope: "))
 (setq XptL1 (car ptL1))
 (setq YptL1 (cadr ptL1))
 (setq XptL2 (car ptL2))
 (setq YptL2 (cadr ptL2))
 (setq Len_X (- XptL2 XptL1))
 (setq Len_Y (- YptL2 YptL1))
; What if XptL1 = XptL2 --> Len_X=0?
; (setq Len
;  (sqrt
;   (+ (* Len_X Len_X) (* Len_Y Len_Y))
;  ); sqrt
; ); Len
; (setq Ang (atan Len_Y Len_X))
;Len_Y/Len_X = DownslopePercents/100
 (setq DownslopePercents (* (/ Len_Y Len_X) 100))
 (setq DownslopePercents2string (rtos DownslopePercents 2 3)); Mode=2=Engineering, Precision=3
 (princ "\nDownslope = ")
 DownslopePercents2string
 (princ "%.")
; (princ "\nAngle = ")
; Length
; (princ " <Here should be current angle units. Should I type 'getvar AUNITS?'>.")
; (princ "\nLength = ")
; Length
; (princ ".")
);defun

 

Some parts of this lisp I ignore with ';', because they will be investigated in other cases - on ground of this lisp I want to write lisps which return to CommandLine Distance and Angle between two picked Points. And I can't do them using 'getdist' and 'getangle', because the user would type his own value for Distance and Angle.

 

So returning to the main topic: This lisp doesn't work properly.

In the CommandLine it returns:

 

Command: DOWNSLOPE
Specify First Point to calculate Downslope:
Specify Second Point to calculate Downslope:
Downslope = %."%."

 

Could you please tell me why it doesn't work in way which I suspected?

0 Likes
1,058 Views
25 Replies
Replies (25)
Message 21 of 26

hmsilva
Mentor
Mentor
Glad you have it sorted!

Henrique

EESignature

0 Likes
Message 22 of 26

Anonymous
Not applicable

So I conclude in one 'if' statemetn I can write only one thing to do as 'then' and only one thing to do as 'else'?

I am right?

0 Likes
Message 23 of 26

hmsilva
Mentor
Mentor

@Anonymous wrote:

So I conclude in one 'if' statemetn I can write only one thing to do as 'then' and only one thing to do as 'else'?

I am right?


No, you can write one statement.
e.g.
(if (xxxxx)
 (progn
  (do this)
(do n times as needed) (do that) );end progn from test not nil (progn (do this)
(do n times as needed) (do that) );end progn from test nil ); end if

 >> progn <<

 

Henrique

 

EESignature

0 Likes
Message 24 of 26

Anonymous
Not applicable

Thank you very much!

That is the next, new interesting thing which I just have learned.

 

I noticed 'progn' on the beginning if this lisp

 

(if (and (setq ptL1 (getpoint "\nSpecify First Point to calculate Downslope: "))
	   (setq ptL2 (getpoint "\nSpecify Second Point to calculate Downslope: "))
	   (not (equal ptL1 ptL2 1e-8))
      )
    (progn
      (setq XptL1 (car ptL1))
      (setq YptL1 (cadr ptL1))
      (setq XptL2 (car ptL2))
      (setq YptL2 (cadr ptL2))
      (setq Len_X (- XptL2 XptL1))
      (setq Len_Y (- YptL2 YptL1))
      ; What if XptL1 = XptL2 --> Len_X=0?

 but I thought it is optional thing and I could not write it.

 

But now I know I was wrong.

 

http://www.afralisp.net/autolisp/tutorials/cond-vs-if.php

http://www.afralisp.net/autolisp/tutorials/conditionals.php

 

0 Likes
Message 25 of 26

hmsilva
Mentor
Mentor
You're welcome, Damian!

Henrique

EESignature

0 Likes
Message 26 of 26

Anonymous
Not applicable

I modified this lisp and now it is working properly.

So, here is the next version of this lisp:

 

; 2 -INFO ABOUT LINE BETWEEN TWO points
(defun c:23456
 (/ angstring angun auni Ang
  DownslopePercents DownslopePercents2string
  Len Len_X Len_Y
  ptL1 ptL2
  XptL1 XptL2 YptL1 YptL2
 )
  (if (and (setq ptL1 (getpoint "\nSpecify First Point to calculate Downslope: "))
	   (setq ptL2 (getpoint "\nSpecify Second Point to calculate Downslope: "))
	   (not (equal ptL1 ptL2 1e-8))
      )
    (progn
      (setq XptL1 (car ptL1))
      (setq YptL1 (cadr ptL1))
      (setq XptL2 (car ptL2))
      (setq YptL2 (cadr ptL2))
      (setq Len_X (- XptL2 XptL1))
      (setq Len_Y (- YptL2 YptL1))
      ; What if XptL1 = XptL2 --> Len_X=0?
	  
      ;; (setq len (distance ptL1 ptL2))
      (setq Len
	     (sqrt
	       (+ (* Len_X Len_X) (* Len_Y Len_Y))
	     ); sqrt
      ); Len
	  
      (setq angun (getvar 'aunits))
      (cond ((or (= angun 0)
		 (= angun 1)
	     )
	     (setq auni "Degrees")
	    )
	    ((= angun 2)
	     (setq auni "Gradians")
	    )
	    ((= angun 3)
	     (setq auni "Radians")
	    )
	    ((= angun 4)
	     (setq auni "Surveyor")
	    )
      )
	  
     ; (setq Ang (atan Len_Y Len_X)) ; if you pick two Points which create Vertical line, the Length_X =0 and in the CommandLine there is ""error: Divide by zero"
	(if (/= Len_X 0)
	  
	  (progn
        (setq Ang (atan Len_Y Len_X))
	    (setq DownslopePercents (* (/ Len_Y Len_X) 100)) ; DownslopePercents = tan(Ang) * 100% = (Len_Y / Len_X) * 100% ; It is another way to calculate DownslopePercents
		(setq DownslopePercents2string (rtos DownslopePercents 2 3))
	  )
	  
      (if (> YptL2 YptL1)
		
		(progn
         (setq Ang (/ PI 2))       ; I gave PI/2 and 3PI/2 instead of 90 and 270, because Ang is an angle in Radians
		 (setq DownslopePercents "plus infinity") ; I used strings of "plus infinity" and "minus infinity" instead of numbers 100 and -100. Earlier I thought that Downslope changes from 0% to 100% (and of course I was totally wrong) so that's why there were values of 100 and -100.
		 (setq DownslopePercents2string DownslopePercents)
        ) 
		
		(progn
		 (setq Ang (* 3 (/ PI 2)))
		 (setq DownslopePercents "minus infinity")
		 (setq DownslopePercents2string DownslopePercents)
	    )
      )
	)  

	(setq angstring 
	  (strcat
	     (if (minusp Ang)
		 (angtos (- (* 2 PI) (abs Ang) ) angun 3) ; I gave 2PI-Ang instead of (-Ang) in order to have a value ;such like it would be in Properties Palette
		 (angtos (abs Ang) angun 3)
		 )
	  )
	)
		 
      ;Len_Y/Len_X = DownslopePercents/100
;	        (if (zerop Len_X)
;        (setq DownslopePercents 100)
;        (setq DownslopePercents (* (/ Len_Y Len_X) 100))
;      )
	  
;	  		(setq DownslopePercents2string (rtos DownslopePercents 2 3)) ; This expresiion I copied into three separate cases above in 'if' 
      
      ; Mode=2= Decimal, Precision=3
      (princ (strcat "\nDownslope = " DownslopePercents2string  " %.")) ; I gave space bar here to not have prompts "minus infinity%"
	  (princ (strcat "\nLength_X = " (rtos Len_X 2 3) "."))
	  (princ (strcat "\nLength_Y = " (rtos Len_Y 2 3) "."))
      (princ (strcat "\nAngle = " angstring " " auni "."))
      (princ (strcat "\nLength = " (rtos Len 2 3) "."))
	  (princ "\nPress [F2] to open and close results in CommandLine.")
    )
	
    (prompt "\nYou did select the same point!!!")
  )
(princ);; exits quietly
);defun	

 

I have learned so much only modifing this one lisp.

I am really proud of create it, because it seams to be small, but it is very useful!

I checked the Downslope of the road on bridge which I design.

I edited this lisp so many times... But still I could not say that it is the final version.

0 Likes