A plane subdivision into non-overlapping regions by a set of polygons - algorithm

Please see the example image:
There are a set of polygons (convex, non-convex, but not self-intersecting) in a plane. Polygon is defined by vertices – points (x and y coordinates, cartesian coordinate system).
Example set of polygons:
The first polygon is A, B, C.
The second polygon is D, E, F, G, H, I, J.
The third polygon is K, L, M, N.
The fourth polygon is O, P, Q.
Polygons divide a plane into regions. Some parts of polygons may be overlapping (like the first and the second polygon, the second polygon and the third polygon). This overlapping parts is seperate regions too. Some polygons may be inside others (like the fourth polygon inside the second polygon).
Example regions after subdivision: blue, pink, green, orange, brown and purple.
I imagine for simplicity that the plane is a rectangle with constant x, y coordinates.
The Goal
Detect the region (blue, pink, green, etc.) by the query point.
I am looking for algorithm and data structure for a plane subdivision with these assumptions.

First transform your set of polygons into a set of non-overlapping polygons by iteratively looking for pairwise intersections and replacing the pair of intersecting polygons with their intersection and the original polygons minus the intersection. This might be easier and faster if you first split each polygon into a set of convex polygons (the convex polygons can simply "inherit" the "color" of the original concave polygon).
You can then put the polygons into a quad-tree or a similar data structure which allows you to quickly select candidate polygons for membership tests for a given query point.
You will need to define what is happening on edges shared between multiple polygons.

I can recommend a trapezoidal decomposition http://en.wikipedia.org/wiki/Point_location#Trapezoidal_decomposition for efficient point queries in a planar subdivision.
In your case, the subdivision is defined indirectly so there is an extra step. You can try three approaches:
1) use a general polygon intersection algorithm that you will call incrementally,
2) form the trapezoidal decompositions of the polygons and perform fusions of these trapezoidal maps,
3) modify an existing trapezoidal decomposition algorithm so that it accepts as input a subdivision formed of overlapping polygons.
You will need to use some 2D Computational Geometry library... and courage.
ALTERNATIVE:
If your precision requirements are not too high, use a bitmap and fill every polygon, changing the color when pixels already painted are met.

Related

How to Judge the Equality of 2 Triangular Meshes?

Given a triangular mesh A in 3D space. Rotate and translate all its points to generate a new mesh B.
How to determine the equality of A and B, just by their vertices and faces?
Topology of the mesh is not important, I only care about the geometric equality, A and B should be equal even if their triangulation are changed. It is
something like the transform in-variance problem for triangular mesh, only translate and rotation is considered.
To complete #Spektre's answer, if the two meshes are not exactly the same, that is there is at least a pair of nodes or edges which does not perfectly overlap, You can use the Hausdorff distance to quantify the "difference" between the two meshes.
Assuming triangle faces only.
compare number of triangles
if not matching return false.
sort triangles by their size
if the sizes and order does not match between both meshes return false.
find distinct triangle in shapes
So either the biggest or smallest in area, edge length or whatever. If not present then you need other distinct feature like 2 most distant points etc ... If none present even that then you need the RANSAC for this.
Align both meshes so the matching triangles (or feature points) will have the same position in both meshes.
compare matching vertexes
so find the closest vertex form Mesh A to each vertex in mesh B and if the distance of any them cross some threshold return false
return true
In case meshes has no distinct features for 3 you need to either use brute force loop through all combinations of triangles form A and B until #4 returns true or all combinations tested or use RANSAC for this.
There are alternatives to #3 like find the centroid and closest and farthermost points to it and use them as basis vectors instead of triangle. that requires single vertex or close group of vertexes to be the min and max. if not present like in symmetrical meshes like cube icosahedron, sphere you're out of luck.
You can enhance this by using other features from the mesh if present like color, texture coordinate ...
[Edit1] just a crazy thinking on partial approach without the need of aligninig
compute average point C
compute biggest inscribed sphere centered at C
just distance from C to its closest point
compute smallest outscribed sphere centered at C
just distance from C to its farthest point
compare the radiuses between the shapes
if not equal shapes are not identical for sure. If equal then you have to check with approaches above.
The paper On 3D Shape Similarity (Heung-yeung Shum, Martial Hebert, Katsushi Ikeuchi) computes a similarity score between two triangular meshes by comparing semiregular sphere tessellations that have been deformed to approximate the original meshes.
In this case, the meshes are expected to be identical (up to some small error due to the transformation), so an algorithm inspired by the paper could be constructed as follows:
Group the vertices of each mesh A, B by the number of neighboring vertices they have.
Choose one vertex V_A from mesh A and vertex V_Bi from mesh B, both with same number of neighbors.
The vertex and its N neighbors V_n1...V_nN form a triangle fan of N triangles. Construct N transforms which take vertex V_Bi to V_A and each possible fan (starting from a different neighbor V_Bn1, V_Bn2, ..., V_BnN) to V_An1...V_AnN.
Find the minimum of the sums of distances from each vertex of B to the closest vertex to it in A, for each N transforms for each vertex V_Bi.
If a sum of near zero is found, the vertices of the transformed mesh B coincide with vertices of A, a mapping between them can be constructed, and you can do further topological, edge presence or direction checks, as needed.

