I am trying to figure out how to develop an algorithm that can accomplish this task using the complex O ((n + s) log n) task. s is the number of intersections. I tried searching the Internet but could not find something.
In any case, I understand that a good data structure is important here. I am using a Red Black Tree implementation in java: TreeMap. I also use the famous (?) Sweep Algorithm to help me deal with my problem.
Let me explain my setup first.
I have a scheduler. This is a PriorityQueue with ordered circles (ascending) based on their leftmost coordinate. scheduler.next() basically poll PriorityQueue, returning the next leftmost circle.
public Circle next() { return this.pq.poll(); }
I also have an array with 4n events here. Giving each circle has 2 event points: most left x and rightmost x. The scheduler has a sweepline () method to get the next event point.
public Double sweepline() { return this.schedule[pointer++]; }
I also have a status. More accurate scan line status. According to theory, the status contains circles that can be matched to each other. The point of having a scan line in this whole story is that you can exclude many candidates because they simply are not in the radius of the current circles.
I executed the status using TreeMap<Double, Circle> . The double is circle.getMostLeftCoord().
This TreeMap guarantees O (log n) for insert / delete / search.
The algorithm itself is implemented as follows:
Double sweepLine = scheduler.sweepline(); Circle c = null; while (notDone){ while((!scheduler.isEmpty()) && (c = scheduler.next()).getMostLeftCoord() >= sweepLine) status.add(c); while(status.oldestCircle().getMostRightCoord() < sweepLine) status.deleteOldest(); Circle otherCircle; for(Map.Entry<Double, Circle> entry: status.keys()){ otherCircle = entry.getValue(); if(!c.equals(otherCircle)){ Intersection[] is = Solver.findIntersection(c, otherCircle); if(is != null) for(Intersection intersection: is) intersections.add(intersection); } } sweepLine = scheduler.sweepline(); }
EDIT: Solver.findIntersection(c, otherCircle); returns max 2 intersection points. Overlapping circles are not considered intersecting.
SweepLineStatus Code
public class BetterSweepLineStatus { TreeMap<Double, Circle> status = new TreeMap<Double, Circle>(); public void add(Circle c) { this.status.put(c.getMostLeftCoord(), c); } public void deleteOldest() { this.status.remove(status.firstKey()); } public TreeMap<Double, Circle> circles() { return this.status; } public Set<Entry<Double, Circle>> keys() { return this.status.entrySet(); } public Circle oldestCircle() { return this.status.get(this.status.firstKey()); }
I tested my program and I obviously had O (n ^ 2) complexity. What am I missing here? Any input that you guys can provide is more than welcome.
Thanks in advance!