Here you go. My logic ( if you can't follow the code, or just to make it easier ) is to get the angle you want to snap to. Then I get all four of the angles. Then as you drag the mouse, then current angle is gotten. Then that is compared to the angles in the list ( the four angles ). When it finds the closes one, it uses that angle to snap to. The distance is the total distance from the start point to the drag point. Not sure if that is correct, but that is my simple thinking. It seems this could be a sub if you want it to be, and could be coded a little different, but you can get the picture from it.
(progn
(setq ang1 (getangle "\n Enter angle to snap ortho to: "))
(setq ang2 (rem (+ ang1 (* pi 0.5)) (* pi 2.)))
(setq ang3 (rem (+ ang1 pi) (* pi 2.)))
(setq ang4 (rem (+ ang1 (* pi 1.5)) (* pi 2.)))
(setq pt1 (getpoint "\n Select first point: "))
(while (not (member (car (setq tempList (grread T 0))) '(11 25)))
(redraw)
(if (equal (car tempList) 5)
(progn
(setq pt2 (cadr tempList))
(setq ang (angle pt1 pt2))
(setq dist (distance pt1 pt2))
(setq pt3
(polar
pt1
(caar
(vl-sort
(mapcar
'(lambda (x)
(cons x (abs (- x ang)))
)
(list ang1 ang2 ang3 ang4)
)
'(lambda (a b)
(< (cdr a) (cdr b))
)
)
)
dist
)
)
(grdraw pt1 pt3 1)
)
)
)
)