Author Topic: Mirrored Angles  (Read 2976 times)

0 Members and 1 Guest are viewing this topic.

cmwade77

  • Swamp Rat
  • Posts: 1443
Mirrored Angles
« on: February 25, 2022, 03:18:40 PM »
So let's say I have an angle of 30 degrees, I would like to calculate all 4 mirrored angles for 30 degrees. So for 30 that would be:
30
150
210
330

Of course if I was always dealing with the same angle, that would be fine, but the 30 degrees could be any autocad angle.

I am having a moment of not being able to think of how to calculate all four angles, as for example the initial angle could be 210, but I would still want the other 3 angles as specified.

Anyone have any ideas?

kpblc

  • Bull Frog
  • Posts: 396
Re: Mirrored Angles
« Reply #1 on: February 25, 2022, 03:27:03 PM »
Stupid solution
Code - Auto/Visual Lisp: [Select]
  1. (defun all-angles (step / res)
  2.   (setq res (list step))
  3.   (while (< (car res) 360)
  4.     (setq res (cons (+ (car res) step) res))
  5.   ) ;_ end of while
  6.   (reverse res)
  7. ) ;_ end of defun
call:
Code - Auto/Visual Lisp: [Select]
  1. (all-angles 15)
Sorry for my English.

cmwade77

  • Swamp Rat
  • Posts: 1443
Re: Mirrored Angles
« Reply #2 on: February 25, 2022, 03:30:23 PM »
Stupid solution
Code - Auto/Visual Lisp: [Select]
  1. (defun all-angles (step / res)
  2.   (setq res (list step))
  3.   (while (< (car res) 360)
  4.     (setq res (cons (+ (car res) step) res))
  5.   ) ;_ end of while
  6.   (reverse res)
  7. ) ;_ end of defun
call:
Code - Auto/Visual Lisp: [Select]
  1. (all-angles 15)
Nope, with an input of 330, I get 330 and 660.

kpblc

  • Bull Frog
  • Posts: 396
Re: Mirrored Angles
« Reply #3 on: February 25, 2022, 03:35:43 PM »
One more:
Code - Auto/Visual Lisp: [Select]
  1. (defun all-angles (step / res temp)
  2.   (setq res (list step))
  3.   (while (< (setq temp (+ step (car res))) 360)
  4.     (setq res (cons temp res))
  5.   ) ;_ end of while
  6.   (reverse res)
  7. ) ;_ end of defun
Sorry for my English.

cmwade77

  • Swamp Rat
  • Posts: 1443
Re: Mirrored Angles
« Reply #4 on: February 25, 2022, 03:42:16 PM »
One more:
Code - Auto/Visual Lisp: [Select]
  1. (defun all-angles (step / res temp)
  2.   (setq res (list step))
  3.   (while (< (setq temp (+ step (car res))) 360)
  4.     (setq res (cons temp res))
  5.   ) ;_ end of while
  6.   (reverse res)
  7. ) ;_ end of defun
Nope, now I get 348.22 or something like that with an input of 330

ribarm

  • Gator
  • Posts: 3309
  • Marko Ribar, architect
