When The Maths Is Sus
Maths is a peculiar beast. Even a slight issue in the problem will cause the correct solution to completely lose all meaning. Sometimes such a problem is very easy to stumble into (and sometimes I’m too lazy to bring out the pictures, so be prepared to flex your mind muscles a bit).
Map to map mapping
Imagine a 3D world. If you can’t imagine that, then open your eyes. If that doesn’t work then imagine three unit vectors that are orthogonal to each other and any set of coordinates with three values that correspond to the total sum of the unit vectors such that it uniquely identifies any point. Failing that, my imagination starts to fail. Oh, and this 3D world needs to Euclidean as well.
Now, with our three dimensional world, we want to put in on a map. We want a two dimensonal, flat, planar representation of our world from the top down. Why, you ask? Because the rest of this post depends on this need.
Now to make our map be of any use, we need to be able to map any point in our world to our map. This practice is often referred to as mapping. Or in nerdier terms: we need a mapping from our world coordinates to our map coordinates, regardless of which way around the map is.
Points picker
We can, of course, map each point manually, but that is tedious and very error prone. So we automate it, mostly anyway. The process is very simple if one understands linear algebra: we manually pick three distinct points from the world (A, B, C) and we carefully pick their counterparts on the map (A’, B’, C’). We can then represent the world points in a matrix W with the top row being each point’s x coordinate in order, middle row each point’s y coordinate in order, and the last row all 1s. We should also represent the map points similarily in a matrix M.
We know that, as long as the points don’t form a single line but a triangle, there exists a matrix T that maps our world points into map points: TW = M. Finding this T is easy once we know W and M, but it’s also not important here. There is a way to do it and it works (hint: T = MW-1). The only source of error here is that if our points are off, the mapping will be off as well and any other world points we want to map may appear in incorrect places on our map. We’ll accept some inaccuracy, so if the points are a bit off, it’s okay.
For nerds: we’re ignoring the z coordinate from world points because we’re mapping the points from an orthographic top-down projection of the world on to the map, so z is irrelevant.
Put your points where your mapping is
Everything has gone well thus far. But oh no! The implementation doesn’t work! We picked three points and their counterparts on the map, but every other point is going crazy and being placed anywhichway! What’s going on?
This situation happened to me recently, and after carefully making sure all the maths code was correct the problem still persisted. This meant that the problem is with the maths, not the implementation.
But how can that be? The maths don’t lie, that is how it works, the matrix T we get out of that can only be correct, because if it were not, we wouldn’t even have it in the first place! So what gives?
I mean, we expect there to be some inaccuracy due to our manual points pickings, but this much? Nah, we picked two good points far apart on very good corners and a third point on a very recognizable feature. Makes no sense this.
I’m not crazy, you’re crazy!
I only needed to think about this for two days (two full workdays). Only two days, haha. I felt very dissatisfied with having to break down the mapping into parts (rotation, translation, skew, scale, etc.) and I was unable to explain why the above equation didn’t work. Before I could explain it I was not able to believe that it didn’t work.
Note that for most of this I was only able to see the maths, not the code or the visualization of the mapping or anything interactive. I just had four points and their counterparts. Finally when I visualized the transformation in proper scale did I notice that the three points were so very close to forming a single line (i.e. the points were almost collinear), but the map points were a bit further apart.
Only a slight inaccuracy in the points picking caused the mapping to become insanely skewed. Having found this I immediately asked for another test with a clearly further away point that formed a right angle triangle and lo and behold it worked!
So where do we draw the line
The problem all along was that the point C’ did not map exactly to where C should have mapped and because C was so close to B and the line AB it caused a massive skew in T. This discovery was a huge relief to me, because it meant that the equation did work! And I was right to not believe it didn’t.
The thing about this equation is that T will always map our three points exactly, no room for movement. This puts a fair amount of pressure on the third point to be placed accurately, which is rather difficult if your map is a perspective projection of the world and point C is not on the same z level as A and B (assuming A and B are on same z).
What excites me about this story, is that the maths were in a sense too correct and were too rigorous when we wanted relaxed. I had to question the validity of some very straightforward maths and only because I insisted on understanding why did I eventually figure it out.
Maths tends to be a topic everyone runs away from and applying it is just an exercise in copypasting and trial-and-error. Well, I spent two days with a pen and paper (or their whiteboard equivalents) and learned more about a topic I took an exam on six years ago.