Procedural urban modeling - polygon subdivision (maybe better ideas?) - c#

Question: How to "divide polygon" to create quads adjacent to the each segment.
My 1st idea: Divide each segment of polygon. Move each newly created point - perpendicular to divided segment. Now we get points for quads. At the end - remove overlapped quads. Questions: How to check if each (new) point of quad is inside polygon? Because the newly created points can go beyond the polygon - specifically on corners. Also how to check overlapped quads?
My 2nd idea: Inset polygon. Divide segments then connect points. But how about more complex polygons where some segments after inset can intersect?
I know this is more a math problem but I'm looking for ready-made solutions for above problems - like simple 2d collision detection of rectangles (but not only one axis aligned).
Maybe someone have better ideas how to create procedural urban parcels?

Do they have to be quads? That is a pretty serious restriction, especially when dealing with arbitrary geometries like in your picture.
For something like this, I would try using Voronoi diagram to partition the space. A Voronoi diagram algorithm takes a set of points as inputs and partitions the space so that each input point is associated with a region of space where all the points inside that region are closest to that input point. For your inputs you could put two sets of points on the interior of your polygon, one set closest to the edge which contains the regions you will use, and the second set of points will be that interior area that you will discard.
Have a look at the Fortune Voronoi implementation in C#.

Related

Finding verticies of a 2D voronoi region defined by edges in a bounded area

(I'm not 100% sure if the title is the best description, I'll edit if necessary)
I'm trying to create a voronoi region to do a split-screen effect in a game. I'm following the steps outlined in this PDF. As I understand them:
Find a line running along the midway point between players
Find the vertices of the intersections of each player's respective lines, bounded by the area in question
Create a region for each player using the convex hull of those vertices.
I found the algorithms for step 3, where I'm stuck is how to find the vertices of each region. Using this image as an example:
Looking at player C, I worked out that I need to find the intersection point of the A/C line, the B/C line and the D/C line. Easy enough. Where I'm stuck is that if a line hits an edge, then I have to find vertices for where it hits an edge, plus any corners in the region (like the bottom left in this image). But I can't just throw the sides of the region in as lines, because with more than 4 players, a region isn't guaranteed to touch the edge of the screen, so those points would need to be discarded and I'm not sure how to factor that into the process.
If it makes any difference, I'm doing this in C# / Unity.
I think it might be beneficial for you to take a look at the wiki article on
Voronoi_diagrams and their dual diagrams, called Delaunay triangulations.
If you can construct a Voronoi diagram, then you can construct its dual Delaunay triangulation and vice versa. The vertices of the Voronoi diagram are the centers of the circles circumscribed around the triangles of the Delaunay triangulation. As such, every Voronoi vertex is the intersection point of the three orthogonal bisectors of its corresponding dual triangle from the Delaunay triangulation.
Particularly, for some specific algorithms, you can check out:
Fortune's algorithm or the dual of Bowyer-Watson algorithm.

c# how to detect intersecting circles as separate from edgepoints

