Find gap between two non-overlapping polygons - math

I want to identify the gap between two non-overlapping polygons as a new polygon. As displayed in the image below, the comparison will be between polygons A and C, and the result should be the black area (gap) between them. For display purposes the gap area is highlighted with a red line. Any ideas on how to approach this problem ?
I tried using boolean clipping operation in c++, such as difference and exclusiveOr, but given that the polygon where non intersecting the results where not the gap between them.

Related

Calculating area without overlap of polygon

I have a question. I am trying to calculate the area of the following layer (see picture)
intersect area
I used the intersection tool to find the intersection between the layer of 4 overlapping buffers with another polygon (transformed from raster and therefore consists of many other polygons). This layers now consists of more than 200 polygons and most of them on top of each other. I actually want to calculate the 2D area of this layer, so I actually want to transform this layer of many polygons into one polygon so that you are able to calculate the area of this one polygon. My question is therefore, is there a possibility to transform this layer into polygons that are adjacent of each other and that there are no overlapping polygons anymore so I can calculate the area? Maybe there is another way to do this?
If understand your question correctly, you should be able to use the Dissolve Boundaries tool in ArcGIS; dissolve into one polygon; then calculate the area of that polygon.

Dividing space outside of convex polygons into horizontally spanning quadrilaterals

I'm looking for an algorithm that can take an area containing a set of non-overlapping convex polygons as input, and break the space outside of the polygons into a set of non-overlapping convex quadrilaterals. The quadrilaterals need to have the property that they (individually) use as much horizontal space as possible.
Here's the input:
Here's the desired output:
I feel like I have seen some variation of this algorithm used to calculate regions to be flood-filled in very old paint programs. Is there a pleasant way to do this in better than O(n^2) time?
Edit: I realize there are some triangles in the output. I should probably state that quadrilaterals are the desired output, falling back to triangles only when it's physically impossible to use a quad.
I came up with a solution to this. In order to solve this efficiently, some sort of spatial data structure is needed in order to query which polygons are overlapped by a given rectangular area. I used a Quadtree. It's also necessary for the polygon data structure being used to be able to distinguish between internal and external edges. An edge is internal if it is common to two polygons.
The steps are as follows (assuming a coordinate system with the origin in the top-left corner):
Insert all polygons into whatever spatial data structure you're using.
Iterate over all polygons and build a list of all of the Y values upon
which vertices occur. This has the effect of conceptually dividing up
the scene into horizontal strips:
Iterate over the pairs of Y values from top to bottom. For each
pair (y0, y1) of Y values, declare a rectangular area a with
the the top left corner (0, y0) and bottom right corner
(width, y1). Determine the set of polygons S that are
overlapped by a by querying the spatial data structure. For
each polygon p in S, determine the set of edges E of p
that are overlapped by a. For best results, ignore any edge in
E with a normal that points directly up or down. For each
edge e in E, it's then necessary to determine the pair of
points at which e intersects the top and bottom edges of a.
This is achieved with a simple line intersection test,
treating the top and bottom edges of a as simple horizontal
line segments. Join the intersection points to create a set of
new line segments, shown in red:
Create vertical line segments L0 = (0, y0) → (0, y1) and
L1 = (width, y0) → (width, y1). Working from left to right,
gather any line segments created in the preceding step into pairs,
ignoring any line segments that were created from internal edges.
If there were no intersecting external edges, then the only two
edges will be L0 and L1. In this example strip, only four
edges remain:
Join the vertices in the remaining pairs of edges to create
polygons:
Repeating the above process for each horizontal strip achieves
the desired result. Assuming a set of convex, non-overlapping
polygons as input, the created polygons are guaranteed to be
either triangles or quadrilaterals. If a horizontal strip contains
no edges, the algorithm will create a single rectangle. If no
polygons exist in the scene, the algorithm will create a single
rectangle covering the whole scene.

Generating centered hexagonal lattice

I want to create a hexagonal lattice but it should be centered basically the whole lattice is a central hexagon and then layers of hexagon around, like shown in the figure. (may be my description is confusion, but right now that is how I am seeing it).
So I want to generate the coordinates for lattice below. I found many algorithm to create square lattice of hexagons but I want to ask if there is a algorithm for following lattice too.
Note:
N-th layer consists of 6N cells.
First cell of that layer in your representation has coordinate shift
(N*A*Sqrt(3)/2, N*A*3/2), where A is edge length.
First cell of that layer has number
2+3*N*(N-1) //(you have missed 14)
You can start from the first cell of Nth layer, make N more cells to left, N cells to left-down and so on...

Cover polygon with minimal number of overlapping polygons at fixed positions

