Maybe something like this?
_$
(mapcar 'rtd
(angmir
(dtr
30)))(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:
(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.