Hi guys,
The following idea hit me
:
_$ (SnapNumber 88.92 '(0.0 90.0 180.0 270.0 360.0)) -> 90.0
My intention was to "fix" some inaccurate values, by snapping to a value from a numerical list.
Decided that the most approriate name for this subfunction would be "SnapNumber" (my other thoughts were "FixNumber" "getClosestNumberTo").
So I started simple:
; 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
); defun SnapNumber
But then I thought, what if the number is in the middle between two values in the list.. soo:
; Snaps a number to the closest ones in the list (if the num is equally between 2 vals, then it returns list of both values)
; _$ (SnapNumber2 5 '(0 2 4 6)) -> (4 6)
; _$ (SnapNumber2 5.2 '(0 2 4 6)) -> 6
; _$ (SnapNumber2 45 '(0.0 90.0 180.0 270.0 360.0)) -> (0.0 90.0)
(defun SnapNumber2
( n Ln
/ _Positions Ld rtn
)
(defun _Positions
( x lst
/ p
) ; MP ;; find all the positions of x in lst ;; (_Positions 1 '(0 0 1 0 0 1)) >> (2 5) )
)
)
); defun _Positions
)
); cond
); defun SnapNumber2
Which means:
_$ (SnapNumber2 45 '(0.0 90.0 180.0 270.0 360.0)) -> (0.0 90.0)
But my last intention was to add some tolerance/fuzz, where if the snap number is not within range, return the original number:
If we have (defun SnapNumber2 (n fuzz Ln / ...) ... )
Then:
_$ (SnapNumber2 89.1 1.0 '(0.0 90.0 180.0 270.0 360.0)) -> 90
_$ (SnapNumber2 89.1 0.5 '(0.0 90.0 180.0 270.0 360.0)) -> 89.1
_$ (SnapNumber2 5 5 '(0.0 90.0 180.0 270.0 360.0)) -> 0
_$ (SnapNumber2 5 4.9 '(0.0 90.0 180.0 270.0 360.0)) -> 5
Unfortunately right now I don't have enough time to figure this out, so decided to leave it here (instead of burrowing this with my other unfinished subfunctions).