Translate and transform plane geometry based on corner coordinates

I have a plane mesh with divisions and I want to specify the coordinates that each of the corners should be positioned. Moving and updating the mesh vertices achieves what I'm trying to do, so long as the plane only has no internal segments. If internal segments are added then I have more vertices than I can manually place, so these need to automatically fall in line with the transformation of the outer edges.
My initial thought here was that I could create a geometry with only four vertices, reposition them, and then increase the number of segments on my plane, apparently, this isn't something that Three.js supports, so I'm looking for a workaround.
Any thoughts would be appreciated.
I don't think that this sort of transformation is expressible as a single matrix that you could then just apply to your plane mesh. I think you really do need to calculate the coordinates of each vertex of the subdivided plane manually.
There are different ways to do this calculation. Bilinear interpolation is this case seems to do the job. Here's how you do it. If you have four points A, B, C, D, then for each internal points, its position can be found as the weighted average of (the weighted average of A and B, and the weighted average of C and D). The weights for the averages come from the index of the subdivision vertex in one direction (say, X) for the inner averages and in the other direction (say, Y) for the outer average. Your indexes run from 0 up to the number of subdivisions in that direction (inclusive), the weight should be from 0 to 1, so the weight = index / number of subdivisions.

calculate intersection area of two triangle

I have been trying to find an algorithm which computes the intersecting area of two triangles but I failed to find any. Can anybody give a clue how to write this algorithm?
I would like something like:
double getAreaOfIntersection(Vector2 p1,Vector2 p2, Vector2 p3,Vector2 p4,Vector2 p5,Vector2 p6 )
where pX represents the 2 triangles.
You could first compute the polygon which describes the intersection area by a clipping algorithm, e.g.:
Sutherland-Hodgman algorithm
Then you would compute the area of the resulting convex polygon, which is rather easy, see, e.g., here:
Area of a Convex Polygon
Determining wether or not a point lies within a given polygon is easy (and even easier for triangles since those are simple polygons). You can use the winding number algorithm (and the crossing number algorithm for simple polygons) which is implemented and well explained here.
Using this you can obtain all the vertices of your intersection polygon:
The vertices pX of a triangle that are contained in the other triangle as well
The points where the two triangles intersect (see intersection of line segments)
You will need to loop over your edges to find all the intersection points, so this should be quick enough as long as you only want to determine intersections of triangles but i would not suggest to try to find intersections of arbitrary polygons this way.

Surface subdivision into equal parts

