# From 3d rotation, snap to nearest 90 directions

I have a 4x4 transformation matrix, made only from successive rotations and translations, and I'd like to "snap" my object to the "nearest" of the 24 orthogonal (multiples of 90 degree) rotations.

I'm not sure how to think of the problem. Round each element of the upper 3x3 matrix to -1, 0, and +1 (cutting at .707)? I am pretty sure that would be too good to be true. Another possibility would be to convert to axis-and-rotation or quaternion, but would that make it simpler somehow? I'm not fluent in those manipulations.

Any guidance most welcome!

• Try it and see how it works? – MichaelHouse Sep 18 '14 at 2:23
• – Lars Viklund Sep 18 '14 at 9:08
• I did find some similar 2d questions, but it wasn't obvious to me that those (straightforward) approaches mapped easily to 3d... – david van brink Sep 18 '14 at 21:08

## 1 Answer

Not sure if this is the most performant, but it can be visualized easily:

//assuming you're starting with a relatively orthonormal matrix

1.) Take one of your matrix's 3 basis vectors and dot it against the 6 world orthogonal vectors and set it to the one whose result is closest to 1.0.

2.) Do the same for one of the 2 remaining basis vectors.

3.) Cross the two that you just reset to determine and reset the third basis vector.

• You should probably guard against the second vector snapping to the same as the first (or the -ve of the first). This might happen e.g. if the original matrix was a rotation of 45 degrees around an axis. You can avoid this happening by excluding the first "snapped" vector from the candidates for the second one. – GuyRT Sep 18 '14 at 21:01
• I am not quite convinced that this method will always yield the closest to the 24 candidate matrices in the sense of choosing the one which needs the smallest rotation to arrive at from the original. – GuyRT Sep 18 '14 at 21:05
• ding! the light is beginning to show. i'll be trying this... (By which I mean, I'll be googling some of the terms next. Basis vector... description sounds to me maybe like, check where (1,0,0) is transformed to, what world orthogonal vector it becomes closest too, where (0,1,0) goes, and what's left for (0,0,1). Is that sort-of on target?) – david van brink Sep 18 '14 at 21:17
• @GuyRT i see what you mean, steps as written might favor whichever vector you check first. Possibly check all 3 vectors up front, and sort from there... – david van brink Sep 18 '14 at 21:25
• That's what I was thinking, but I'm not sure it matters. I'll +1 this answer because it's pretty easy to implement, intuitively yields the correct result and definitely worth trying. I can think of a method which is more exhaustive, but it's more effort to implement and more costly at runtime. – GuyRT Sep 18 '14 at 21:39