I am trying to create a 2(or more) circles from a list of edgepoints which is sorted. A egdepoint is just a point. A list of edgepoints make the edge of a circle. Drawing a line between the edgepoints gives the black line in the pictures. So there is no radius and circles can vary in size.
It looks like this:
My idea is to split it like picture 2. Next, create circles like in this article. Ofcourse with the fist, middle and last point.
I created a method to detect whether the edgepoints are sorted clockwise or counter clockwise. Unfortunately I am stuck on how to detect these "split points" The picture can be rotated ofcourse.
The result should be 2(or more) list with edgepoints:
So how can I detect these "split points"? Or is there a better way to detect intersecting circles as separate?
Input: Something like Point[]. Output: Something like List[Circle]
Assume input is sorted by position around the outer edge of some picture that is made up of overlapping circles. Any points in the interior of the picture are not included.
I thought about it more and I think you can find the points easier if you consider slope. Points where the slope varies wildly are the points you are looking for.
[Revised thought - Find the transition points first, then the circles.]
Start by using a function to calculate the slope of a line segment between two points. As you go around a circle, you will have a reasonable change in slope (you will have to discover this by reviewing how close the points are together). Say you have points like { A, B, C, D, ...}. Compute the slope of A->B and B->C. If the points are evenly spaced, that difference or the average difference might be a tolerance (you have to be careful of transition points here - maybe compute an average over the entire set of points). If at some point the slope of K->L and L->M is very different from J->K and K->L then record that index as a transition point. Once you have traversed the whole set (include a test for Y->Z and Z->A as well if it is a closed shape), the recorded indexes should define the transition points. Use the mid-point of each segment as the third point for each circle. (e.g. if you identified I and M as transition points, then use I, K, and M to define a circle).
[Original thought - find the circles first]
Use the referenced article to determine the center of a circle based on three points. Then determine if it is really an interesting circle by testing some of the points around the reference points. (Say, pick every 5th or 10th point then verify with all the interior points). With more overlapping circles, this becomes a less effective process so you will have to define the algorithm carefully. Once you get all the reference circles, process through all of the edge points (assuming these are points on the exterior of the drawing). Using center, radius, a distance formula, and a tolerance, determine which points are on which circle. Points that fit the tolerance on more than one circle are the points you are looking for I think.

Find if one Polygon is inside another

I want to find out if one polygon is inside another by giving an array of points of each vertex. Is there any simple way to do that?
Edit: it's not enough to check whether minimum point of inner is greater than outer and maximum point for outer is less then inner. It's not the sufficient condition. Proof:
Once you've checked that the minimum bounding box for polygon A lies inside that for polygon B I think you're going to have to check each edge of A for non-intersection with all the edges of B.
This is, I think, a simple approach, but I suspect you really want a clever approach which is more efficient.
I have done something very similar using Java2D particularly the Area class. The code for that class is freely available if you want to replicate the functionality. An easier option might be to look at this library: http://www.cs.man.ac.uk/~toby/alan/software/ It should allow you to do what you want or give you starting points anyway.
some point of polygon1 lies inside of polygon2
you can use ray casting here
there are no edge-edge intersection between polygons
for large numbers of edges space-partition trees may increase speed, for small number of edges N*M enumeration is OK
First, use axis-aligned boundary boxes to see if they're anywhere near one another. (Essentially, draw an X-Y aligned box around each one and see if they are intersecting. This is MUCH easier than the case for polygons and generally saves a lot of time.)
If the boxes intersect, you should now perform detailed intersection testing. You'll want to draw a line perpendicular to each side of the "outside" polygon and project all of the points from both of them onto the line. Then, check that the resulting points for the inside polygon are between the points projected from the outside polygon.
I understand that example is difficult to visualize at first- I recommend this tutorial about collision detection to people interested in this area:
http://www.wildbunny.co.uk/blog/2011/04/20/collision-detection-for-dummies/
However, your task is slightly different as mentioned because you are projecting onto the perpendicular line for each side and you need ALL of them to contain the segment. I also suggest boning up a bit on the notion of a projection and your linear algebra if you want to do a lot of this.
Your question is underdetermined - just giving the coordinates of each vertex is not enough to specify a polygon. Example: draw a square and fill in the diagonals. Your five vertices are the square's corners and the point at the diagonals' intersection. From these vertices, it is possible to construct four different polygons: each one is constructed by using the edges of the original drawing, while removing one single edge from the square and limiting the diagonals (I hope this is clear enough).
EDIT: Apparently it wasn't clear enough. Let a1, a2, a3, a4 be vertices corresponding to the four points of a square (say, clockwise from top left), and let a5 be a vertex corresponding to the intersection of the square's diagonals. Just for the sake of the example, here are two polygons which fit the above vertices:
1. (a1,a2),(a2,a5),(a5,a3),(a3,a4),(a4,a1). This should look like a right-facing pacman.
2. (a1,a2),(a2,a3),(a3,a4),(a4,a5),(a5,a1). This should look like a left-facing pacman.

