Algorithm for joining circles into a polygon - algorithm

What is the best way of combining overlapping circles into polygons?
I am given a list of centre points of circles with a fixed diameter.
I need to join any overlapping circles together and output a list of points in the resulting polygon.
This seems like a fairly common problem (GIS systems, vectors, etc.). This is possible to do through the Google Maps API but I am looking for the actual algorithm.
I have tried to solve this problem by calculating points around each circle.
Then removing any points located inside any circle.
This gives me the correct list of points in the desired polygon.
However, the order of the points is a problem with this solution. Each circle has its points stored in an array. To merge them correctly with 2 overlapping circles is relatively straight forward. However, when dealing with multiple overlapping circles it gets complicated.
Hopefully you have some ideas to either make this solution work or of another algorithm that will achieve the desired result.
Thanks in advance!

You should be able to use an appraoch like the following:
First, identify circles that belong to the same group of overlapping circles. Obviously, two circles overlap if the absolute distance of their centres is less than their combined radii. For each circle, store the circles it itersecs with in a hashmap/dictionary. (You can extend this to entire groups of circles using the union-find algorithm, or disjoint sets, but this is not really needed.)
When creating the points belonging to one circle, memorize the left and right neighbor of each point. You get this for free by just storing them in an ordered array.
Remove the "inner" points, i.e. those that are closer than one radius to any of the centres of the circles intersecting the first circle.
Mark the neighbors to those inner points that were not removed the "loose ends" of the circles.
Connect the points that were not removed, including the loose ends, to their original left and right neighbors.
For each loose end point, find the closest loose end of a different circle in the same group and connect them.
Here's a picture to illustrate the approach.
Red dots are "inner" points that are removed
Blue dots are "loose ends" by being neighbors to "inner" points; each "loose end" has another "loose end" of a different circle that's less than two "point-distances" away
Green dots can easily be connected to their neighbors (including the "loose ends") by the order in which they were arranged around the circle.
You can further decrease the number of possible combinations by distinguishing left and right loose ends, and using the fact that each left loose end of one circle has to be connected to a right loose end of another circle. For n circles in a group, that leaves just (n-1)! ways to connect those circles, irrespective of the number of points per circle.
And even this can be reduced further if you consider only those circles in the group that actually intersect the circle with the loose end (just store those in a hashmap/dictionary). So if you have n circles that on average intersect with k other circles, then there are only n*k possible combinations.
You could also use the fact that the other loose end can not be farther away than two times the distance between two point on the circle. Let's call this distance d, then you can create a spatial map with resolution d (e.g. a hashmap, or just a 2D array) and assign each loose end to cells in that map, then the other loose end must be in the same of one of the surrounding cells of the first loose end.
Thus, the number of ways in which points can be connected to each other is greatly reduced (in particular, the way they are connected in your final image would not be allowed to begin with): This should be doable even with brute force unless you have lots of overlapping circles in the same group, and there are smarter algorithms for nearest-neighbor search that you can use.
Update: Reviewing this answer after some time, it seems that you can determine the matching pairs of "loose end" points rather easily: Say you have a "right" loose end in circle A, then the matching "left" loose end has to belong to the circle whose radius overlapped the next "inner" point to the first "loose end". So if you store that relation in another map, you can immediately determine the matching loose end. (If an inner point is overlapped by multiple other circles, the map should contain the circle that overlaps it the most.)

Here's a sketch of an O(n log n)-time algorithm.
Use your favorite algorithm/library to compute a Delaunay triangulation on the circle centers.
Delete the edges between circles that do not overlap.
Walk around the infinite face of each connected component. This is easy to do with a doubly connected edge list representation, where the ordering of the edge lists is used to indicate the topology of the planar graph. Every half-edge on this boundary turns into a vertex where an arc segment belonging to its tail point ends and an arc segment belonging to its head point begins.
(Optional) Approximate each arc segment by a polygonal line.
If anyone from Google is reading this, please note that I have not looked at the relevant code.

