algorithm for optimal subdivision (i.e. tessellation / partitioning) of 2d polygons into smaller polygons? - algorithm

I've got some 2D polygons, each as a list of clockwise coordinates. The polygons are
simple (i.e. they may be concave but they don't intersect themselves) and they don't overlap eachother.
I need to subdivide these polygons into smaller polygons to fit a size constraint. Just like the original polygons, the smaller ones should be simple (non-self-intersecting) and the constraint is they should each fit within one 'unit square' (which, for sake of simplicity, I can assume to be 1x1).
The thing is, I need to do this as efficiently as possible, where 'efficient' means the lowest number of resulting (small) polygons possible. Computation time is not important.
Is there some smart algorithm for this? At first I thought about recursively subdividing each polygon (splitting it in half, either horizontally or vertically whichever direction is larger) which works, but I don't seem to get very optimal results with this. Any ideas?

Draw a circle with a center of one of the initial points of initial polygon and radius of your desired length constraint.
The circle will intersect at least two lines at two points. Now you have your first triangle by the biggest as possible. Then choose those intersections as next target. Do until there is no initial points left outside. You have your triangles as large as possible(so as few as possible)
Do not account the already-created triangle edges as an intersection point.
Resulting polygons are not always triangle, they can be quads too. Maybe larger point-numbers too!
They all just nearly equal to the desired size.
Fine-tuning the interior parts would need some calculation.

I suggest you use the following:
Triangulate the polygon, e.g. using a sweep line algorithm.
Make sure all the triangles do not violate the constraint. If one violates the constraint, first try edge-flips to fix it, otherwise subdivide on the longest edge.
Use dynamic programming to join the triangles, while maintaining the constraint and only joining adjacent polygons.

Related

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.

Can one polygon be transformed into another using only parallel translation and proportional scaling?

At the entrance, two polygons are given (the coordinates of the vertices of these polygons are listed in the order of their traversal; however, the traversal order for different polygon angles can be chosen different). Can one polygon be transformed into another using only parallel translation and proportional scaling?
I have following idea
So, find some common peak for two polygons and make the transfer of one polygon so that these vertices lie on one point then Scaling so that the neighboring point matches the corresponding point of another polygon, but I think it's wrong , at least I can't write it in code
Is there some special formula or theorem for this problem?
I would solve it like this.
Find the necessary parallel transport.
Find the necessary scaling.
See if they are the same polygon now.
So to start take the vertex that it farthest to the left, and if there is a tie, the one that is farthest down. Find that for both polygons. Use parallel transport to put that vertex at the origin for both.
Now take the vertex that is farthest to the right, and if there is a tie, the one that is farthest up. Find that for both polygons. If it is not at the same slope, then they are different. If it is, then scale one so that the points match.
Now see if all of the points match. If not, they are different. Otherwise the answer is yes.
Compute the axis-aligned bounding boxes of the two polygons.
If the aspect ratios do not match, the answer is negative. Otherwise the ratio of corresponding sides is your scaling factor. The translation is obtained by linking the top left corners and the transformation equations are
X = s.(x - xtl) + Xtl
Y = s.(y - ytl) + Ytl
where s is the scaling factor and (xtl, ytl), (Xtl, Ytl) are the corners.
Now choose a vertex of the first polygon, predict the coordinates in the other and find the matching vertex. If you can't, the answer is negative. Otherwise, you can compare the remaining vertices*.
*I assume that the polygons do not have overlapping vertices. If they can have arbitrary self-overlaps, I guess that you have to try matching all vertices, with all cyclic permutations.

Is there an algorithm to reduce the sides of a Polygon while keeping all Points within the Polygon?

I'm trying to reduce a polygon with 4+ vertexes to a polygon with 4 sides to perform perspective transformation later on. I need to find the polygon with 4 sides which contains all the points the original polygon had. Basicly what i want is something like this:
The real problem here is that the polygon must only get bigger... if it gets smaller with let's say a polygon approximation algorithm it's not usefull anymore...
EDIT:
I need the optimal solution, that means that the resulting 4-sided polygon has as little area as possible!
EDIT2:
What would also work is an convex hull algorithm where I can determine the number of sides the resulting polygon must have!
The easiest solution is to take the bounding box of your polygon, the rectangle defined by the min and max of the x values of your vertices, and the min and max of the y values.
If you need a 4-vertex polygon with smaller area, an idea could be:
Take the convex hull of your polygon.
Select one side for deletion, and extend its neighboring sides to the point where they meet. Do this only if they really meet at the end where the deleted side was. Maybe you want to select the side to be deleted by the smallest area that this deletion adds to the polygon (that's the triangle formed by the deleted side and the new intersection point).
Repeat until only 4 sides are left.

Area of Intersection of Two Rotated Rectangles

I have two 2D rectangles, defined as an origin (x,y) a size (height, width) and an angle of rotation (0-360°). I can guarantee that both rectangles are the same size.
I need to calculate the approximate area of intersection of these two rectangles.
The calculation does not need to be exact, although it can be. I will be comparing the result with other areas of intersection to determine the largest area of intersection in a set of rectangles, so it only needs to be accurate relative to other computations of the same algorithm.
I thought about using the area of the bounding box of the intersected region, but I'm having trouble getting the vertices of the intersected region because of all of the different possible cases:
I'm writing this program in Objective-C in the Cocoa framework, for what it's worth, so if anyone knows any shortcuts using NSBezierPath or something you're welcome to suggest that too.
To supplement the other answers, your problem is an instance of line clipping, a topic heavily studied in computer graphics, and for which there are many algorithms available.
If you rotate your coordinate system so that one rectangle has a horizontal edge, then the problem is exactly line clipping from there on.
You could start at the Wikipedia article on the topic, and investigate from there.
A simple algorithm that will give an approximate answer is sampling.
Divide one of your rectangles up into grids of small squares. For each intersection point, check if that point is inside the other rectangle. The number of points that lie inside the other rectangle will be a fairly good approximation to the area of the overlapping region. Increasing the density of points will increase the accuracy of the calculation, at the cost of performance.
In any case, computing the exact intersection polygon of two convex polygons is an easy task, since any convex polygon can be seen as an intersection of half-planes. "Sequential cutting" does the job.
Choose one rectangle (any) as the cutting rectangle. Iterate through the sides of the cutting rectangle, one by one. Cut the second rectangle by the line that contains the current side of the cutting rectangle and discard everything that lies in the "outer" half-plane.
Once you finish iterating through all cutting sides, what remains of the other rectangle is the result.
You can actually compute the exact area.
Make one polygon out of the two rectangles. See this question (especially this answer), or use the gpc library.
Find the area of this polygon. See here.
The shared area is
area of rectangle 1 + area of rectangle 2 - area of aggregated polygon
Take each line segment of each rectangle and see if they intersect. There will be several possibilities:
If none intersect - shared area is zero - unless all points of one are inside the other. In that case the shared area is the area of the smaller one.
a If two consecutive edges of one rectactangle intersect with a single edge of another rectangle, this forms a triangle. Compute its area.
b. If the edges are not consequtive, this forms a quadrilateral. Compute a line from two opposite corners of the quadrilateral, this makes two triangles. Compute the area of each and sum.
If two edges of one intersect with two edges of another, then you will have a quadrilateral. Compute as in 2b.
If each edge of one intersects with each edge of the other, you will have an octagon. Break it up into triangles ( e.g. draw a ray from one vertex to each other vertex to make 4 triangles )
#edit: I have a more general solution.
Check the special case in 1.
Then start with any intersecting vertex, and follow the edges from there to any other intersection point until you are back to the first intersecting vertex. This forms a convex polygon. draw a ray from the first vertex to each opposite vetex ( e.g. skip the vertex to the left and right. ) This will divide it into a bunch of triangles. compute the area for each and sum.
A brute-force-ish way:
take all points from the set of [corners of
rectangles] + [points of intersection of edges]
remove the points that are not inside or on the edge of both rectangles.
Now You have corners of intersection. Note that the intersection is convex.
sort the remaining points by angle between arbitrary point from the set, arbitrary other point, and the given point.
Now You have the points of intersection in order.
calculate area the usual way (by cross product)
.

How to calculate the area of multiple polygons?

I posted some days ago this question: How to intersect multiple polygons?. Now I implemented a sweep line algorithm as recommended (concrete the one from Martinez, Rueda and Feito).
The result is a set of polygons that do not overlap. But these polygons can contain each other (holes) or touch the boundaries (being a hole or an island polygon).
A picture of what I mean:
I think this should cover all the special cases; intersections are handled by the sweep line algorithm.
Now I need the area of the polygons (marked gray). My first idea was to add polygon by polygon and to check if they contain each other and use some intelligent selection mechanism to only select the needed polygons. But this generates some O(n^2) algorithm: For each polygon to process, every edge has to be compared to every edge that is already processed.
Not that good. Can you give me a hint how to calculate the total area?
The standard vertex order is counterclockwise for polygons and clockwise for holes. If you store your data using this convention, just compute the area with the standard polygon area calculation method. Areas of the holes will be negative.
If you have them in some other order, then you have a problem. Better fix it now.

Resources