Outer Bounding Points of Image/Shape using C#

I have some images that I'd like to draw a polyon around the outer edges. The images themselves are on transparent backgrounds and I've created an array of the pixels in the images which contain a point and are not transparent (or white).
Now, my question is: how do I draw an accurate polygon around the outer edge points? I've used a Graham Scan algorithm that I read about to create a convex hull around the edges but this doesn't seem to work for objects with concavities. For example:
http://i48.tinypic.com/4s0lna.png
The image on the left gets filled in using this method with the one on the right. As you can see, it's 'filling in' a little too much.
I assume there must be some other algorithm or approach that can be used to solve this, but I'm not sure of where to look or what it might be called. Could anyone point me in the right direction? I'm using C#/.net and hopefully there might be something that already exists which could work along these lines.
I think the 2D "Alpha shapes" algorithm would the right choice for you.
http://www.cgal.org/Manual/latest/doc_html/cgal_manual/Alpha_shapes_2/Chapter_main.html
Alpha shapes can be considered as a generalization for the "convex Hull" algorithm that allows for generation of more general shapes.
By using alpha shapes you will be having control over the level of details to be captured by the resultant shape by changing the alpha parameter value.
You can try the java applet here : http://cgm.cs.mcgill.ca/~godfried/teaching/projects97/belair/alpha.html
to have better understanding about does this algorithm do.
You can start on a pixel by pixel level, using a flood-fill approach.
Start in the corner, checking that it does have zero alpha.
Check the neighbours for zero alpha and iterate until we have no unchecked neighhours.
This gives you a mask for the image which will consist of two simply connected regions, the interior and exterior.
The set you seek then consists of:
all the points in the exterior which are on the boundary of the interior.
You can then turn that into a polygon by:
Take an initial polygon that consists of all the points in the edge set
Remove redundant vertices that lie along straight edges.

Finding Remote Points in 2D

I have a set of points on the infinite (well, double precision) 2D plane.
Given the convex hull for this set, how can find some points on the inside of the convex hull that are relatively far away from all the points in the input set?
In the image below, the black points are part of the original set and the hatched area represents the space taken up by all the points if we "grow" them with radius R.
The orange points are examples of what I'd like to get. It doesn't really matter where exactly they are, as long as they are relatively far away from all the black points.
Furthest Point Search http://en.wiki.mcneel.com/content/upload/images/point_far_search.png
Update: Using a delaunay algorithm to find large empty triangles seems to be a great approach for this:
Delaunay Solution http://en.wiki.mcneel.com/content/upload/images/DelaunaySolutionToInternalFurthestPoints.png
This is a good example of a problem that may be solved using KD-Trees... there are some good notes in Numerical Recipes 3rd Addition.
If you are trying to find point locations that are relatively isolated... maybe the center of the largest quad elements would be a good candidate.
The complexity would be O(n log^2 n) for creating the KD-Tree... and creating a sorted list of quad sizes would be O(n Log n). Seems reasonable for even a large number of points (of course, depending on your requirements).
This is a naive algorithm:
Get the list of points within the convex shape.
Of those, find the minimum distance to any other point.
Rank all points by their respective R values
Select the top x points.
For (2), thinking of this as a radius search still means you end up calculating the distance from each point to each other point, because finding out whether a point lies within a given radius of another point is the same thing as finding the distance between the points.
To optimize the search, you can divide the space into a grid, and assign each point to a grid location. Then, your search for (2) above would first check within the same square and the surrounding 8 squares. If the minimum distance to another point is within the same square, return that value. If it is from one of the 8 and the distance is such that a point outside the 9 could be closer, you have to then check the next outline of grid locations outside those 9 for any closer than those found within the 9. Rinse/repeat.

Categories

Resources