A somewhat simpler way, if a bit more tedious is to project the point onto each axis using the dot product, and just pick whichever one has the largest absolute value. No trig or anything needed. As some crappy lua code, because that's what I was sitting in front of at the time... Could certainly be simplified a lot.

function project_onto_axis(point, axis) local dist = dot(point, axis) return math.abs(dist), axis*dist end function max_axis(a_dist, a_proj, b_dist, b_proj) if(a_dist > b_dist) then return a_dist, a_proj else return b_dist, b_proj end end function snap(point) x_dist, x_proj = project_onto_axis(point, vec2(1, 0)) y_dist, y_proj = project_onto_axis(point, vec2(0, 1)) card_dist, card_proj = max_axis(x_dist, x_proj, y_dist, y_proj) -- can use a better sqrt(2) approx here if you care. xy_dist, xy_proj = project_onto_axis(point, vec2(0.7, 0.7)) yx_dist, yx_proj = project_onto_axis(point, vec2(0.7, -0.7)) diag_dist, diag_proj = max_axis(xy_dist, xy_proj, yx_dist, yx_proj) return max_axis(card_dist, card_proj, diag_dist, diag_proj) end