How to draw an outline of a group of multiple rectangles? - objective-c

I need to draw an enclosing polygon of a group of rectangles that are placed next to each other.
Let's think of text fields that share at least one edge (or part of it) with at least one of the other rectangles.
I can get the rectangles points coordinates, and so I basically have any data I need about them.
Can you think of a simple algorithm / procedure to draw a polygon (connected straight paths) around these objects.
Here's a demonstration of different potential cases (A, B, C, etc...). In example A I also drew a blue polygon which is the path that I need to draw, outlining the group of rectangles.
I've read here about convex hull and stuff like that but really, this looks like a far simpler problem.
One (beginning of) solution I thought of was that the points I actually need to draw through are only ones that are not shared by any pair of rectangles, meaning points that are vertices of more than one rectangle are redundant. What I couldn't find out was the order by which I need to draw lines from one to the next.
I currently work on objective c, but any other language or algo would be appreciated, including pseudo.
Thanks!

IMHO it should be like this. Make a list of edged and see if some are overlaying: This should be simple if the rectangles are aligned with the x,y axis. You just find the edges that have the vertexes on the same x or y and the other coordinates need to be in between. After this the remaining edges should form the outline.
Another method to find common edges is to break all rectangles along each x and y axis where you have vertices. This should look as if you are growing all lines to infinity. After this all common edges will have common vertices and can be eliminated.

You have two rows, and three different y-values. Let's say y0 is the top of the thing, y2 is the bottom end, and y1 marks the middle between both rows.
Each row has a maximum and a minimum x-value, let's say the top-row goes from x0_min to x0_max, and the bottom row from x2_min to x2_max. Given those values you just draw around the thing:
(x0_min,y0)->
(x0_max,y0)->
(x0_max,y1)->
(x2_max,y1)->
(x2_max,y2)->
(x2_min,y2)->
(x2_min,y1)->
(x0_min,y1)->
(x0_min,y0)

Related

Matplotlib Polygon gets fill outside of polygon

I have a collection of polygons, created with scipy.spatial.Voronoi (specifically, a subset of the Voronoi regions), which I'd like to plot with matplotlib. However, it seems like there are some constraints on the vertex order of the matplotlib polygons, since some of the polygons end up with the fill on the outside of the polygon rather than the inside. In these cases, reversing the order the vertices are specified seems to fix the problem, so it seems to me like a winding issue (even if the docs don't mention anything like this).
However, since some polygons are in the right order and some are in the wrong order, I can't just reverse all the vertex lists, so is there a way I can detect the incorrectly wound lists and fix only those or alternatively a way to get matplotlib to do the equivalent thing automatically?
ImportanceOfBeingErnest's comment put me on the right track, which in turn led me to How to determine if a list of polygon points are in clockwise order?. Basically, we find the bottom-rightmost point in the polygon P, the point A before P, and the point B after P. The sign of the cross product AP x PB gives the winding: positive in case of CCW winding and negative for CW winding.

How to get non-intersection region of CGRect with multiple intersects?

I have one main (red) rectangle and several other rectangles, which intersect main rectangle randomly.
How can I get non-intersection area of main rectangle (red area)?
This depends very much on what you mean by "have" and "get". What are the input and output formats? Do you want a sequence of points, or just the area? Is this for a general solution, or just this simplified case?
For a fast, general solution, I highly recommend the BOOST polygon library (disclosure: I was one reviewer for the BOOST conference presentation). This handles arbitrary polygons, including holes, and does a lovely job of all the basic polygon operations.
A simple polygon is a sequence of points. You can make sets of polygons. For this case, declare all of your polygons; put the red rectangle into set A, the gray ones into set B. Then A-B returns the desired displayed polygon.

Computing Minkowski Difference For Circles and Convex Polygons

I'm needing to implement a Minkowski sum function that can return the Minkowski sum of either 2 circles, 2 convex polygons or a circle and a convex polygon. I found this thread that explained how to do this for convex polygons, but I'm not sure how to do this for a circle and polygon. Also, how would I even represent the answer?! I'd like the algorithm to run in O(n) time but beggars can't be choosers.
Circle is trivial -- just add the center points, and add the radii. Circle + ConvexPoly is nearly as simple: move each segment perpendicularly outward by the circle radius, and connect adjacent segments with circular arcs centered at the original poly vertices. Translate the whole by the circle center point.
As for how you represent the answer: Well, it depends on what you want to do with it. You could convert it to a NURBS if you just want to draw it with a vector drawing library. You could approximate the circular arcs with polylines if you just want a polygonal approximation. Or you might store it as is -- "this polygon, expanded by such-and-such a radius". That would be the best choice for things like raycasting, for instance. Or as a compromise, you could connect adjacent segments linearly instead of with circular arcs, and store it as the union of the (new) convex polygon and a list of circles at the vertices.
Oh, about ConvexPoly + ConvexPoly. That's the trickiest one, but still straightforward. The basic idea is that you take the list of segment vectors for each polygon (starting from some particular extremal point, like the point on each poly with the lowest X coordinate), then merge the two lists together, keeping it sorted by angle. Sum the two points you started with, then apply each vector from the merged vector list to produce the other points.