I have a closed contour represented by a list of points and I need to split it into equal parts, knowing the area of the parts.
I think that I can use some subdivision algorithm, like Delanuy subdivision. But with this method I have to give the centroid of the subdivded parts.
Anyone has some hints?
if i understand correctly: given say a rectangle say of area 10, and a target area of 1, you would need to partition rectangle into 10 parts, each having area of 1. So slicing the rectangles into 10 thin rectangles (like guitar frets, or bread slices) would do.
If that's the case, then I would do the following:
Create a function to compute the area of a convex poly. This is fairly trivial (since poly is convex).
Observe, since input poly is convex, any line segment that splits the polygon into two, will intersect the polygon in exactly two places. Specifically, you can triangulate the polygon by picking a vertex of the poly and connecting it to every other vert of the polygon, like a fan.
Triangulating in this fashion would create a partition that would be close to what you need. Assume that the input polygon is given by a vertex list poly = {v1, v2, v3, ..., vn}, where verts are unique and no three are co-linear (convex poly).
Observe that given a triangle of that poly formed by say (v2,v3,v4) we can compute its area, A1. Now if we grow the triangle into a poly by adding one extra vert to the next, say v5, to form (v2, v3, v4, v5) the area increased to A2 (sum of two triangles, (v2,v3,v4) and (v2,v4,v5). Due to linearity if you wanted to grow the original triangle to say A2' where A1 < A2' < A2, you can interpolate on the line segment (v4,v5) to find v4' that will give you the right area A2' that you need.
Since you can compute the total area of initial input poly, and you know the target area of each subdivision, you can cut the input poly into pieces of desired area until you subdivide the entire thing. If you want a nicer partition, you can start from the center of the polygon, i.e. first (seed triangle) would be (center, v1,v2). Then shrink/grow it until desired area, move to the next triangle, repeat.
Hope that makes sense :D

How to efficient extract new polygons form the exist polygons

the polygons image
All of the polygons are simply, there are no holes in them.
board polygon(P0 to P7)
Red polygon (R0 to R6)
Green polygon (G0 G1 P2 G3)
Yellow polygon(Y0 to Y3)
I want to got new four polygons marked as 1 to 4 , polygon 1's coordinates are(J7 J10 R5 R4).
When I use polygon clipping algorithm, I can got the results easy , board diff(red union green union yellow). But when I have more than 10,000 polygons, I need a long time to get my results. My polygons are simply and my result polygons are simply also, there are no holes in the result polygons also.
You know I can find out the four polygons form the image easy using eyes, but how to find them using algorithm.
Thanks.
If all vertices of your computed black polygons do not have more than 2 edges intersecting at the vertex, then there may be a faster way than a more general tool.
Since the number of polygons is on the order of 10000, first try computing the intersection points of all pairs of polygons, and hopefully the number of intersection points is small enough (like 10 million or less). Then, for each intersection point test to see if it is contained in the interior of another polygon (in case you have multiple polygons that jointly overlap). Testing to see if a point is contained in the interior of a polygon can be done quickly, you can read how online. Then, all intersection points that are not contained in another polygon, which note also contains all the original polygon vertices that are not contained in the interior of a polygon, these are the vertices for the "black" polygons you want to compute. These points should be stored with a secondary structure that for each polygon edge, it stores all the stored intersection points along that edge, in sorted order. Similarly, for each stored vertex and intersection point you should store the edges that intersect at that point, and the location of the intersection point in the previous structure. So then pick any stored intersection point that hasn't been used yet in a black polygon, and pick one edge that defines the intersection point. Then you move to the neighboring intersection point along the edge which has the property that the part of the edge between the two intersection points does not pass inside a polygon. Then continue by similarly moving along the other edge that defines the neighboring intersection point. Continue until you reach the vertex you started at; this defines one black polygon. Then you can pick a new unused stored intersection point and repeat. Since your polygons have no holes, this will find all black polygons.

Resources