Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check connection between two points on 2D plane

SO,

The problem

I have a question about algorithm of determining if two points are connected on 2D-plane. I have:

  • Array of 2D-lines. Each line is limited with its start end end 2D-point. Each point is simple array of two elements [x,y] - i.e. each line looks like ['start'=>[X0, Y0], 'end'=>[X1, Y1]] Let this lines set be named as L. Lines can belongs one to another (i.e. one could be part of another), they can be intersected by only one point e.t.c. - i.e. there are no restrictions for them on 2D plane. But line can not be a point - i.e. start of line can not be equal to end of line.
  • Two points S and E, i.e. arrays [Xs, Ys] and [Xe, Ye]

Now, all lines from L are drawn on the plane. Then, S and E are also drawn and I need to answer the question - can E be reached from S without intersection of any lines in L? And, to be more specific - which algorithm will be optimal? By 'could be reached' I mean that there is a way on the plane from S to E without intersection any line from L - and, of cause, this way could be anything, not just line.

Sample

enter image description here

-as you see, in sample S and E are not connected. Also in the sample there is a case when one line fully belongs to another (gray and purple lines) - and a case when one line has a start/end on another line (green and rose lines).

My approach

Currently, I have non-deterministic polynomial (NP) algorithm to do that. It's steps are:

  • Find all intersections for each pairs of lines.
  • Create new set of lines from points of first step. If two lines has one intersection, then there will be 4 new lines with intersection point at the start of each new line - or it can be 3 new lines if first line has it's start/end on second line - or it can be 2 new lines if first line has it's start/end exactly match with second's line start/end. I.e:

Five general cases for two lines

so 1-st case will result in 4 new lines, 2-4 cases in 3 new lines and 5 case in 2 new lines. (lines are [A, B] and [C, D])

  • Next, in lines step from 2-nd step I'm searching all polygons. Polygon is a closed line set (i.e. it holds closed part of area)
  • I'm determining for S subset of such polygons that contain S. To do this, I'm using simple algorithm - counting number of intersections with polygon's edges and some line from S to outer plane (if it's odd, then S is inside polygon and if it's even - then outside). This is a ray-casting algorithm. Then I do that for E
  • Now, when I have polygons set for both S and E I'm simply comparing both sets. If they are equal, then E could be reached from S and could not be - otherwise.

Why is this NP?

The answer is simple: on 3-rd step I'm performing search of all loops in 2D-graph. Since a problem of finding maximum/minimum loop length if NP, then mine is too (because I can get maximum/minimum loop length simply with sorting resulted loops set). Good information about this is located here.

The question

Since my current solution is NP, I want to know - may be my solution for the problem is an overkill? I.e. may be there are simpler solution which will result in polynomial time?

like image 260
Alma Do Avatar asked Sep 27 '13 09:09

Alma Do


2 Answers

Basically the problem boils down to:
1) Determine all of the polygons enclosing some space which don't contain any other polygon. In your above example, you have 3 shapes/cycles/polygons that do not contain any others: the quadrilateral containing S, the quadrilateral containing E, and the triangle below the 2 of them.
2) Determine if S and E are on opposite inside/outside of any of these polygons.

For part 1, you have to build a graph:

Create an array of intersection points of your given line, this is N^2. Remember which 2 lines each intersection point came from. These intersection points are the vertexes of your graph.

Two vertexes are "connected" if they are from the same line and there is no other intersection point between them. Don't rely on the accuracy of floating point to determine this, obviously.

Now you wish to find the polygons in your layout. A graph may in general contain an exponential number of cycles. However, each edge may only border 2 "inner" polygons, so we are only interested in a polynomial subset of the cycles. So pick an edge, then find the next edge in the polygon, and keep repeating until you get back to where you started or determine that the first edge wasn't part of a polygon.

So suppose you are coming from edge E = (U, V), and want to find the next edge in the polygon (sharing the same vertex V).
1) Create a vector T as U - V.
2) Create the set of edges A that are adjacent to vertex V. Remove E from that set.
3) If the set is empty, then the edge isn't part of a polygon.
4) For each edge (Q, V) in A, construct a vector R as Q - V. (Remember Q and V represent points in the 2D plane).
5) Normalize R : divide it by it's length to create a vector of length 1.
6) Determine CrossProductValue(T, R).
7) The edge in A with the least CrossProductValue is the next edge in one the adjacent polygons. The edge in A with the largest CrossProductValue is the next edge in the other polygon.

CrossProductChecker(2D T, 2D R) {   return (T.x*R.y - T.y*R.x); // cross product for 2 dimensions } 

So use this to find your polygons. Lookup the relation between cross products and sinusoids to get an idea how this works.

============

Now that you have all of your polygons, all there is to do is check if there is one that S is inside of and E is outside of, or the other way around.

The easy way to do this is to draw a line from S to E. If it intersects any polygon (cycle from above) an even number of times, they are both inside or both outside the polygon so keep checking.

If the line intersects a cycle an odd number of times, then one is inside the polygon and one is outside, so you can say that there is no path.

like image 80
DanielV Avatar answered Sep 25 '22 18:09

DanielV


You can construct a so-called "Visibility graph" that connects two obstacle vertices iif they are directly visible. Shortest path in this graph (with S and E added) will be the shortest obstacle-free path between S and E in your configuration space. Algorithms and optimisations concerning Visibility Graph are well-known and widely described.

The main difficulty you'll have is handling corner cases so you can't "leak" in some improper intersection to the other side of the segment (shared segments, endpoint as intersection, etc). Handling such corner cases is not algorithmically difficult but requires patience.

EDIT:

So let me be more formal: build a graph G(Ver, Edg) where Ver contains all segment's endpoints, S and E; and Edg contains all pairs of vertices which are directly visible (including following the segment).

like image 26
goldwin-es Avatar answered Sep 23 '22 18:09

goldwin-es