Picking up cucumbers: Sorting points by polar angle

665 Views Asked by At

I'm solving a programming problem that asks me given a list of cucumbers (which are just closed line segments in Cartesian coordinate system given by two points) which don't touch the origin $(0,0)$, how much of them can you pick up if you move from the origin in one direction (maximum).

So for example one cucumber is defined by $x_1,y_1,x_2,y_2\in \Bbb{Z}$ where $(x_1,y_1)$ is the beginning point and $(x_2,y_2)$ as end point.

Now my idea was to mark the beginning/end points of a cucumber as start/end depending on the angle from $x$-axis to the point, where start point has a smaller angle then the end point.

Then sort all points by their angle from the $x$-axis, and if there's a tie put the start points before the end.

Now just traverse the points and keep track of the number of start points and end points and the maximum difference between the number of start and end points is the maximum number of cucumbers that can be picked.

Now there are two caveats I need help with:

Calculating the angle with $\operatorname{atan2}(y,x)$ is not precise neither is $y/x$ so I've thought comparing $y_1x_2$ with $y_2x_1$ but it seems too cumbersome (excuse the pun) because $y_1,x_1,x_2,y_2$ can be negative and I'm not exactly sure how to compare them.

And the second is if the cucumber lays in 1st and 3rd (or 2nd and 4th) for exampleenter image description here Here since the line passes through the 3rd quadrant blue point is the start and green the end however if the line passed through the second quadrant the green would be the start and blue the end, not sure how to differentiate those two cases.

1

There are 1 best solutions below

0
On BEST ANSWER

It can be done without computing square roots, angles, or atan2s (whatever that is). Replace all cucumbers by an equivalent segment through the interior of the square $Q:=[{-1},1]^2$. For this you need a small subroutine accepting a data point $(x_i,y_i)$ as input and producing the corresponding point $\bigl(1,{y_i\over x_i}\bigr)$ (or similar, depending on the signs of $x_i$, $y_i$, and whether $|x_i|$ or $|y_i|$ is larger) on $\partial Q$ as output. You end up with four lists of real numbers $\alpha_i\in[{-1},1]$ corresponding to the four edges of $Q$. It is now sufficient to order these lists "counterclockwise" and then work your way along them in order to find a ray through $(0,0)$ that hits as many segments as possible.