Checking for rectangle overlap in multi-dimensional array C# - c#

So I'm making a procedural dungeon maker, right now I store the map in a multi-dimensional array. I plot n number of rooms of random positions and random sizes all of which are rectangles. As seen below:
'X' represents part of a room and '.' represent empty space. As you can see since I am randomly generating the size and position of these rooms some of these rooms overlap, this can be seen in the image.
My question is how would I go about checking if there are overlapping rectangles and therefore remove the overlapping rectangles? Not asking anyone to code this, I'm just struggling with understanding the logic.
Thanks

1) make a 2D array like that and check for X's BEFORE you put a room there ;-) If there are X's, don't put the new room there to begin with. Doesn't have to be rocket science. Remember you have control over this. Put the room-making logic in a method that can see your grid and room dimensions, have it operate in 2 modes: mode1=return TRUE if overlapping, mode 2, update the grid. call it once to see if you have a good good spot for a new room, if not, make another room!
2) brute force compares: (pseudocode) this is if you have an array of individual drawing.2d.rectangles.
bool collides(rect newrect, rect[] allrects)
for each item in allrects
if item.intersects(newrect)
return true
There, I didn't 'code' it ;-)
Before adding a new rectangle, call this routine.

Related

How to find inner border of shape represented as point collection?

I need to get inner border of shape. Previously, I found nearest point to the center of shape in case of square or circle shape, but how can I do it in M-shape case.
What I have (I need marked points at screenshot №2):
Any algorithms, steps to find these points?
UPD: Now, I have segments direction vector like (1, 0) or (0.5, 0.5)
It looks like the first step is to simplify by averaging near-neighbour dots into a single point. Then find the smallest convex polygon that contains all points (easily done). Then selectively punch some sides in to meet the internal points (the polygon becomes concave). There are many ways to select which sides to punch in, and which points to punch in to first, and I can't be sure what's best without knowing more about your specific goals.
A simple approach would be to deal first with those points that are closest to an existing side, and punch the nearest side in to meet them. But you may want to apply other scoring conditions to choose the best points to deal with first and the best sides to punch in. For instance, you may want to give higher scores to points that are closely vertically or horizontally aligned with one of the vertices of the current polygon, so that they are dealt with earlier rather than later; and give the sides adjoining that vertex a higher score as candidates for punching in. You probably also want to award longer sides with higher scores as candidates for punching in.
I imagine that with a few simple weighting criteria such as these, you will quickly get some sensible results.
Finally, if you wish, you can refer back to your original set of unaveraged dots, and make further small adjustments to the shape to ensure that all those dots fall outside its boundaries.

algorithm for creating shapes out of arrays

I'm looking for an algorithm which could create shapes based
on arrays with coordinates. I have two 50x50 arrays: one with x and second with y coordinates.
There is always 2500 points. Then I have another 50x50 array with my values for coordinates.
I create 3 to 6 areas based on value (for example 0-100, 200-300 and 300-500). Points with certain values creates areas.
I need an algorithm which can calculate if there is only one shape in area or more and fill shapes with colors.
I need that because I must fill shapes with certain colors for each area.
Language is C#.
Example points.
Expected edges.
Expected result
Basically you could use hierarchical clustering to find the clusters.
Each point is its own cluster
Find two cluster closest together and merge them
Repeat until end condition is met
Couple of specifics: In step 2 you could use many metrics to find the closest clusters. Mean-to-mean distance or minimum distance over all point pairs are probably best choices
In Step 3, you can either stop when remaining number of clusters is 2 (or some other number). Or stop when distance is more than a threshold.
To find the actual outline, I suggest coming up with some optimization function that minimizes the length of outline while minimizing the area of the outline. And the some heuristics to optimize the function.
Something like Area - constant*Length.

Programmatically link all points

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.

Detect mouseover of non-square part of an Image

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.

Best data structure to hold a group of coordinates inside a really big rectangle?

I have an abstract representation of a map with, lets say, 5.000.000 different integer coordinates on the X and Y coordinates, so it is a really big 2d rectangle.
And then, inside that variable-sized rectangle, I have several objects (characters, monsters, npcs). A player can select a position of this rectangle, and I have to check if there is a monster or a character on said position.
So far, I made a custom class called GameMatrix with columns and rows, and said columns has 3000x2000 positions (the area view of a character).
When a player of my game clicks on said coordinate, I have to do a foreach() of every element inside the matrix, and most of the times it is empty.
Is there a better way to solve this? Specifically, I am asking on what is the best way to, having a really big rectangle and a coordinate, check if there are objects inside said coordinate in an efficient way.
Forgot to mention, but this is done in the server-side several times per miliseconds. So I need a lot of performance.
Edit: Forgot to mention, I am using C#.
You should use a quad-tree implementation, unless the number of items in the grid is really small (like a couple of dozens items), in which case a linear search (brute force inspecting all of them at the same time) is probably the best choice.
See here
http://en.wikipedia.org/wiki/Quadtree
Note that a quad tree can be queried very quickly and efficiently, but updates are a bit more costly, that is if your items move a lot across your map, this becomes more complicated to do with a good performance.
I would recommend just trying the simplest solution first and worry about the optimization later.
Try using an array. Improve your solution as you go. A list or hash map might be interesting too depending on your setup.

Categories