REWRITE: I wasn't getting much feedback on this question, I assume I did not write it properly and am attempting to clarify.
I am making a program that lets people created countries. The thick red lines in the picture below are the borders to said countries. I am trying to figure out how to generate a polygon that will fill the entire area inside of the "border" lines. I have the triangulation code that accepts the polygons working - I tested that out with a polygon I entered manually - now I'm trying to figure out how to generate the polygon from the lines/linked point.
For more info - all the red lines are how the yellow dots are linked together. The users drag the yellow dots together to link the lines. It is possible for the polygon to have a hole inside and be open - what I am trying to do is make code that handles open polygons and polygons with holes inside it and generates an output of all the yellow dot's locations (vector3's with x and z as it lies at 0 on the y plane) for my triangulation code.
I'm still looking up way to figure this out but I haven't come up with even where to start looking for solutions. Thanks for all the help.
OLD QUESTION BELOW
I'm trying to find a way to link points together to form an internal polygon. Basically, I'm creating a program that lets people link lines together. After a closed polygon is made, it is supposed to generate a new polygon object inside the lines.
I'm not too sure how to do this - I have made it so they can generate the lines and link them together, but how to do a closed polygon escapes me. I looked at convex hulls but this isn't the same, and tried looking or thinking up a few different things that don't seem to work. I'm curious if anyone can point me in the write direction/a tutorial or idea on how to continue on my creation.
I have two pictures uploaded to help show my point.
Above is what I am trying to do but not too sure how - basically, when the user finished a closed polygon (all the yellow dots are the polygon's external points), I want it to generate an internal polygon (marked by the black 1, 2 and 3).
You may be interessted in Polylines. This could help you to prevent lots of research on graph theory. Like the Polygon class, you can fill a Polyline object. The documentation says:
This object is similar to the Polyline object, except that this object must be a closed shape.
Since you want your shape to be "open", this could help you.
And the linked manual page even includes an example of how to create the Polyline programmatically:
// Add the Polyline Element
myPolyline = new Polyline();
myPolyline.Stroke = System.Windows.Media.Brushes.SlateGray;
myPolyline.StrokeThickness = 2;
myPolyline.FillRule = FillRule.EvenOdd;
System.Windows.Point Point4 = new System.Windows.Point(1, 50);
System.Windows.Point Point5 = new System.Windows.Point(10, 80);
System.Windows.Point Point6 = new System.Windows.Point(20, 40);
PointCollection myPointCollection2 = new PointCollection();
myPointCollection2.Add(Point4);
myPointCollection2.Add(Point5);
myPointCollection2.Add(Point6);
myPolyline.Points = myPointCollection2;
myGrid.Children.Add(myPolyline);
Your second requirement is, that your shape can have "holes".
Notice, that you don't have to take care of filling the Polyline. By setting myPolyline.FillRule you can have "holes" inside of your shape. See the Polyline.FillRule page on MSDN, which shows:
If you have further wishes on how to make "holes", have a look at the Geometry.Combine Method and especially the GeometryCombineMode.
An example that demonstrates GeometryCombineModes...
Have fun : )
Pictures and code are example content, provided by Microsoft and were extracted from MSDN. Please take care of the copyrights, which are available through the given links, when reusing it. For using those contents here, I want to refer to the Microsoft Limited Public License.
What about a derivative of Marching Quads? you could have something like this :
for each three points (grouped in creation order inside of the mesh) find the center of the polygon and let the user assign a bool value to it which will define if this polygon is inside or outside the mesh and then draw it or not
You can't create an open polygon. It's only becomes a polygon when it's closed. But, here is an approach that might serve your needs.
Create a closed polygon by connecting all of the available lines, and then calculate the final line that links the starting point with the end point while it's in an intermediate state.
Then,
Draw (not fill) the polygon with a different color than the
background.
Draw the final calculated line with the background color so it disappears.
That approach, or a modified version, will create the illusion of an open polygon.
Commenter #SamyS.Rathore is right. If your question is "How do I find the closed areas (polygons) in a planar graph given its vertices and edges?" then you want to look into Simple Circle algorithms like https://stackoverflow.com/a/14115627/642532 there.
However after finding those circles additional work is required to support holes. Basically what you want to do is to detect wether a polygon is inside another one and then geometrically subtract it.
Simple Circles doesn't deal with partially opened areas. But that shouldn't be a problem in your case, because those areas can only exist at the outer borders of the playing field and the user can easily close them at will.
I got this done by taking every point and linking it to a class that had a base vector3 that was the location of the point, as well as every linked line that went out from it. Basically.
class DoubleV3
Vector3 MiddleVector
List LinkedVectors
I also take care of people having accidentally or purposefully put the same entries multiple times right now by remove all redundant lines.
After that I go through the entire thing and check every doubleV3's linked vectors, I go from every linkedvector to the left-most vector beyond it (basically, I check the last vector and next vector of every linkedvectors list to a north vector 1 up from the middle and take the smallest angle). This gives me a bunch of closed polygons (yes, I know now the proper term is cycle, I now use that). This deals with open cycles (which I do not want). It won't deal with complex cycles that come from overlapping lines, but I deal with that in another method.
After that I simply remove all duplicate polygons and check to make sure no polygon in inside another (I also throw out all internal cycles that aren't part of the outer hull).
Thanks everyone for helping me ^.^ This is how I ended up doing it in case anyone else is in my situation.
Related
Part 1: Forgive me if the question itself is unclear. I am learning how to use Unity and script in C#, and I want to know if there's a way to apply a gradient of color (or an image) utilizing the game objects that already exist as the places where the gradient will show up.
Say I have a group of these circles that randomly grow and change size during the game run.
Example image of circles
I am not sure of the correct terminology, but a couple of words come to mind, i.e. shader/mask. My goal is to display the gradient/image only within where the game objects exist. So instead of white circles, it's circles display parts of the one singular image/gradient.
Part 2:
To take a it a step further, I'd like to know how to have the gradient continuously run through its spectrum so one can see the colors shift across the circles.
Again, still very new to this kind of stuff, but would anyone know what steps I would need to take to get there.
Thanks!
I have a directed closed path consisting of (cubic) bezier curves and lines, which represents a pen stroke. When I oversimplify it, it can look something like this:
In the end, I need to get the shape outline. I can recognize inner path cycles (highlighted in red in second picture above), but can't determine if they represent a hole in the shape or not. What I've been doing so far is getting a point inside the inner cycle and computing it's winding number (using the nonzero-rule) and for the most cases it turns out pretty well.
This is not the case though. No matter in which direction I cast the ray from the little inner cycle, the winding number sum is always (correctly) zero, indicating there's a hole where there should be instinctively none. Two examples:
What could probably help is that I can distinguish between both sides of the pen stroke, meaning I can recognize it's start and end (yellow-orange lines) and side paths (green and blue).
I can think of some ways this could help. For example crossing the same path (green) twice and not meeting it's counterpart (blue) twice indicates that the point I'm testing lies inside the pen stroke and that I can safely remove the inner cycle inside which it lies (unless it lies inside multiple inner cycles at once, but that doesn't happen in my case). What if I don't meet the blue counterpart, but the yellow line instead - what then?
Question: Is there any way I could determine that the little cycle is "inside" the pen stroke? If I'm able to do this, I can get the correct shape outline and later possibly fill the pen stroke.
Just to be clear, when you imagine the pen stroke filled, the should be only one hole, not two, as the nonzero winding rule suggests.
Thank you.
I got points on a map and lines connecting those points.
How do I get all independent inner polygons that are formed?
The linked picture describes the problem.
http://i.imgur.com/0LdA3ji.jpg
I'm supposing I need a tree search algorithm that enumerates all the points and connecting lines in a tree structure and then searches for cycles but this job is kinda over my head.
In a perfect world the example would be in C#.)
I found:
Finding all cycles in undirected graphs
but it does not mark independent polygons. It finds all possible polygons even overlapping ones.
I'm using google maps. The use case is: I detect clicks on map and draw points. I detect click on points and then get lines between points. Now I need to automaticaly generate polygons from the lines and points. Sure I can draw polygons. I just dont know which ones (what coordinates - or rather: what points to choose for a polygon)
I actually have no experience in graphics and how to actually colour a polygon once you've found it, but assuming:
You have the polygons themselves.
They do not patialy overlap or any other weird behaviour.
Then the colouring pseudo code could go something like this:
while listOfPolygons is not empty
temp <- find smallest polygon in listOfPolygons
colour temp
remove from listOfPolygons all polygons containing temp
remove temp from listOfPolygons
Notice that the part about finding the containing polygons might be tricky.
Edit:
Checking if polygon A is in polygon B can be done by checking if any corner (vertex?) of A is located inside B.
I need to arrange tooltips for points that are located on a complex 2D shape.
The tooltips have different sizes
They must not obscure the shape itself
The lines that connect the tooltip to the points should not cross one each other.
The tooltip should be as mush closer to the point it belongs to.
I've tried several searches in google but nothing was close enough to what I need.
You've asked quite a doozy. I haven't personally worked on something like this, another SO member will likely be able to give you a complete solution. However, here are some points to consider when finding your solution.
1. The tooltips have different sizes
You will need a way determining this independently of your shape location algorythm. Performing the re-size as part of step 2 would make things much more complicated and may result in inconsistent behavior. So firstly, look into generating the dimensions of your tooltips.
2. They must not obscure the shape itself
In principle, you want a solution where the tooltip is not 'colliding' 'inside' the complex shape. Looking up '2d shape collision detection' would help here. You will need to know the dimensions of the shape of interest. You can't use a picture of a shape (unless you use a map of some sort). Most algorythms will require the following information for shapes containing concave points:
The points (2d vectors) that make up the complex shape
The points from which tooltips "spawn"
The tooltip dimensions (see point 1)
3. The lines that that connect the tooltip to a point should not cross eachover
This makes the problem significantly more complicated because it implies that multiple tooltips generated by #2 may be visible at the same time which will introduce alot of complexity.
Now you have N tooltips which need N locations occupying different areas which may not overlap, collide with the complex shape, or, when a line is drawn from them to point x, does not intersect any other lines from the remaining (N-1) shapes. It means the algorthm must be performed on the entire set and find the correct locations for all of them, a kind of three body problem.
4. The tooltip must be as close as possible to its associated point
This adds another small caveat which, because of stipulations set in #3 may not be able to be met 'ideally' (what if two shapes are colliding near two close points, which one 'wins out'?).
Again, these are some points to consider as you generate a solution. The result is that you have mathematically 'ideal' locations for your tooltips. However, with these considerations in mind, you may want to look into where realistic concessions may be made. If it's for a design project where the complex shape is unlikely to change then semimanual solutions may be better. If it's for a complex piece of software that will require automatically generated locations you may be able to redesign the UI to give the user the necessary feedback without such a complex solution.
A heuristic:
Compute the centroid of the points.
Place a circle, centered at the centroid, fully enclosing the shape.
Find the places on the circle, where a line form the center through each point
intersects the circle, i.e. project the points on the the circle.
These locations would serve as corners for the tooltip, depending on the which quadrant the point on the circle is, relative to the circle center.
You may increase the circle radius a bit, for aesthetic purposes :)
If I'm not mistaken, this should cover requirements (1), (2) and (3). For (4) you can refine the initial place by moving the tooltip towards the sphere center and checking for intersection with the shape, e.g. using binary search.
Something like this:
There are problems with this approach, of course, but nevertheless it may turn out to be a good starting point for refinement :)
So I am working on a Risk type game in XNA/C#. I have a map, similar this one, and I need to be able to detect mouseovers on each territory (number). If these areas were squares, it would be easy, as they could each be represented by a rectangle. However, they are different size polygons. Is there a polygon shape that behaves similar to a square? If there isn't, how would I go about doing this?
I sugest this:attach color to each number, recreate your picture in these colors: every shape will be in its particular color. Dont draw it onscreen, use it only as reference map. And when the user clicks or moves mouse over your original map, you just simply project mouse coordinates into the color map, check the color of pixel laying under the mouse and because you have each color associated to number of territory...
This is not c# specific (as I've never written anything in the language, so no idea of what apis there are), though there are 2 algorithms that come to mind for detecting if a point is inside a polygon (which can be used to detect if a mouse point is over another polygon/map shape).
One is based on raycasting, where you cast a ray in 1 direction from the (mouse) point to "infinity" (edge of the board in this case) and count the number of times it crosses the polygon's edges. If it is odd, then the point is inside the polygon, if it is even, then the point is outside of the polygon.
A wiki link to it: http://en.wikipedia.org/wiki/Point_in_polygon#Ray_casting_algorithm
The other algorithm that comes to mind works only for triangles I think but it can be more simple to implement I think (taking a quick glance at your shapes, I think they can easily be broken down into triangles and some are already triangles). It is to do with checking if the point is on the same (internal) "side" of all the edges in the triangle. To find out what "side" a point is on vs an edge, you'd take create 2 vectors, the first vector would be the edge itself (made up of 2 points) and the other vector would be the first point of that edge to the input point, then calculate the cross product of those 2 vectors. The result will be negative or positive, which can be used to determine the "direction".
A link to it: http://www.blackpawn.com/texts/pointinpoly/default.html
(On that page is another algorithm that can also work for triangles)
Hit testing on a polygon is not so difficult to do in real time. You could use a KD-Tree for optimisation if the map is huge. Otherwise find a simple Contains method for a polygon and use that. I have one on another computer. Let me know if you'd like it.