Given an ordered set of 2D pixel locations (adjacent or adjacent-diagonal) that form a complete path with no repeats, how do I determine the Greatest Linear Dimension of the polygon whose perimeter is that set of pixels? (where the GLD is the greatest linear distance of any pair of points in the set)
For my purposes, the obvious O(n^2) solution is probably not fast enough for figures of thousands of points. Are there good heuristics or lookup methods that bring the time complexity nearer to O(n) or O(log(n))?
My off-the-cuff solution is to try a binary partitioning approach, where you draw a line somwwhere in the middle and check distances of all points from the middle of that line. That would provide you with 2 Presumably Very Far points. Then check the distance of those two and repeat the above distance check. Repeat this process for a while.
My gut says this is an n log n heuristic that will get you Pretty Close.
On this page:
it shows that you can determine the maximum diameter of a convex polygon in O(n). I just need to turn my point set into a convex polygon first (probably using Graham scan).
Here is some C# code I came across for computing the convex hull:
An easy way is to first find the convex hull of the points, which can be done in O(n log n) time in many ways. [I like Graham scan (see animation), but the incremental algorithm is also popular, as are others, although some take more time.]
Then you can find the farthest pair (the diameter) by starting with any two points (say x and y) on the convex hull, moving y clockwise until it is furthest from x, then moving x, moving y again, etc. You can prove that this whole thing takes only O(n) time (amortized). So it's O(n log n)+O(n)=O(n log n) in all, and possibly O(nh) if you use gift-wrapping as your convex hull algorithm instead. This idea is called rotating calipers, as you mentioned.
Here is code by David Eppstein (computational geometry researcher; see also his Python Algorithms and Data Structures for future reference).
All this is not very hard to code (should be a hundred lines at most; is less than 50 in the Python code above), but before you do that -- you should first consider whether you really need it. If, as you say, you have only "thousands of points", then the trivial O(n^2) algorithm (that compares all pairs) will be run in less than a second in any reasonable programming language. Even with a million points it shouldn't take more than an hour. :-)
You should pick the simplest algorithm that works.
You could maybe draw a circle that was bigger than the polygon and slowly shrink it, checking if youve intersected any points yet. Then your diameter is the number youre looking for. Not sure if this is a good method, it sounds somewhere between O(n) and O(n^2)
I ported the Python code to C#. It seems to work.