Search code examples
algorithmgeometrycomputational-geometryeuclidean-distancepolar-coordinates

Segment direction in a polar plane


I have the following situation: Base point (green) and segments, for each segment his vertices represented as polar point with theta angle from base point.

enter image description here

The problem: For each segment I have his 2 vertices theta's. Not ordered! I need just from this data to figure out the range of angles this segment overlaps. For example for the 2 vertices {20,300} belonging to the top segment, the correct answer is all angles from 300 to 20 and NOT from 20 to 300.

The direction is from 0 to 359 and as seen in the example it's cyclic.

EDIT: Assumption - Maximum overlap angle for Segment is less then 180, which means 179.

I think the solution is just to find the "right conditions" for the if...

class Node {
    int theta;  //angle from base point e.g. 45
    double radius;  //distance (in problem specific metric) from base point
}

class Segment {
    //nodes not ordered in any way
    Node node_1;
    Node node_2;
}

List<Segments> allSegments = new ArrayList<>();
//populate allSegments...

Segment mSegment;
for (int i=0; i<allSegments.size(); i++) {
    mSegment = allSegments.get(i);
    if (TODO? mSegment.node_1.tetha ? mSegment.node_2.theta) {
       //the order is from node_1 to node_2 or otherwise...
    }
}

Thanks,


Solution

  • Let's leave aside the case where the line segment passes through the origin. We will consider it later.

    The angles will define two arcs: one that is less than 180 degrees and one that is greater than 180 degrees. Your arc will always be the one that is less than 180 degrees. Why? Consider the x-axis displaced vertically by a very small amount. The range will be 90 degrees to 270 degrees, roughly, giver or take a small amount. As long as you remain on the same side of the x-axis, neither angle will be more than a right angle, so the sum will be less than 2 x 90 degrees.

    Given any two angles x and y, with x and y in [0, 360) (half open interval), we may w.l.o.g. assume x >= y. Then the ranges are (x - y) and (y - x + 360). Compute both and take the smaller of the two. In your example: (300 - 20) = 280 and (20 - 300 + 360) = 80, so 80 is the answer (or 300-20, if you prefer the range format). Again: compute both (x - y) and (y - x + 360), and your range will be "y through x" if (x - y) is smaller or "x through y" if (y - x + 360) is smaller.

    Now consider the case when x = y + 180. What should your algorithm answer then? That's not a rhetorical question - that's a question for users.