Jump to content

Perpendicular Angles (Orthogonality test)


j2lstaples

Recommended Posts

Hello everyone, I've been coding a lot the past few days and I just wanted to share my code for those who may have some use for them, and also for me to keep track of my progress.

 

;********************************************************;
;; MA:perp-test - Test if two angles are perpendicular
;; Arguments:
;; - a (float): First angle in radians
;; - b (float): Second angle in radians
;; - tol (float): Tolerance value for comparison
;; Returns:
;; - test (bool): True if the angles are perpendicular within the given tolerance, False otherwise
;; Usage: (MA:perp-test a b tol)
(defun MA:perp-test (a b tol / test) 
  (if (and a b tol) 
    (if (< (abs (- (abs (cos a)) (abs (sin b)))) tol) 
      (setq test T)
      (setq test nil)
    )
  )
)

 

This is a very simple script for when you want to compare two angles, especially of blocks you're working with. This can be modified to where it has a default tolerance value for orthogonality, but that would be a good exercise for you guys to test for yourselves.

  • Like 4
Link to comment
Share on other sites

oh yeah, checking if one's cosinus is the other's sinus (absolute value).

I'll steal this one.

 

  • Like 1
Link to comment
Share on other sites

5 hours ago, Emmanuel Delay said:

oh yeah, checking if one's cosinus is the other's sinus (absolute value).

I'll steal this one.

 

it feels great when someone you used as a reference likes your code, lol. Cheers Emmanuel. 

Link to comment
Share on other sites

Congrats on your function - note that you can reduce it to the following to achieve the same result:

 

(defun MA:perp-test ( a b tol ) 
    (< (abs (- (abs (cos a)) (abs (sin b)))) tol)
)

 

Personally, the validity of the arguments should be the responsibility of the caller.

  • Like 1
Link to comment
Share on other sites

22 hours ago, Lee Mac said:

Congrats on your function - note that you can reduce it to the following to achieve the same result:

 

(defun MA:perp-test ( a b tol ) 
    (< (abs (- (abs (cos a)) (abs (sin b)))) tol)
)

 

Personally, the validity of the arguments should be the responsibility of the caller.

That looks insanely neater than what I did. I guess I wasn't thinking about refactoring the code. I need to work on recognizing things like this better.

Link to comment
Share on other sites

On 7/14/2023 at 8:22 PM, j2lstaples said:

That looks insanely neater than what I did. I guess I wasn't thinking about refactoring the code. I need to work on recognizing things like this better.

 

It's the same expression as is present in your code, you just don't need to explicitly assign a value to a boolean variable in order to return the boolean value.

Link to comment
Share on other sites

On 7/13/2023 at 2:26 PM, Lee Mac said:

Personally, the validity of the arguments should be the responsibility of the caller.

Agree 100%.

Link to comment
Share on other sites

Be careful of how "tol" is used in your program. Due to the slope of the sine function being close to 45 degrees near zero degrees compared to its slope near 90 degress (almost flat) you wil get more precision when angle "a"  i,s closer to 0 degrees than when it's near 90 degrees.  Your program should use sin(a) cos(b) for when a is < 45 and sin(b), cos(a) otherwise.

In each of the following examples, the angle difference between a and b  is 89.7 degrees. Note how the difference varies as a function of the angles used.

image.png.3b51688cd29a196a446f3b3b2a991f52.png

 

Edited by lrm
  • Like 1
Link to comment
Share on other sites

My solution:

start this lisp and click 3 times on the screen. Your clicks are assigned to points A, B and C. It will return TRUE only If AB is perpendicular to BC

(defun c:ra( / a b c c1 c2 h fuzz) ;right angle
  (setq a (getpoint)
	b (getpoint)
	c (getpoint)
	fuzz 1e-6)
  (equal (+ (* (setq c1 (distance a b)) c1) (* (setq c2 (distance b c)) c2)) (* (setq h (distance a c)) h) fuzz)
  )

 

Link to comment
Share on other sites

29 minutes ago, fuccaro said:

My solution:

start this lisp and click 3 times on the screen. Your clicks are assigned to points A, B and C. It will return TRUE only If AB is perpendicular to BC

(defun c:ra( / a b c c1 c2 h fuzz) ;right angle
  (setq a (getpoint)
	b (getpoint)
	c (getpoint)
	fuzz 1e-6)
  (equal (+ (* (setq c1 (distance a b)) c1) (* (setq c2 (distance b c)) c2)) (* (setq h (distance a c)) h) fuzz)
  )

 

 

Nice and easy to understand function.

You may want to consider using a simple square-function so you don't have to keep saving variables and makes the code more readable.

(defun sqr (x) (* x x))

(defun c:ra ( / a b c c1 c2 h fuzz) ;right angle
  (setq a (getpoint)
        b (getpoint)
        c (getpoint)
        fuzz 1e-6)
  (equal (+ (sqr (distance a b)) (sqr (distance b c))) (sqr (distance a c)) fuzz)
)

 

  • Agree 1
Link to comment
Share on other sites

@dexus:

Nice point! If writing speed is concerned, your code is better. If running speed is important, my solution will be (probable) faster with say 0.1% :)

 

@ Lee Mac:

Not just Pythagoras; even CADTutor could be proud for the lisps and all the other stuffs posted here in this forum!  :)

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