How to select the minimal number of polygons from a set of polygons with fixed positions, whose union covers the input polygon?
For example, let's consider the following input, where the green polygons are the queried set and the blue one is the query:
The correct covering would be with two polygons:
How to calculate which polygons most efficiently cover the input area (minimizing the number of selected polygons)?
I suppose that polygons are quads, and that you want to maximize returned area for minimal number of photos since with that you will obtain more area for same cost which can be used in future.
This is just a thought about solution.
For each polygon intersection part store list of cover polygons that contain that intersection part. In your example, there are ~30 intersection parts. Some of them are quads, some are L shaped.
For query polygon find all intersection parts that polygon contains or intersects. With that we have set of intersection parts and for each part list of cover polygons. Like:
ip_1 - [c1, c3]
ip_2 - [c1, c2, c3, c6]
...
Inverting this 'matrix':
c1 - [ip_1, ip_2, ...]
c2 - [ip_2, ... ]
c3 - [ip_1, ip_2, ... ]
Finding minimal number of c's that union of lists is whole set of ip's is set covering problem.
This method finds optimal solution. It works with general polygons. In simplest version it doesn't solve area maximization.
Problem is in implementation :-)
First is creation of data structure that support indexing by polygons. For that some space partition structure is needed. Inserting new polygon into data structure means creation of new intersections with intersection parts already in structure. I think that number of intersection parts at the end will be constant factor to number of cover polygons. If you have quads regularly spaced, than cover consists of n*m parts, where n and m are probably small.
Second is set cover problem, it is NP-complete. I hope that you will have not too much of sets to cover.
The solution that seems to give correct results is the following:
Clip all polygons to the queried area
Divide each of the clipped polygon with any others that intersect it, eliminating any duplicates - let's call this operation "chopping". For example, such operation would produce the following non-overlapping polygons:
From the following polygons (clipped by range):
All of the chopped polygons represent the universe in the set covering terms; the chopped polygons covered by a single clipped cover polygon represent a subset
Pre-select all subsets corresponding to the polygons that are not fully covered by the union of other polygons.
Use the approximate algorithm to find the minimum set cover (as described here)
I've implemented this using GeoTools. Here's the code: https://github.com/w-k/MinimalCoverage and the archive with the jar and the dependencies can be downloaded from here: https://github.com/w-k/MinimalCoverage/releases.
I've based this on Ante's answer which was very valuable but did not provide the correct solution. It is incorrect because satisfying the requirement that all intersection parts be covered, results in excessive coverage of the query polygon. For example, the cover polygons clipped by the range polygon (as in the picture above) produce the following common parts:
In order to cover all of the common parts we would have to select all three cover polygons (the middle common part is not entirely covered by either the leftmost nor the rightmost polygon).

How can a convex polygon be broken down into right triangles aligned on the X- and Y- axes?

Given a convex polygon represented by a set of vertices (we can assume they're in counter-clockwise order), how can this polygon be broken down into a set of right triangles whose legs are aligned with the X- and Y-axes?
Since I probably lack some math terminology, "legs" are what I'm calling those two lines that are not the hypotenuse (apologies in advance if I've stabbed math jargon in the face--brief corrections are extra credit).
I'm not sure about writing an algorithm to do this but it seems entirely possible to do this for any convex polygon on a piece of paper. For each vertex project a line vertically or horizontally from that vertex until it meets another of these vertical or horizontal lines. For vertices with small changes in angle, where adjacent sides are both travelling in the same direction in terms of x and y, you will need to add two lines from the vertex, one horizontal and one vetical.
Once you have done this, you should be left with a polygon in the centre of the origonal polygon but with sides that are either vertical or horizontal because the sides have been formed by the lines drawn from the vertices of the original polygon. Because these sides are either vertical or horizontal, this shape can easily be sub-divided into a number of triangles with one horizontal side, one vertical side and one hypotenuse.
I'm assuming you've already ordered the vertices as you describe above, and that they indeed define a convex polygon.
Each vertex defines a horizontal line. For V vertices, then, you will have a set of V lines. Discard any line that meets one of the following criteria:
The vertex or vertices defining that line has/have the highest or lowest Y component (if one vertex, that line intersects the polygon only at that point; if two, that line coincides with a polygon edge)
If two vertices have equal Y coordinates otherwise, keep only one of those lines (it's duplicated).
The result will resemble a "banding" of the polygon.
Each horizontal line intersects the polygon at two points. One is its defining vertex. The other is either another vertex, or a point on a segment defined by two vertices. You can determine which is the case easily enough - just simple comparison of Y coords. The coordinates of the intersection with a segment is also easy math, which I leave to you.
Each intersection defines a vertical segment. The segment is contained within the polygon (if it coincides with an edge, you can discard it), and the other end meets either another horizontal line, or the edge of the polygon if that edge is itself horizontal. Determining the case is again a matter of mere comparison of coords. Finally, there may be 0-2 additional vertical segments, defined by the vertices with the highest and/or lowest Y coords, if there is only one of either.
The resulting diagram now shows each band with a right triangle trimmed off each end if possible. Each triangle should meet your criteria. The leftover regions are rectangles; draw an arbitrary diagonal to split each into two more right triangles meeting your criteria.
You're done.
I'm not sure if this is possible. Think about a square that's already aligned with the sides on the X and Y axes. How do you draw triangles using the vertices that are also aligned to the X,Y axes?
Or are the actual sides of the polygon allowed to be along the x,y axis. Which means you could just draw a line down the diagonal of the square. If so, it might be difficult to do with a more complex polygon where some sides are aligned to the axes, while others are not.
I'm not convinced there is a general solution to the question as posed. The problem is the aligned with the X- and Y-axes bit. That means that each vertex needs to be projected to the opposite side of the polygon in both the X and Y directions, and new vertices created at those intersection points. But that process must continue on for each new vertex added that way. You might get lucky and have this process terminate (because there's already a vertex appropriately placed on the opposite side), but in the general case it's just going to go on and on.
If you throw out that restriction, then Neil N's suggestion seems good to me.
Neil N is right, I think. Unfortunate that he didn't provide any specific links.
If you have a trapezoid whose top and bottom are parallel to the X axis, you can easily render that with 4 right triangles. Call that shape a horizontal trapezoid.
If you have a triangle with one side parallel to the X axis, you can render that with 2 right triangles -- or you can consider a degenerate case of the trapezoid with the top of bottom having length zero.
Start at either the top or bottom of your convex hull (i.e. search for coordinate with min or max y) and split it into horizontal trapezoids.
It's not to hard to write the code so that it works just as well with non-convex polygons.
I think this is not possible in the general case.
Consider the polygon {(0, 1), (1, 0), (2, 0)}
.
..
This triangle can not be split into a finite number of triangles as you describe.

Resources