I'm drawing a whole bunch of Polygons onto a canvas, most of which share an edge with at least one other Polygon. I'd like to indicate a Polygon is "special" by outlining it, however due to the overlapping edges the Stroke on a Polygon tends to be partially drawn over by another Polygon causing the Stroke to look thinner than it should in places. Additionally, depending on draw order, a Polygon may have its Stroke almost entirely covered by those around it. Spacing the Polygons out is not a very attractive option, as visible gaps between Polygons are much less preferable to this "thin stroke" problem.
I reason that the effect I'm looking for can be achieved by generating each Polygon as a pair of Polygons instead, such that one Polygon is completely contained within the other and this smaller Polygon's Stroke runs up to (but does not overlap) the outer Polygon's Stroke. The inner Polygon would have a transparent Fill at all times, and a non-transparent Stroke only when I wish to indicate that the now pair of Polygons are "special".
My question boils down to; how can I derive such an inner Polygon from the outer one, or failing that how else might I achieve this effect?
The Polygon's in question can be constrained to the regular polygons if need be, and the Strokes are simple 1 thickness solid lines with no fancy miters or the like. I'd like to be able to adjust the thickness of the Stroke at some point, but nothing fancier than that.
I think there's actually a few ways to achieve what you want.
First, going with your original idea of drawing a second, slightly smaller polygon within the original polygon; it's not a bad idea. To answer your original question as to how to generate the smaller polygon: you can find the centroid of each polygon, and offset each vertex by a percentage of the distance to that centroid point of the polygon to get the smaller polygon. This should give a pleasing effect.
Another way you could go would be to use z-order, and offset the "thicker" polygon by a slight negative z-distance.
Yet another way to go would be to exploit draw order; draw your thicker polygons last, which will prevent them from being overdrawn by the surrounding polygons.
Yet another idea that might work depending on your needs might be not to draw polygons at all, but to draw a series of lines, simply thickening some of the lines.
There's a lot of options for you to try; hope you find one that works out well!
Related
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.
I'm trying to scan some pictures together (personal 3x4 cm images) and then split them into separated images. the first step about scanning is done but about second step (edge detection and splitting) I've some problems.
1- Normally when they scan pictures, some pictures rotate some degrees and its preventing me to have straight edges.
2- How do I remove big noises? (Imagine when they scan those pictures, they put a paper behind them. sometimes the paper makes some edges in the scanned picture... how can I understand that its not the edge I'm looking for?)
Here is a sample image:
The sample images within the scan are all rectangular, and they are all roughly the same size. There are a variety of techniques for finding rectangles in an image (even at completely arbitrary rotation), but I'll start with the more fundamental techniques.
Hough line fit can be used to find lines in an image, even when the background is noisy. From the Hough line fits you can find intersection points and perhaps compare those intersection points to points found with corner detections (see 3 below).
Edge points on lines have gradients perpendicular to those lines. When searching for edge points, you can favor edge points that are roughly a distance L or a distance W from other edge points with gradients in the parallel direction, where L and W are the known length and width of your images.
Corner detectors can help identify corners of your small rectangular images. You know the length and width of the pictures, which should help you accept/reject corners.
If you want to get fancy (which I don't recommend), then a simple normalized cross-correlation technique could detect all instances of a "template" subimage within a larger image. The technique is a bit crude, but it works okay if there isn't much rotation. Since the subimages have well-defined borders of known shape and (presumably) consistent size, it'd be easier just to find the edges rather than try to match the image content.
Once you've identified the location and orientation of each rectangular subimage, then a simple rotational transform + interpolation could generate a "right side up" version of each image. With scanners you won't have problems with perspective distortion, but if at some point in the future you would take pictures of pictures (?) at an angle, then an affine transform can map the distorted, trapezoidal images to rectangular images.
Hough transform
http://en.wikipedia.org/wiki/Hough_transform
Corner detection
http://en.wikipedia.org/wiki/Corner_detection
For simple edge detection that should work sufficiently well for your application, see the section "Other first-order methods" in the Edge Detection article on Wikipedia. The technique is easy to understand and simple to implement.
http://en.wikipedia.org/wiki/Edge_detection
Good luck, and once again Happy New Year!
I have a big polygon (Pa). Inside the polygon there are a lot of small "holes", as shown:
Here are a few condition for the holes:
The holes cannot overlap one another
The holes cannot go outside the outer polygon
However, the holes can touch the outer polygon edge
How to obtain the remaining polygon ( or the polygon list) in an efficient manner? The easiest way ( brute force way) is to take the Pa, and gradually computing the remaining polygon by subtracting out the holes. Although this idea is feasible, but I suspect that there is a more efficient algorithm.
Edit: I'm not asking about how to perform polygon clipping ( or subtraction) algorithm! In fact that's something I would do by brute force. I'm asking in addition to the polygon clipping method ( take the main polygon and then gradually clip the holes out), is there other more efficient way?
This is very hard to do in a general manner. You can find source code for a solution here:
General Polygon Clipper (GPC)
Well, if you use the right representation for your polygon you would not need to do anything. Just append the list of edges of the holes to the list of edges of Pa.
The only consideration you should have is that if some hole vertex or edge can touch Pa edge, you will have to perform some simplification there.
A different problem is rendering that polygon into a bitmap!
You can do like this.
Draw the main polygon with a color in a bitmap.
Draw the holes with another color in the same bitmap.
Then extract the polygon by running marching square algorithm with the main polygons color as threshold.
The output will contain all the points that belong to that polygon.
You can sort the points if you want it as a continous closed polygon.
I agree with salva, but my post is going to address the drawing part. Basically, you can add up all lines of the main and the hole polygons together and thereby get a single complex polygon.
The algorithm itself is not very complicted and it is nicely explained in the Polygon Fill Teaching Tool.