Related

Drawing no intersected polygon with dragging vertexes

I'm trying to draw a polygon without intersecting.
Below is good example which I want to.
Bad example what I want to prevent.
If I choose red dot one, then what algorithm I can apply to prevent the intersecting sides of the polygon?
Technical answer:
The moving point must belong to the visibility zones of its two neighbors (ignoring the two adjoining edges).
You can construct these two zones and their intersection once for all, then constrain the cursor to remain in the intersection. This can be made efficiently in time O(Log(N)) per query, after some preprocessing. But this is quite complex and not worth the effort.
Practical answer:
Simply check that the two edges from the moving point do not intersect the remaining edges.

Sweep line algorithm for circle intersection, represent circle into two halves

I am trying to develop sweep line algorithm for given list of circles. by checking different sources I am able to understand the algorithm .
here are the links that i am referring ,
http://www.stolerman.net/studies/cs623/cs623_winter_2012_sol2.pdf
https://www.cs.cmu.edu/~15451-f17/lectures/lec21-sweepline.pdf
As the solution in given links says that We need to represent the circle in two halves because every sweep line intersect a given circle at most two point at any given time.
I am not able to understand how can we represent any circle in two halves e.g., bottom half and top half . It will be great help if someone can explain the data structure to represent a circle into two halves and how the ordering will be defined for semicircles in binary search tree ?
The algorithm you linked to uses the fact that, if you have two opposite points on a circle, the segment between them uniquely defines a circle, and that segment is a diameter of the circle.
Hence, if you keep a list of all rightmost and leftmost points for all your circle, you will have a representation of all your circles.
More generally, you just need to make sure that the two points you are keeping for each circle make a diameter that is perpendicular to the sweep line you are using in the algorithm.
Depending on what the expected input for the algorithm is, you will need to translate that representation into those two points, but then, with a list of couple of points: [(p1, p2), ..., (p_{2n-1}, p_{2n})] where you have n circles.
Rather than storing a circle in the tree, you can store two half-circles. They result from splitting the circle so that the sweep-line meets a half-circle only once. Whether you indeed store two half circles, or two references to the same circle with a way to tell which half is a matter of ease of implementation.
Beware that two half-circles may intersect even if the segments that join the same endpoints do not intersect.

How to compute the set of polygons from a set of overlapping circles?

This question is an extension on some computation details of this question.
Suppose one has a set of (potentially overlapping) circles, and one wishes to compute the area this set of circles covers. (For simplicity, one can assume some precomputation steps have been made, such as getting rid of circles included entirely in other circles, as well as that the circles induce one connected component.)
One way to do this is mentioned in Ants Aasma's and Timothy's Shields' answers, being that the area of overlapping circles is just a collection of circle slices and polygons, both of which the area is easy to compute.
The trouble I'm encountering however is the computation of these polygons. The nodes of the polygons (consisting of circle centers and "outer" intersection points) are easy enough to compute:
And at first I thought a simple algorithm of picking a random node and visiting neighbors in clockwise order would be sufficient, but this can result in the following "outer" polygon to be constructed, which is not part of the correct polygons.
So I thought of different approaches. A Breadth First Search to compute minimal cycles, but I think the previous counterexample can easily be modified so that this approach results in the "inner" polygon containing the hole (and which is thus not a correct polygon).
I was thinking of maybe running a Las Vegas style algorithm, taking random points and if said point is in an intersection of circles, try to compute the corresponding polygon. If such a polygon exists, remove circle centers and intersection points composing said polygon. Repeat until no circle centers or intersection points remain.
This would avoid ending up computing the "outer" polygon or the "inner" polygon, but would introduce new problems (outside of the potentially high running time) e.g. more than 2 circles intersecting in a single intersection point could remove said intersection point when computing one polygon, but would be necessary still for the next.
Ultimately, my question is: How to compute such polygons?
PS: As a bonus question for after having computed the polygons, how to know which angle to consider when computing the area of some circle slice, between theta and 2PI - theta?
Once we have the points of the polygons in the right order, computing the area is a not too difficult.
The way to achieve that is by exploiting planar duality. See the Wikipedia article on the doubly connected edge list representation for diagrams, but the gist is, given an oriented edge whose right face is inside a polygon, the next oriented edge in that polygon is the reverse direction of the previous oriented edge with the same head in clockwise order.
Hence we've reduced the problem to finding the oriented edges of the polygonal union and determining the correct order with respect to each head. We actually solve the latter problem first. Each intersection of disks gives rise to a quadrilateral. Let's call the centers C and D and the intersections A and B. Assume without loss of generality that the disk centered at C is not smaller than the disk centered at D. The interior angle formed by A→C←B is less than 180 degrees, so the signed area of that triangle is negative if and only if A→C precedes B→C in clockwise order around C, in turn if and only if B→D precedes A→D in clockwise order around D.
Now we determine which edges are actually polygon boundaries. For a particular disk, we have a bunch of angle intervals around its center from before (each sweeping out the clockwise sector from the first endpoint to the second). What we need amounts to a more complicated version of the common interview question of computing the union of segments. The usual sweep line algorithm that increases the cover count whenever it scans an opening endpoint and decreases the cover count whenever it scans a closing endpoint can be made to work here, with the adjustment that we need to initialize the count not to 0 but to the proper cover count of the starting angle.
There's a way to do all of this with no trigonometry, just subtraction and determinants and comparisons.

given N disjoint triangles in 2D space, discover which one contains a given point without iterating through everyone

Pretty straightforward: given N triangles T1, ... ,Tn and a point P, what is the best approach to find an i such that P is inside Ti?
PS: Don't know if this is important, but the triangles are disposed as if they were part of the map of a country (for example, get any country and draw it only with triangles, thats how the given triangles should be placed like).
If preprocessing is an option, you can consider inserting your triangles in an R-tree.
https://en.wikipedia.org/wiki/R-tree
Update:
If there is a single point, there is no shortcut. Exhaustive comparison is mandated. Otherwise the algorithm could "guess" the position of some triangles without even looking at them.
Make use of Sweepline algorithm. You need to order triangles from their left to right co-ordinates.
Make a Minpriority queue and put all triangles(co-ordinates , left and right, so each trinangle will be inserted twice, the first point is begin point(x-min) and the second point is end point(x-max)) in priotity queue and the co-ordinates of point also.
Remove the first co-ordinate:
if it is left point then put it in binary search tree along witht triangle whose co-ordinate is this.
If it is right co-ordinate then remove the triangle from the binarysearchtree.
If it is co-ordinates of point then the your point must lie in only those triangles who are in binarysearchtree.

select subset of points if inside a circle

Imagine lots of points like of order 10M.
Now I randomly draw a circle in a given space.
This circle will now enclose some points depending on the center and radius.
Now, I want to select all the points which are present inside this circle.
The brute force approach is very inefficient.
Is there a better way to solve this.
P.S- I am coding in python.
Thanks
Edit:
Brute Force Approach:
Select a point from the space , calculate the distance from the center and if it is less than the radius, then it lies inside otherwise outside.
The brute force is, well I have to go thru all the points and this is problametic because in the next iteration I am going to again select a point in random and repeat above steps.So this is like O(n^2)..
Can I do better?
Arrange points in advance in some space partitioning structure.
For example, quad-tree. Traverse the tree. As each node corresponds to a square on the plane, you can quickly check if that square intersects with your circle (having at least one corner inside the circle or circle being entirely inside the square). If it does intersect, continue traversing down that node, if it does not intersect, skip all of its children, potentially eliminating a large number of individual checks against the points in that square.

Resources