Re: Mirrored Angles
« Reply #5 on: February 25, 2022, 03:52:52 PM »
Code - Auto/Visual Lisp: [Select]
  1. (defun f ( a / a+ l )
  2.  
  3.   (defun a+ ( a )
  4.     (if (misusp a)
  5.       (rem a (* 2 pi))
  6.     )
  7.   )
  8.  
  9.   (if (> (sin a) 0.0)
  10.     (setq l (list a (+ a pi)))
  11.     (setq l (list a (- a pi)))
  12.   )
  13.   (setq l (append l (mapcar '- l)))
  14.   (vl-sort (mapcar 'a+ l) '<)
  15. )
  16.  

Code: [Select]
(cvunit (f (cvunit 30 "degree" "radian")) "radian" "degree")
(cvunit (f (cvunit 210 "degree" "radian")) "radian" "degree")
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

cmwade77

  • Swamp Rat
  • Posts: 1443
Re: Mirrored Angles
« Reply #6 on: February 25, 2022, 04:56:14 PM »
Code - Auto/Visual Lisp: [Select]
  1. (defun f ( a / a+ l )
  2.  
  3.   (defun a+ ( a )
  4.     (if (misusp a)
  5.       (rem a (* 2 pi))
  6.     )
  7.   )
  8.  
  9.   (if (> (sin a) 0.0)
  10.     (setq l (list a (+ a pi)))
  11.     (setq l (list a (- a pi)))
  12.   )
  13.   (setq l (append l (mapcar '- l)))
  14.   (vl-sort (mapcar 'a+ l) '<)
  15. )
  16.  

Code: [Select]
(cvunit (f (cvunit 30 "degree" "radian")) "radian" "degree")
(cvunit (f (cvunit 210 "degree" "radian")) "radian" "degree")

I get an error of no function misusp.

kirby

  • Newt
  • Posts: 132
Re: Mirrored Angles
« Reply #7 on: February 25, 2022, 05:33:07 PM »
Might do the trick.  Unit circle approach.  Friday afternoon fun, not rigourously tested..

Command: (circlequads 30 1)
  (30.0 150.0 210.0 330.0)
Command: (circlequads 15 1)
  (15.0 165.0 195.0 345.0)
Command: (circlequads 330 1)
  (30.0 150.0 210.0 330.0)

Code - Auto/Visual Lisp: [Select]
  1. (defun CircleQuads (MyAngle UnitCode / hpi 2pi 34pi BaseAngle OutList)
  2. ; Get complimentary 'mirror' angles in each quadrant of a circle
  3. ; KJM - Feb 2022
  4. ; Input:
  5. ;       MyAngle - (real) angle in degrees or radians
  6. ;       UnitCode - (integer) code.  0 or nil = angles in radians, 1 = angles in degrees
  7. ; Returns:
  8. ;       list of angles in each quadrant of circle
  9. ; Uses custom functions:
  10. ;       dtr
  11. ;       rtd
  12. ;       FixAng
  13.  
  14. ; defaults
  15. (if (not UnitCode) (setq UnitCode 0))
  16. (if (not hpi) (setq hpi (* 0.5 pi)))
  17. (if (not 2pi) (setq 2pi (* 2.0 pi)))
  18. (if (not 34pi) (setq 34pi (* 1.5 pi)))
  19.  
  20. ; Convert to radians
  21. (if (eq UnitCode 1)
  22.         (setq MyAngle (dtr MyAngle))
  23. )      
  24.  
  25. ; Force angle between 0 and 2pi (eliminated negatives and over-runs)
  26. (setq MyAngle (fixang MyAngle))
  27.  
  28. ; Find quadrant of provided angle
  29.         ((and (>= MyAngle 0.0) (< MyAngle hpi)) (setq BaseAngle MyAngle))
  30.         ((and (>= MyAngle hpi) (< MyAngle pi)) (setq BaseAngle (- pi MyAngle)))
  31.         ((and (>= MyAngle pi) (< MyAngle 34pi)) (setq BaseAngle (+ pi MyAngle)))       
  32.         ((and (>= MyAngle 34pi) (< MyAngle 2pi)) (setq BaseAngle (- 2pi MyAngle)))     
  33. ) ; close cond
  34.  
  35. ; Make list of complimentary angles
  36. (if (eq UnitCode 0)
  37.   (progn
  38.         ; return list of angles in radians
  39.         (setq OutList (list BaseAngle (- pi BaseAngle) (+ pi BaseAngle) (- 2pi BaseAngle)))
  40.   )
  41.   (progn
  42.         ; return list of angles in degrees
  43.         (setq BaseAngle (rtd BaseAngle))
  44.         (setq OutList (list BaseAngle (- 180.0 BaseAngle) (+ 180.0 BaseAngle) (- 360.0 BaseAngle)))
  45.   )    
  46. )
  47.  
  48. OutList
  49. )
  50.  
  51.  
  52. (defun RTD (A)
  53. ; Radians to Degrees
  54.         (* 180.0 (/ A pi))
  55. )
  56.  
  57. (defun DTR (A)
  58. ; Degrees to Radians
  59.         (* pi (/ A 180.0))
  60. )
  61.  
  62.  
  63.  
  64.  
  65. (defun Fixang (Ang / K)
  66. ; Correct angle to lie within 0 and 2*pi
  67. ; KJM - Jan 1988, Mod KJM March 2019
  68. ; Note: now equivalent to 'Unitcircle' function
  69.  
  70. (if (eq 2pi nil) (setq 2pi (* 2.0 pi)))
  71.  
  72. (if (or (equal Ang 0.0 0.0001) (equal Ang 2pi 0.0001))
  73.         (setq Ang 0.0)
  74. )
  75.  
  76. (setq K 1)
  77.         (cond
  78.                 ((>= Ang 2pi)
  79.                         (setq Ang (- Ang 2pi))
  80.                 )
  81.                 ((< Ang 0.0)
  82.                         (setq Ang (+ Ang 2pi))
  83.                 )
  84.         )
  85.         (if (and (>= Ang 0.0) (< Ang 2pi))
  86.                 (setq K nil)
  87.         )
  88. )
  89. Ang     ; return fixed angle
  90. )

cmwade77

  • Swamp Rat
  • Posts: 1443
Re: Mirrored Angles
« Reply #8 on: February 25, 2022, 05:59:49 PM »
Might do the trick.  Unit circle approach.  Friday afternoon fun, not rigourously tested..

Command: (circlequads 30 1)
  (30.0 150.0 210.0 330.0)
Command: (circlequads 15 1)
  (15.0 165.0 195.0 345.0)
Command: (circlequads 330 1)
  (30.0 150.0 210.0 330.0)

Code - Auto/Visual Lisp: [Select]
  1. (defun CircleQuads (MyAngle UnitCode / hpi 2pi 34pi BaseAngle OutList)
  2. ; Get complimentary 'mirror' angles in each quadrant of a circle
  3. ; KJM - Feb 2022
  4. ; Input:
  5. ;       MyAngle - (real) angle in degrees or radians
  6. ;       UnitCode - (integer) code.  0 or nil = angles in radians, 1 = angles in degrees
  7. ; Returns:
  8. ;       list of angles in each quadrant of circle
  9. ; Uses custom functions:
  10. ;       dtr
  11. ;       rtd
  12. ;       FixAng
  13.  
  14. ; defaults
  15. (if (not UnitCode) (setq UnitCode 0))
  16. (if (not hpi) (setq hpi (* 0.5 pi)))
  17. (if (not 2pi) (setq 2pi (* 2.0 pi)))
  18. (if (not 34pi) (setq 34pi (* 1.5 pi)))
  19.  
  20. ; Convert to radians
  21. (if (eq UnitCode 1)
  22.         (setq MyAngle (dtr MyAngle))
  23. )      
  24.  
  25. ; Force angle between 0 and 2pi (eliminated negatives and over-runs)
  26. (setq MyAngle (fixang MyAngle))
  27.  
  28. ; Find quadrant of provided angle
  29.         ((and (>= MyAngle 0.0) (< MyAngle hpi)) (setq BaseAngle MyAngle))
  30.         ((and (>= MyAngle hpi) (< MyAngle pi)) (setq BaseAngle (- pi MyAngle)))
  31.         ((and (>= MyAngle pi) (< MyAngle 34pi)) (setq BaseAngle (+ pi MyAngle)))       
  32.         ((and (>= MyAngle 34pi) (< MyAngle 2pi)) (setq BaseAngle (- 2pi MyAngle)))     
  33. ) ; close cond
  34.  
  35. ; Make list of complimentary angles
  36. (if (eq UnitCode 0)
  37.   (progn
  38.         ; return list of angles in radians
  39.         (setq OutList (list BaseAngle (- pi BaseAngle) (+ pi BaseAngle) (- 2pi BaseAngle)))
  40.   )
  41.   (progn
  42.         ; return list of angles in degrees
  43.         (setq BaseAngle (rtd BaseAngle))
  44.         (setq OutList (list BaseAngle (- 180.0 BaseAngle) (+ 180.0 BaseAngle) (- 360.0 BaseAngle)))
  45.   )    
  46. )
  47.  
  48. OutList
  49. )
  50.  
  51.  
  52. (defun RTD (A)
  53. ; Radians to Degrees
  54.         (* 180.0 (/ A pi))
  55. )
  56.  
  57. (defun DTR (A)
  58. ; Degrees to Radians
  59.         (* pi (/ A 180.0))
  60. )
  61.  
  62.  
  63.  
  64.  
  65. (defun Fixang (Ang / K)
  66. ; Correct angle to lie within 0 and 2*pi
  67. ; KJM - Jan 1988, Mod KJM March 2019
  68. ; Note: now equivalent to 'Unitcircle' function
  69.  
  70. (if (eq 2pi nil) (setq 2pi (* 2.0 pi)))
  71.  
  72. (if (or (equal Ang 0.0 0.0001) (equal Ang 2pi 0.0001))
  73.         (setq Ang 0.0)
  74. )
  75.  
  76. (setq K 1)
  77.         (cond
  78.                 ((>= Ang 2pi)
  79.                         (setq Ang (- Ang 2pi))
  80.                 )
  81.                 ((< Ang 0.0)
  82.                         (setq Ang (+ Ang 2pi))
  83.                 )
  84.         )
  85.         (if (and (>= Ang 0.0) (< Ang 2pi))
  86.                 (setq K nil)
  87.         )
  88. )
  89. Ang     ; return fixed angle
  90. )

Getting closer, it works unless 210 is the input.

ribarm

  • Gator
  • Posts: 3309
  • Marko Ribar, architect
Re: Mirrored Angles
« Reply #9 on: February 25, 2022, 07:40:24 PM »
Code - Auto/Visual Lisp: [Select]
  1. (defun f ( a / a+ l )
  2.  
  3.   (defun a+ ( a )
  4.     (if (misusp a)
  5.       (rem a (* 2 pi))
  6.     )
  7.   )
  8.  
  9.   (if (> (sin a) 0.0)
  10.     (setq l (list a (+ a pi)))
  11.     (setq l (list a (- a pi)))
  12.   )
  13.   (setq l (append l (mapcar '- l)))
  14.   (vl-sort (mapcar 'a+ l) '<)
  15. )
  16.  

Code: [Select]
(cvunit (f (cvunit 30 "degree" "radian")) "radian" "degree")
(cvunit (f (cvunit 210 "degree" "radian")) "radian" "degree")

Code - Auto/Visual Lisp: [Select]
  1. (defun f ( a / a+ l )
  2.  
  3. ;|
  4.   (defun a+ ( a )
  5.     (if (minusp a)
  6.       (rem (+ pi pi a) (* 2 pi))
  7.       a ;;; now saw ;;;
  8.     )
  9.   )
  10. |; ;;; this is all very unnecessary ;;;
  11.  
  12.   (defun a+ ( a )
  13.     (rem (+ pi pi a) (* 2 pi))
  14.   )
  15.  
  16.   (if (> (sin a) 0.0)
  17.     (setq l (list a (+ a pi)))
  18.     (setq l (list a (- a pi)))
  19.   )
  20.   (setq l (append l (mapcar '- l)))
  21.   (vl-sort (mapcar 'a+ l) '<)
  22. )
  23.  

Code: [Select]
(mapcar '(lambda ( x ) (cvunit x "radian" "degree")) (f (cvunit 30 "degree" "radian")))
(mapcar '(lambda ( x ) (cvunit x "radian" "degree")) (f (cvunit 210 "degree" "radian")))
« Last Edit: February 25, 2022, 08:20:11 PM by ribarm »
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

cmwade77

  • Swamp Rat
  • Posts: 1443
Re: Mirrored Angles
« Reply #10 on: February 25, 2022, 08:09:35 PM »
Might do the trick.  Unit circle approach.  Friday afternoon fun, not rigourously tested..

Command: (circlequads 30 1)
  (30.0 150.0 210.0 330.0)
Command: (circlequads 15 1)
  (15.0 165.0 195.0 345.0)
Command: (circlequads 330 1)
  (30.0 150.0 210.0 330.0)

Code - Auto/Visual Lisp: [Select]
  1. (defun CircleQuads (MyAngle UnitCode / hpi 2pi 34pi BaseAngle OutList)
  2. ; Get complimentary 'mirror' angles in each quadrant of a circle
  3. ; KJM - Feb 2022
  4. ; Input:
  5. ;       MyAngle - (real) angle in degrees or radians
  6. ;       UnitCode - (integer) code.  0 or nil = angles in radians, 1 = angles in degrees
  7. ; Returns:
  8. ;       list of angles in each quadrant of circle
  9. ; Uses custom functions:
  10. ;       dtr
  11. ;       rtd
  12. ;       FixAng
  13.  
  14. ; defaults
  15. (if (not UnitCode) (setq UnitCode 0))
  16. (if (not hpi) (setq hpi (* 0.5 pi)))
  17. (if (not 2pi) (setq 2pi (* 2.0 pi)))
  18. (if (not 34pi) (setq 34pi (* 1.5 pi)))
  19.  
  20. ; Convert to radians
  21. (if (eq UnitCode 1)
  22.         (setq MyAngle (dtr MyAngle))
  23. )      
  24.  
  25. ; Force angle between 0 and 2pi (eliminated negatives and over-runs)
  26. (setq MyAngle (fixang MyAngle))
  27.  
  28. ; Find quadrant of provided angle
  29.         ((and (>= MyAngle 0.0) (< MyAngle hpi)) (setq BaseAngle MyAngle))
  30.         ((and (>= MyAngle hpi) (< MyAngle pi)) (setq BaseAngle (- pi MyAngle)))
  31.         ((and (>= MyAngle pi) (< MyAngle 34pi)) (setq BaseAngle (+ pi MyAngle)))       
  32.         ((and (>= MyAngle 34pi) (< MyAngle 2pi)) (setq BaseAngle (- 2pi MyAngle)))     
  33. ) ; close cond
  34.  
  35. ; Make list of complimentary angles
  36. (if (eq UnitCode 0)
  37.   (progn
  38.         ; return list of angles in radians
  39.         (setq OutList (list BaseAngle (- pi BaseAngle) (+ pi BaseAngle) (- 2pi BaseAngle)))
  40.   )
  41.   (progn
  42.         ; return list of angles in degrees
  43.         (setq BaseAngle (rtd BaseAngle))
  44.         (setq OutList (list BaseAngle (- 180.0 BaseAngle) (+ 180.0 BaseAngle) (- 360.0 BaseAngle)))
  45.   )    
  46. )
  47.  
  48. OutList
  49. )
  50.  
  51.  
  52. (defun RTD (A)
  53. ; Radians to Degrees
  54.         (* 180.0 (/ A pi))
  55. )
  56.  
  57. (defun DTR (A)
  58. ; Degrees to Radians
  59.         (* pi (/ A 180.0))
  60. )
  61.  
  62.  
  63.  
  64.  
  65. (defun Fixang (Ang / K)
  66. ; Correct angle to lie within 0 and 2*pi
  67. ; KJM - Jan 1988, Mod KJM March 2019
  68. ; Note: now equivalent to 'Unitcircle' function
  69.  
  70. (if (eq 2pi nil) (setq 2pi (* 2.0 pi)))
  71.  
  72. (if (or (equal Ang 0.0 0.0001) (equal Ang 2pi 0.0001))
  73.         (setq Ang 0.0)
  74. )
  75.  
  76. (setq K 1)
  77.         (cond
  78.                 ((>= Ang 2pi)
  79.                         (setq Ang (- Ang 2pi))
  80.                 )
  81.                 ((< Ang 0.0)
  82.                         (setq Ang (+ Ang 2pi))
  83.                 )
  84.         )
  85.         (if (and (>= Ang 0.0) (< Ang 2pi))
  86.                 (setq K nil)
  87.         )
  88. )
  89. Ang     ; return fixed angle
  90. )


Found the issue with this one, changed it to:
Code: [Select]
(defun CircleQuads (MyAngle UnitCode / hpi 2pi 34pi BaseAngle OutList)
        ; Get complimentary 'mirror' angles in each quadrant of a circle
        ; KJM - Feb 2022
        ; Input:
        ;       MyAngle - (real) angle in degrees or radians
        ;       UnitCode - (integer) code.  0 or nil = angles in radians, 1 = angles in degrees
        ; Returns:
        ;       list of angles in each quadrant of circle
        ; Uses custom functions:
        ;       dtr
        ;       rtd
        ;       FixAng
       
        ; defaults
         
        (defun RTD (A)
        ; Radians to Degrees
                (* 180.0 (/ A pi))
        )
       
        (defun DTR (A)
        ; Degrees to Radians
                (* pi (/ A 180.0))
        )
         
        (defun Fixang (Ang / K)
        ; Correct angle to lie within 0 and 2*pi
        ; KJM - Jan 1988, Mod KJM March 2019
        ; Note: now equivalent to 'Unitcircle' function
       
        (if (eq 2pi nil) (setq 2pi (* 2.0 pi)))
       
        (if (or (equal Ang 0.0 0.0001) (equal Ang 2pi 0.0001))
                (setq Ang 0.0)
        )
         
        (setq K 1)
        (while K
                (cond
                        ((>= Ang 2pi)
                                (setq Ang (- Ang 2pi))
                        )
                        ((< Ang 0.0)
                                (setq Ang (+ Ang 2pi))
                        )
                )
                (if (and (>= Ang 0.0) (< Ang 2pi))
                        (setq K nil)
                )
        )
        Ang     ; return fixed angle
        )
         
        (if (not UnitCode) (setq UnitCode 0))
        (if (not hpi) (setq hpi (* 0.5 pi)))
        (if (not 2pi) (setq 2pi (* 2.0 pi)))
        (if (not 34pi) (setq 34pi (* 1.5 pi)))
       
        ; Convert to radians
        (if (eq UnitCode 1)
                (setq MyAngle (dtr MyAngle))
        )       
       
        ; Force angle between 0 and 2pi (eliminated negatives and over-runs)
        (setq MyAngle (fixang MyAngle))
       
        ; Find quadrant of provided angle
        (cond
                ((and (>= MyAngle 0.0) (< MyAngle hpi))(setq BaseAngle MyAngle))
                ((and (>= MyAngle hpi) (< MyAngle pi)) (setq BaseAngle (- pi MyAngle)))
                ((and (>= MyAngle pi) (< MyAngle 34pi)) (setq BaseAngle (- MyAngle pi))); This was the line with an error
                ((and (>= MyAngle 34pi) (< MyAngle 2pi)) (setq BaseAngle (- 2pi MyAngle)))     
        ) ; close cond
        ; Make list of complimentary angles
        (if (eq UnitCode 0)
          (progn
                ; return list of angles in radians
                (setq OutList (list BaseAngle (- pi BaseAngle) (+ pi BaseAngle) (- 2pi BaseAngle)))
          )
          (progn
                ; return list of angles in degrees
                (setq BaseAngle (rtd BaseAngle))
                (setq OutList (list BaseAngle (- 180.0 BaseAngle) (+ 180.0 BaseAngle) (- 360.0 BaseAngle)))
          )     
        )
       
        OutList
      )

kirby

  • Newt
  • Posts: 132
Re: Mirrored Angles
« Reply #11 on: February 27, 2022, 09:08:26 AM »
Good catch, thanks!

Lee Mac

  • Seagull
  • Posts: 12926
  • London, England
Re: Mirrored Angles
« Reply #12 on: February 27, 2022, 05:13:40 PM »
Maybe something like this?
Code - Auto/Visual Lisp: [Select]
  1. (defun angmir ( a )
  2.     (if (equal (cos a) 0.0 1e-8)
  3.         (list a (rem (+ a pi) (+ pi pi)))
  4.         (apply 'append (mapcar '(lambda ( x ) (mapcar '(lambda ( y ) (apply y (list x a))) '(+ -))) (list 0 pi)))
  5.     )
  6. )
Code - Auto/Visual Lisp: [Select]
  1. _$ (mapcar 'rtd (angmir (dtr 30)))
  2. (30.0 -30.0 210.0 150.0)

cmwade77

  • Swamp Rat
  • Posts: 1443
Re: Mirrored Angles
« Reply #13 on: February 28, 2022, 11:33:45 AM »
Maybe something like this?
Code - Auto/Visual Lisp: [Select]
  1. (defun angmir ( a )
  2.     (if (equal (cos a) 0.0 1e-8)
  3.         (list a (rem (+ a pi) (+ pi pi)))
  4.         (apply 'append (mapcar '(lambda ( x ) (mapcar '(lambda ( y ) (apply y (list x a))) '(+ -))) (list 0 pi)))
  5.     )
  6. )
Code - Auto/Visual Lisp: [Select]
  1. _$ (mapcar 'rtd (angmir (dtr 30)))
  2. (30.0 -30.0 210.0 150.0)
The problem is that will return -30 instead of 330 and for some technical reasons, that doesn't work in the rest of my program.

ribarm

  • Gator
  • Posts: 3309
  • Marko Ribar, architect
Re: Mirrored Angles
« Reply #14 on: February 28, 2022, 12:44:19 PM »
Maybe something like this?
Code - Auto/Visual Lisp: [Select]
  1. (defun angmir ( a )
  2.     (if (equal (cos a) 0.0 1e-8)
  3.         (list a (rem (+ a pi) (+ pi pi)))
  4.         (apply 'append (mapcar '(lambda ( x ) (mapcar '(lambda ( y ) (apply y (list x a))) '(+ -))) (list 0 pi)))
  5.     )
  6. )
Code - Auto/Visual Lisp: [Select]
  1. _$ (mapcar 'rtd (angmir (dtr 30)))
  2. (30.0 -30.0 210.0 150.0)
The problem is that will return -30 instead of 330 and for some technical reasons, that doesn't work in the rest of my program.

Explain technical resons, and study "a+" function provided within my example earlier...
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

cmwade77

  • Swamp Rat
  • Posts: 1443
Re: Mirrored Angles
« Reply #15 on: February 28, 2022, 12:55:29 PM »
Maybe something like this?
Code - Auto/Visual Lisp: [Select]
  1. (defun angmir ( a )
  2.     (if (equal (cos a) 0.0 1e-8)
  3.         (list a (rem (+ a pi) (+ pi pi)))
  4.         (apply 'append (mapcar '(lambda ( x ) (mapcar '(lambda ( y ) (apply y (list x a))) '(+ -))) (list 0 pi)))
  5.     )
  6. )
Code - Auto/Visual Lisp: [Select]
  1. _$ (mapcar 'rtd (angmir (dtr 30)))
  2. (30.0 -30.0 210.0 150.0)
The problem is that will return -30 instead of 330 and for some technical reasons, that doesn't work in the rest of my program.

Explain technical resons, and study "a+" function provided within my example earlier...

I am calculating polar angles and due to how I am going about doing the calculation, -30 throws it off, as I am getting the closest number  based off a list of numbers.

so say I have a list of angles: (30.0 150.0 210.0 330.0)

Then I have someone starting to draw at an angle of 335, it would return 330. But if my list is (30.0 -30.0 210.0 150.0), it would return 150 instead, which would be incorrect. -30 would technically be correct, but it is harder to identify that.

It all has to do with adding polar tracking to a grread function, code as follows:
Code: [Select]
(defun PolarSnap (Pt1 Pt2 Match_Angle Last_Angle / OriginalAngle PolarAngle AngleList Total ClosestNumber AngleDifference FinalPoint AdditionalAngles); Adjusts angle for polar snap
  (defun bitcodef (value bit)
    ;; Originally Written by Lee Ambrosius on: 6/6/04
    ;; Modified by Chris Wade 1/13/2010
    (if (zerop(logand bit value))
      nil
      T
    );;
  ) ;defun bitcode
  (if (or (bitcodef (getvar "autosnap") 8) (= (getvar "ORTHOMODE") 1) Match_Angle)
    (progn     
      ; Find Closest Number from Grrr1337 - http://www.theswamp.org/index.php?topic=52776.msg576493#msg576493
      ; Snaps a number to the closest one in the list (if the num is equally between 2 vals, then it returns the lower value)
      ; _$ (SnapNumber 3.2 '(0 2 4 6)) -> 4
      ; _$ (SnapNumber 3 '(0 2 4 6)) -> 2
      ; _$ (SnapNumber 45 '(0.0 90.0 180.0 270.0 360.0)) -> 0.0
      (defun SnapNumber ( n Ln / Ld )
        (cond
          ( (or (not (numberp n)) (not (vl-every 'numberp Ln))) (princ "\nInvalid inputs.") nil )
          ( (setq Ld (mapcar '(lambda (x) (abs (- n x))) Ln))
            (nth (vl-position (apply 'min Ld) Ld) Ln)
          )
        ); cond
      ); defun SnapNumber
     
      (defun CircleQuads (MyAngle UnitCode / hpi 2pi 34pi BaseAngle OutList)
        ; Get complimentary 'mirror' angles in each quadrant of a circle
        ; KJM - Feb 2022
        ; Input:
        ;       MyAngle - (real) angle in degrees or radians
        ;       UnitCode - (integer) code.  0 or nil = angles in radians, 1 = angles in degrees
        ; Returns:
        ;       list of angles in each quadrant of circle
        ; Uses custom functions:
        ;       dtr
        ;       rtd
        ;       FixAng
       
        ; defaults
         
        (defun RTD (A)
        ; Radians to Degrees
                (* 180.0 (/ A pi))
        )
       
        (defun DTR (A)
        ; Degrees to Radians
                (* pi (/ A 180.0))
        )
         
        (defun Fixang (Ang / K)
        ; Correct angle to lie within 0 and 2*pi
        ; KJM - Jan 1988, Mod KJM March 2019
        ; Note: now equivalent to 'Unitcircle' function
       
        (if (eq 2pi nil) (setq 2pi (* 2.0 pi)))
       
        (if (or (equal Ang 0.0 0.0001) (equal Ang 2pi 0.0001))
                (setq Ang 0.0)
        )
         
        (setq K 1)
        (while K
                (cond
                        ((>= Ang 2pi)
                                (setq Ang (- Ang 2pi))
                        )
                        ((< Ang 0.0)
                                (setq Ang (+ Ang 2pi))
                        )
                )
                (if (and (>= Ang 0.0) (< Ang 2pi))
                        (setq K nil)
                )
        )
        Ang     ; return fixed angle
        )
         
        (if (not UnitCode) (setq UnitCode 0))
        (if (not hpi) (setq hpi (* 0.5 pi)))
        (if (not 2pi) (setq 2pi (* 2.0 pi)))
        (if (not 34pi) (setq 34pi (* 1.5 pi)))
       
        ; Convert to radians
        (if (eq UnitCode 1)
                (setq MyAngle (dtr MyAngle))
        )       
       
        ; Force angle between 0 and 2pi (eliminated negatives and over-runs)
        (setq MyAngle (fixang MyAngle))
       
        ; Find quadrant of provided angle
        (cond
                ((and (>= MyAngle 0.0) (< MyAngle hpi))(setq BaseAngle MyAngle))
                ((and (>= MyAngle hpi) (< MyAngle pi)) (setq BaseAngle (- pi MyAngle)))
                ((and (>= MyAngle pi) (< MyAngle 34pi)) (setq BaseAngle (- MyAngle pi))); This line was originally ((and (>= MyAngle pi) (< MyAngle 34pi)) (setq BaseAngle (+ pi MyAngle)))
                ((and (>= MyAngle 34pi) (< MyAngle 2pi)) (setq BaseAngle (- 2pi MyAngle)))     
        ) ; close cond
        ; Make list of complimentary angles
        (if (eq UnitCode 0)
          (progn
                ; return list of angles in radians
                (setq OutList (list BaseAngle (- pi BaseAngle) (+ pi BaseAngle) (- 2pi BaseAngle)))
          )
          (progn
                ; return list of angles in degrees
                (setq BaseAngle (rtd BaseAngle))
                (setq OutList (list BaseAngle (- 180.0 BaseAngle) (+ 180.0 BaseAngle) (- 360.0 BaseAngle)))
          )     
        )
       
        OutList
      )
     
      ;; String to List  -  Lee Mac
      ;; Separates a string using a given delimiter
      ;; str - [str] String to process
      ;; del - [str] Delimiter by which to separate the string
      ;; Returns: [lst] List of strings
      (defun LM:str->lst (str del / pos)
        (if (setq pos (vl-string-search del str))
          (cons (substr str 1 pos)
          (LM:str->lst (substr str (+ pos 1 (strlen del))) del)
          ) ;_ >cons
          (list str)
        ) ;_ >if
      ) ;_ >defun
   
      ;; Unique  -  Lee Mac
      ;; Returns a list with duplicate elements removed.
      (defun LM:Unique (l)
        (if l
          (cons (car l) (LM:Unique (vl-remove (car l) (cdr l))))
        ) ;_ >if
      ) ;_ >defun
     

     
      (defun PolarRound (ang deg)
        (* (/ pi (/ 180 (r2d deg))) (fix (/ (+ (/ pi (/ 360 (r2d deg))) ang) (/ pi (/ 180 (r2d deg))))))
      )
      (setq OriginalAngle (r2d (angle Pt1 Pt2))
            PolarAngle (r2d (getvar "POLARANG"))
            Total 0
            IncrementAngles (list PolarAngle)
            AdditionalAngles (getvar 'POLARADDANG)
      )
      (if (> PolarAngle 0)
        (progn
          (while (<= Total 360)
            (setq Total (+ Total PolarAngle))
            (if (<= Total 360)
              (setq IncrementAngles (append IncrementAngles (list Total)))
            )
          )
        )
      )
      (if AdditionalAngles
        (progn
          (setvar "POLARMODE" 4)
          (setq IncrementAngles
            (append IncrementAngles
              (mapcar
                (function
                  (lambda (ang)
                    (atof ang)
                  ) ;_ >lambda
                ) ;_ >function
                (LM:str->lst AdditionalAngles ";")
              ) ;_ >mapcar
            ) ;_ >append
          ) ;_ >setq
        )
      )
      ;Code adjusted from ribarm - http://www.theswamp.org/index.php?topic=57406.msg608991#msg608991
      (if (= (getvar "ORTHOMODE") 1)
        (setq IncrementAngles nil)
      )
      ;end of code to aid in making Ortho work
      (if (and Match_Angle Last_Angle)
        (progn
          (if (and (not (bitcodef (getvar "autosnap") 8)) (= (getvar "ORTHOMODE") 0))
            (setq IncrementAngles nil)
            (setq IncrementAngles (append IncrementAngles (list 0.0 90.0 180.0 270.0)))
          )
          (setq IncrementAngles (append IncrementAngles (CircleQuads Last_Angle 1)))
        )
      )
      (setq IncrementAngles (vl-sort (LM:Unique IncrementAngles) '<))
      (setq ClosestNumber (SnapNumber OriginalAngle IncrementAngles))
      (if (< ClosestNumber OriginalAngle)
        (setq AngleDifference (- OriginalAngle ClosestNumber))
        (setq AngleDifference (- ClosestNumber OriginalAngle))
      )
      (if (or (= (getvar "ORTHOMODE") 1) (and (< AngleDifference 5) (/= ClosestNumber 0))) ;Increase the AngleDifference number to reduce sensitivity
        (progn
          (setq FinalPoint (polar Pt1 (d2r ClosestNumber) (distance Pt1 Pt2)))
          (if (not (= (getvar "ORTHOMODE") 1))
            (grdraw pt1 (polar Pt1 (angle Pt1 FinalPoint) 10000) 3 1)
          )
        )
        (progn
          (setq FinalPoint Pt2)
        )
      )
    )
    (setq FinalPoint Pt2)
  )
  FinalPoint
)

And yes, there may be better ways to accomplish this end goal, but this is what I was able to make work properly in my routine, but I am definitely open to input.
« Last Edit: February 28, 2022, 12:59:42 PM by cmwade77 »

ribarm

  • Gator
  • Posts: 3309
  • Marko Ribar, architect
Re: Mirrored Angles
« Reply #16 on: February 28, 2022, 01:30:01 PM »
Quote
...study "a+" function provided within my example earlier...
...combine return with (vl-sort) function to sort results in ascending order : (vl-sort anglst '<)...

Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

kirby

  • Newt
  • Posts: 132
Re: Mirrored Angles
« Reply #17 on: February 28, 2022, 01:38:03 PM »
Hi cmwade77

Here is last Friday's 'CircleQuads' function including your correction and a tester routine.  Added functionality to remove duplicate angles from output.

Running Lee Mac's output through the 'FixAng' function in my code will correct all the angles to lie between 0 and 2pi, you'll just need to convert them to and from radians (using the dtr and rtd functions).



Code - Auto/Visual Lisp: [Select]
  1. ; CircQuad.lsp
  2.  
  3. ; ========================================================= Main routines
  4.  
  5. (defun C:TestCQ ()
  6. ; Test routine for 'CircleQuads'
  7.  
  8. (setq MyAngle -360.0)
  9. (setq Incr 10.0)
  10.  
  11. (while (<= MyAngle 360.0)
  12.  
  13.         (setq Ans (circlequads MyAngle 1))      ; call custom routine, angles in degrees
  14.         (prompt "\n  Angle = ")(princ MyAngle)(prompt "  Result = ")(princ Ans)(princ)
  15.  
  16.         (setq MyAngle (+ Incr MyAngle))
  17. ) ; close while
  18.  
  19. )
  20. (prompt "\nTestCQ - test 'CircleQuads' function.")(princ)
  21.  
  22.  
  23.  
  24.  
  25. (defun CircleQuads (MyAngle UnitCode / hpi 2pi 34pi BaseAngle OutList)
  26. ; Get complimentary 'mirror' angles in each quadrant of a circle
  27. ; Input:
  28. ;       MyAngle - (real) angle in degrees or radians
  29. ;       UnitCode - (integer) code.  0 or nil = angles in radians, 1 = angles in degrees
  30. ; Returns:
  31. ;       list of angles in each quadrant of circle
  32. ; Uses custom functions:
  33. ;       dtr
  34. ;       rtd
  35. ;       FixAng
  36. ;       Weedlist
  37.  
  38. ; defaults
  39. (if (not UnitCode) (setq UnitCode 0))
  40. (if (not hpi) (setq hpi (* 0.5 pi)))
  41. (if (not 2pi) (setq 2pi (* 2.0 pi)))
  42. (if (not 34pi) (setq 34pi (* 1.5 pi)))
  43.  
  44. ; Convert to radians
  45. (if (eq UnitCode 1)
  46.         (setq MyAngle (dtr MyAngle))
  47. )      
  48.  
  49. ; Force angle between 0 and 2pi (eliminated negatives and over-runs)
  50. (setq MyAngle (fixang MyAngle))
  51.  
  52. ; Find quadrant of provided angle
  53.         ((and (>= MyAngle 0.0) (< MyAngle hpi)) (setq BaseAngle MyAngle))
  54.         ((and (>= MyAngle hpi) (< MyAngle pi)) (setq BaseAngle (- pi MyAngle)))
  55.         ((and (>= MyAngle pi) (< MyAngle 34pi)) (setq BaseAngle (- MyAngle pi)))        ; *** corrected
  56.         ((and (>= MyAngle 34pi) (< MyAngle 2pi)) (setq BaseAngle (- 2pi MyAngle)))     
  57. ) ; close cond
  58.  
  59. ; Make list of complimentary angles
  60. (if (eq UnitCode 0)
  61.   (progn
  62.         ; return list of angles in radians
  63.         (setq OutList (list BaseAngle (- pi BaseAngle) (+ pi BaseAngle) (- 2pi BaseAngle)))
  64.   )
  65.   (progn
  66.         ; return list of angles in degrees
  67.         (setq BaseAngle (rtd BaseAngle))
  68.         (setq OutList (list BaseAngle (- 180.0 BaseAngle) (+ 180.0 BaseAngle) (- 360.0 BaseAngle)))
  69.   )    
  70. )
  71.  
  72. ; Weed duplicate angles (*** added 2022-02-28)
  73. (setq OutList (weedlist OutList))
  74.  
  75. OutList
  76. )
  77.  
  78. ; ========================================================= Helper routines
  79.  
  80.  
  81. (defun RTD (A)
  82. ; Radians to Degrees
  83.         (* 180.0 (/ A pi))
  84. )
  85.  
  86. (defun DTR (A)
  87. ; Degrees to Radians
  88.         (* pi (/ A 180.0))
  89. )
  90.  
  91.  
  92.  
  93.  
  94. (defun Fixang (Ang / K)
  95. ; Correct angle to lie within 0 and 2*pi
  96. ; KJM - Jan 1988, Mod KJM March 2019
  97. ; Note: now equivalent to 'Unitcircle' function
  98.  
  99. (if (eq 2pi nil) (setq 2pi (* 2.0 pi)))
  100.  
  101. (if (or (equal Ang 0.0 0.0001) (equal Ang 2pi 0.0001))
  102.         (setq Ang 0.0)
  103. )
  104.  
  105. (setq K 1)
  106.         (cond
  107.                 ((>= Ang 2pi)
  108.                         (setq Ang (- Ang 2pi))
  109.                 )
  110.                 ((< Ang 0.0)
  111.                         (setq Ang (+ Ang 2pi))
  112.                 )
  113.         )
  114.         (if (and (>= Ang 0.0) (< Ang 2pi))
  115.                 (setq K nil)
  116.         )
  117. )
  118. Ang     ; return fixed angle
  119. )
  120.  
  121. (defun WeedList (MyList / CNT NewList Item)
  122. ; Remove duplicate entities from a list
  123. ; KJM - I.D. Engineering Canada Inc. - May 1988
  124. (setq NewList nil)
  125.  
  126. (setq CNT 0)
  127. (repeat (length MyList)
  128.         (setq Item (nth CNT MyList))                    ; get element
  129.         (if (= nil (member Item NewList))
  130.                 (setq NewList (cons Item NewList))      ; add to new list
  131.         )
  132.         (setq CNT (1+ CNT))
  133. )
  134. (reverse NewList) ; return the weeded list
  135. )
  136.  
  137.  

ronjonp

  • Needs a day job
  • Posts: 7531
Re: Mirrored Angles
« Reply #18 on: February 28, 2022, 03:33:48 PM »
Maybe something like this?
Code - Auto/Visual Lisp: [Select]
  1. (defun angmir ( a )
  2.     (if (equal (cos a) 0.0 1e-8)
  3.         (list a (rem (+ a pi) (+ pi pi)))
  4.         (apply 'append (mapcar '(lambda ( x ) (mapcar '(lambda ( y ) (apply y (list x a))) '(+ -))) (list 0 pi)))
  5.     )
  6. )
Code - Auto/Visual Lisp: [Select]
  1. _$ (mapcar 'rtd (angmir (dtr 30)))
  2. (30.0 -30.0 210.0 150.0)
The problem is that will return -30 instead of 330 and for some technical reasons, that doesn't work in the rest of my program.
Just pass Lee's code to something like this?
Code - Auto/Visual Lisp: [Select]
  1. (mapcar '(lambda (x)
  2.            (if (minusp x)
  3.              (+ 360 x)
  4.              x
  5.            )
  6.          )
  7.         (mapcar 'rtd (angmir (dtr 30)))
  8. )

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC