Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Finding a ray that intersects a polygon as many times as possible

Here is an interesting exercise:

Let P be a simple, but not necessarily convex, polygon and q an arbitrary point not necessarily in P.

Design an efficient algorithm to find a line segment originating from q that intersects the maximum number of edges of P.

In other words, if standing at point q, in what direction should you aim a gun so the bullet will go through the largest number of walls?

A bullet through a vertex of P gets credit for only one wall.

An O(n log n) algorithm is possible. n is the number of vertices or edges, as it is a polygon, number of edges roughly equals to number of vertices.

Here is my thought:

Connect q with all vertices (let's say there are N vertices) in P first. There will be N lines, or N-1 pairs of lines.

The final shooting line must be in between these pairs. So we must find the pair that contains the largest number of edges.

I don't think this solution is O(n log n).

Any ideas?

like image 888
Jackson Tale Avatar asked May 06 '12 21:05

Jackson Tale


2 Answers

I used algorithm of Boris Stitnicky and wrote my solution in Java. But I chose counterclockwise direction, and to check what point of an interval is the start point and what point is the end of an interval I used the cross product. You can find it here: https://github.com/Katkov/algorithms/blob/master/BulletAgainstWalls.java

like image 59
Michael Katkov Avatar answered Nov 17 '22 00:11

Michael Katkov


Well, first transform the points coordinates into a polar system centered at P.

  • Without loss of generality, let's choose clockwise direction as special with respect to the angle coordinate.
  • Now let's conduct a circular walk in sequence along all the edges of the polygon, and let's notice the starting and the ending point of those edges, where the walk takes us in the clockwise direction with respect to P.
  • Let's call the ending point of such edge a 'butt', and the starting point a 'head'. This all should be done in O(n). Now we'll have to sort those heads and butts, so with quicksort it might be O(nlog(n)). We are sorting them by their angle (φ) coordinate from the smallest φ up, making sure that in case of equal φ coordinate, heads are considered smaller than butts (this is important to comply with the last rule of the problem).
  • Once finished, we'll start walking them from the smallest φ, incrementing the running sum whenever we encounter a butt, and decrementing whenever we encounter a head, noticing a global maximum, which will be an interval on the φ coordinate. This should be also done in O(n), so the overall complexity is O(nlog(n)).

Now would you tell me why are you asking this kind of questions?

like image 27
Boris Stitnicky Avatar answered Nov 17 '22 00:11

Boris Stitnicky