Looking for an efficient structure for checking which circles enclose a point

I have a large set of overlapping circles each at a random location with a specific radius.
type Circle =
struct
val x: float
val y: float
val radius: float
end
Given a new point with type
type Point =
struct
val x: float
val y: float
end
I would like to know which circles in my set enclose the new point. A linear search is trivial. I'm looking for a structure that can hold the circles and return the enclosing circles with better than O(N) for the presented point.
Ideally the structure should be fast for insertion of new circles and removal of circles as well.
I would like to implement this in F# but ideas in any language are fine.
For your information I'm looking to implement
http://takisword.wordpress.com/2009/08/13/bowyerwatson-algorithm/
but it would be an O(N^2) if I use the naive approach of scanning all circles for every new point.
If we assume that circles are distributed over some rectangle with area 1 and the average area of a circle is a then a quadtree with m levels will leave you with an area with size 1/2^m. This leaves
O(Na/2^m)
as the expected number of circles left in the remaining area.
However, we have done O(log(m)) comparisons to get to this point. This leaves the total number of comparisons as
O(log(m)) + O(N/2^m)
The second term will be constant if log(m) is proportional to N.
This suggests that a quadtree can cut things down to O(log n)
Quadtree is a structure for efficient plane search. You can use it to hold subdivision of the plane.
For example you can create quad tree with such properties:
1. Every cell of quadtree contains indices of circles, overlapping it.
2. Every cell does contain not more than K circles (for example 10) // may be broken
3. Height of tree is bounded by M (usually O(log n))
You can construct quadtree, by iterating overlapped cells, and if number of circles inside cell exceedes K, then subdivide that cell into four (if not exceeding max height). Also something should be considered in case of cell inside circles, because its subdivision is pointless.
When finding circles you should localise quadtree, then iterate through overlapping circles and find, those which contains point.
In case of sparse circle distribution search will be very efficient.
I have a bachelor thesis, where I adapted quadtree, for closest segment location, with expected time O(log n), I think similar approach could be used here
Actually you search for triangles whose circumcircles include the new point p. Thus your Delaunay triangulation is already the data structure you need: First search for the triangle t which includes p (google for 'delaunay walk'). The circumcircle of t certainly includes p. Then start from t and grow the (connected) area of triangles whose circumcircles include p.
Implementing it in a fast an reliable way is a lot of work. Unless you want to create a new library you may want to use an existing one. My approach for C++ is Fade2D [1] but there are also many others, it depends on your specific needs.
[1] http://www.geom.at/fade2d/html/

Calculating total coverage area of a union of polygons

I have a number of 2D (possibly intersecting) polygons which I rendered using OpenGL ES on the screen. All the polygons are completely contained within the screen. What is the most timely way to find the percentage area of the union of these polygons to the total screen area? Timeliness is required as I have a requirement for the coverage area to be immediately updated whenever a polygon is shifted.
Currently, I am representing each polygon as a 2D array of booleans. Using a point-in-polygon function (from a geometry package), I sample each point (x,y) on the screen to check if it belongs to the polygon, and set polygon[x][y] = true if so, false otherwise.
After doing that to all the polygons in the screen, I loop through all the screen pixels again, and check through each polygon array, counting that pixel as "covered" if any polygon has its polygon[x][y] value set to true.
This works, but the performance is not ideal as the number of polygons increases. Are there any better ways to do this, using open-source libraries if possible? I thought of:
(1) Unioning the polygons to get one or more non-overlapping polygons. Then compute the area of each polygon using the standard area-of-polygon formula. Then sum them up. Not sure how to get this to work?
(2) Using OpenGL somehow. Imagine that I am rendering all these polygons with a single color. Is it possible to count the number of pixels on the screen buffer with that certain color? This would really sound like a nice solution.
Any efficient means for doing this?
If you know background color and all polygons have other colors, you can read all pixels from framebuffer glReadPixels() and simply count all pixels that have color different than background.
If first condition is not met you may consider creating custom framebuffer and render all polygons with the same color (For example (0.0, 0.0, 0.0) for backgruond and (1.0, 0.0, 0.0) for polygons). Next, read resulting framebuffer and calculate mean of red color across the whole screen.
If you want to get non-overlapping polygons, you can run a line intersection algorithm. A simple variant is the Bentley–Ottmann algorithm, but even faster algorithms of O(n log n + k) (with n vertices and k crossings) are possible.
Given a line intersection, you can unify two polygons by constructing a vertex connecting both polygons on the intersection point. Then you follow the vertices of one of the polygons inside of the other polygon (you can determine the direction you have to go in using your point-in-polygon function), and remove all vertices and edges until you reach the outside of the polygon. There you repair the polygon by creating a new vertex on the second intersection of the two polygons.
Unless I'm mistaken, this can run in O(n log n + k * p) time where p is the maximum overlap of the polygons.
After unification of the polygons you can use an ordinary area function to calculate the exact area of the polygons.
I think that attempt to calculate area of polygons with number of pixels is too complicated and sometimes inaccurate. You can see something similar in stackoverflow answer about calculation the area covered by a polygon and if you construct regular polygons see area of a regular polygon ,