I have 2D world maps that are basically Mercator-Like projections, (If you walk west long enough you end up east of where you started)
Question I have: Can you use A* for computing paths on these types of maps as well?
I can't think of any reason why you couldn't (I'm thinking that you would simply represent the edge map nodes such that the North, South, East, Wed, "border" nodes simply connected to the opposite side).
Thanks in advance, if anyone has seen something like this before or can give me a few hints I would appreciate it.
Pathfinding algorithms don't really care about global topology of the map. The only tricky part is to get a good estimator for A* but using the 3D distance should be ok if your map is indeed a surface in a 3d space and step cost is step length.
Your map can have all sort of strange "connections" (including for example knotted bridges) and this will not be a problem if you implement A* correctly.
I can't imagine why a Mercator-Like projections would cause a problem for A*, as long as your heuristic function approximates distances correctly. I think something along the below function should work fine
float heuristic(point from, point to, size mapsize) {
float x = from.x - to.x;
if (abs(x) > mapsize.x/2)
x = mapsize.x - x;
float y = from.y - to.y;
if (abs(y) > mapsize.y/2)
y = mapsize.y - y;
return sqrt(x*x+y*y);
}
Edited: I realize know I was misled by the non-graph theoretical) use of the word edge (where the question title strongly suggested a graph algorithm question :))
Why do you suppose there are no edges? There are many logical discrete locations that you could model, and limited connections between (i.e. not where a wall is :)). There you go: you have your edges.
What you probably mean is that you don't want to represent your edges in data (which you don't have to, but still there are the logical edges that connect locations/points.)
That said:
you ask whether someone has seen things like this before. I vaguely recall seeing something relevant to this in Knuths Dancing Links article (DLX) which is an implementation technique for A* algorithms.
http://en.wikipedia.org/wiki/Dancing_Links
original publication [PDF]
The article specifically treats states as 'cells' (in a grid) with east/west/north/south links. It's been a long time so I don't quite recall how you would map (no pun intended) your problem on that algorithm.
The dance steps. One good way to implement algorithm X is to represent each 1 in the
matrix A as a data object x with five fields L[x]; R[x]; U [x]; D[x]; C[x]. Rows of the matrix
are doubly linked as circular lists via the L and R fields ("left" and "right"); columns are
doubly linked as circular lists via the U and D fields ("up" and "down"). Each column
list also includes a special data object called its list header.
Related
I'm trying to construct a program in C# that generates a 3D model of a structure composed of beams, and then creates some views of the object (front, side, top and isometric).
As I don't need to draw surfaces (the edges are enough), I've been calculating each line to draw, and then do it with
GraphicObject.DrawLine(myPen, x1, y1, x2, y2)
This worked fine so far, but as I get adding parts to the structure, the refresh of GraphicObject takes too much time. So I'm getting into line visibility check to reduce the amount of lines to draw.
I've searched Wikipedia and some PDFs on the subject, but all I found is oriented by surfaces. So my question: Is there a simplified algorithm to check visibility of object edges, or should i go for a different approach, like considering surfaces?
Any suggestions would be appreciated, thanks for your help.
Additional notes/questions:
My current approach:
calculate every beam in a local axis (all vertices)
=> move them to their global position
=> create a list with pairs of points (projected and scaled to the view)
=> GraphicObject.DrawLine the list of point pairs)
would the whole thing be faster if I'd calculate the view by pixels rather than using the DrawLine method?
Screenshots follow with the type of structure it's going to do (not fully complete yet):
Structure view
Structure detail
There are 2 solutions to improve the performance.
a) switch the computation to the graphics card.
b) Use a kd-tree or some other similar data structure to quickly remove the non visible edges.
Here's more details:
For a), a lot of you computations are multiplying many vertices (vectors of length 3) by some matrix. The CPUs are slow because they only do a couple of these operations at a time. Switch to a GPU, for example using CUDA, which will allow you to do them more in parallel, with better memory access infrastructure. You can also use OpenGL/DirectX/Vulkan or whatever to render the lines themselves to skip having to get the results back from the graphics card and whatever other hiccups get introduced by windows code/libraries. This will help in almost all cases to improve performance.
For b), it only helps when you are not looking at the entire scene (in that case you really need to draw everything). In this cases you can store you scene in a kd-tree or some other data structure and use it to quickly remove things that are for sure outside of the view area. You usually need to intersect some cuboid with a pyramid/fustrum so there's more math involved.
As a compromise that should help in a large scenes where you want to see everything you can consider adjusting the level of detail. From your example, the read beans across are composed of 8 or so components. If you are far enough you are not going to be able to distinguish the 8, so just draw one. This will work great if you have a large number of rounded edges as you can simplify a lot of them.
I am getting coordinates - lat/lon and I want to check if these coordinates are in the continental United States or not. Is there a easy way to do it in C#? I can convert the coordinates into MGRS or UTM.
Thanks!
Oh wow, they have it just for you:
http://econym.org.uk/gmap/states.xml
All the coords of the US states!
Build up a polygon and apply any polygon-contains-point algorithm.
The classic algorithm is ray-casting, and its even pretty simple. Let me know if you have any trouble with it.
Now, you have two options:
Use the data to build a polygon for each state, and check a point with each one of them. If none match, it is not in the US.
However, there is a problem with that approach - I don't know how the data was gathered, but its possible that there are very little gaps between states, or even slight overlaps. So if you only care if its generally in the US or not, I suggest the second approach:
Use the data to build a polygon for each state, and an algorithm to combine those polygons to one (like union). Save that polygon and use that as with the 1st approach.
I wonder if there's any described algorithm that can convert isochrones into approximate area to show a range of some feature (in my problem this feature is a road network).
Example. I have something like on the image beneath:
It's a simple network (where I can arrive from the start point in X minutes or going Y kilometers). I have information of all the nodes and links. Now I need to create an isochrone map that show an approximate range where I can arrive.
Problems:
Convex hull - sucks because of too general approximation,
I can create buffors on roads - so I will get some polygon that shows range, but I will also have the holes by roads that connect into circles.
What I need to obtain is something like this:
I've found some potentially useful information HERE, but there are only some ideas how it could be done. If anyone has any concept, please, help me to solve my problem.
Interesting problem, to get better answers you might want to define exactly what will this area that shows the range (isochrone map) be used for? For example is it illustrative? If you define what kind of approximation you want it could help you solve the problem.
Now here are some ideas.
1) Find all the cycles in the graph (see link), then eliminate edges that are shared between two cycles. Finally take the convex hull of the remaining cycles, this together with all the roads, so that the outliers that do not form cycles are included, will give a good approximation for an isochrome map.
2) A simpler solution is to define a thickness around each point of every road, this thickness should be inversely proportional to how long it takes to arrive at that point from the starting point. I.e. the longer it takes to arrive at the point the less thick. You can then scale the thickness of all points until all wholes are filled, and then you will have an approximate isochrome map. One possible way of implementing this is to run an algorithm that takes all possible routes simultaneously from the starting point, branching off at every new intersection, while tracking how long it took to arrive at each point. During its execution, at every instant of time all previously discovered route should be thickened. At the end you can scale this thickness so as to fill all wholes.
Hopefully this will be of some help. Good luck.
I have solved the problem (it's not so fast and robust, but has to be enough for now).
I generated my possible routes using A* (A-Star) algorithm.
I used #Artur Gower's idea from point one to eliminate cycles and simplify my geometry.
Later I decided to generate 2 types of gemetries (1st - like on the image, 2nd - simple buffers):
1st one:
3. Then I have removed the rest of unnecessary points using Douglas-Peucker algorithm (very fast!).
4. In the end I used Concave Hull algorithm (aka Alpha-Shapes or Non-Convex Hull).
2nd one:
3. Apply a buffer to the existing geometry and take the exterior ring (JTS library made that really easier:)).
Is there any simple (or not) algorithm that is capable of creating polygons from closed path?
Assume w have following path:
0,0; 2,0, 2,1; 1,1;
1,2; 2,2; 2,3; 0,3;
I need to be able to create polygon indexes for OpenGL vertex buffer. Language I'm using is C#.
Someone suggested me Convex Hull, but it's not the thing I'm looking for, cause I have a shape already. I know that this could be a trivial issue, but seriously, I can't find any description or something to point mi in the right direction.
Edit:
Answer 1 suggest to select a point and connect it to other not connected points, this works fine for presented in answer shape but it will not work for shape i posted, shape above looks like this:
Converting to triangles is either easy or hard, depending on what your requirements are and how well you want to do it.
If your polygon is convex, the easiest way is to use GL_TRIANGLES with the indicies
0, 1, 2, 0, 2, 3, 0, 3, 4, ...
It will look like this:
The situation for concave is more work. An algorithm that also works for concave polygons (not ones with holes!) is the Ear-clipping method, described on wikipedia (there is more on that page.)
Things get really interesting when you want a "good" triangulation: avoid skinny or small triangles, reduce number of triangles etc., and then you can trade off quality for speed. I won't go into any advanced algorithms here; searching for polygon triangulation on Google will get you lots of info.
As for normals, if your polygon is planar (it most likely "should" be) then take two non co-incident edges and cross product them (there are two normals and you probably only want one: you need to choose the order in which you cross product (clockwise or anticlockwise) based on the right hand rule.
This seems non-trivial (it gets asked quite a lot on various forums), but I absolutely need this as a building block for a more complex algorithm.
Input: 2 polygons (A and B) in 2D, given as a list of edges [(x0, y0, x1, y2), ...] each. The points are represented by pairs of doubles. I do not know if they are given clockwise, counter-clockwise or in any direction at all. I do know that they are not necessarily convex.
Output: 3 polygons representing A, B and the intersecting polygon AB. Either of which may be an empty (?) polygon, e.g. null.
Hint for optimization: These polygons represent room and floor boundaries. So the room boundary will normally fully intersect with the floor boundary, unless it belongs to another floor on the same plane (argh!).
I'm kind of hoping someone has already done this in c# and will let me use their strategy/code, as what I have found so far on this problem is rather daunting.
EDIT: So it seems I'm not entirely chicken for feiling faint at the prospect of doing this. I would like to restate the desired output here, as this is a special case and might make computation simpler:
Output: First polygon minus all the intersecting bits, intersection polygons (plural is ok). I'm not really interested in the second polygon, just its intersection with the first.
EDIT2: I am currently using the GPC (General Polygon Clipper) library that makes this really easy!
Arash Partow's FastGEO library contains implementations of many interesting algorithms in computational geometry. Polygon intersection is one of them. It's written in Pascal, but it's only implementing math so it's pretty readable. Note that you will certainly need to preprocess your edges a little, to get them into clockwise or counterclockwise order.
ETA: But really, the best way to do this is to not do this. Find another way to approach your problem that doesn't involve arbitrary polygon intersections.
If you are programming in .NET Framework, you may want to take a look at SqlGeometry class available in .NET assemblies shipped as Microsoft SQL Server System CLR Types
The SqlGeometry class provides STIntersection method
SqlGeometry g1 = SqlGeometry.Parse("POLYGON ((...))");
SqlGeometry g2 = SqlGeometry.Parse("POLYGON ((...))");
SqlGeometry intersection = g1.STIntersection(g2);
What I think you should do
Do not attempt to do this yourself if you can possibly help it. Instead, use one of the many available polygon intersection algorithms that already exist.
I was strongly considering the following codebase on the strength of their demonstration code and the fact that they mentioned their handling of most/all of the weird cases. You would need to donate an amount (of you/your company's choice) if you use it commercially, but it's worth it to get a robust version of this kind of code.
http://www.cs.man.ac.uk/~toby/gpc/
What I actually did was to use a polygon-intersection algorithm that is part of the Java2D libraries. You can possibly find something similar in MS's own C# libraries to use.
There are other options out there as well; look for "polygon clipper" or "polygon clipping", since the same basic algorithms that handle polygon intersection also tend to be usable for the general clipping cases.
Once you actually have a polygon clipping library, you just need to subtract polygon B from polygon A to get your first piece of output, and intersect polygons A and B to get your second piece of output.
How to roll your own, for the hopelessly masochistic
When I was considering rolling my own, I found the Weiler-Atherton algorithm to have the most potential for general polygon-cutting. I used the following as a reference:
http://cs1.bradley.edu/public/jcm/weileratherton.html
http://en.wikipedia.org/wiki/Weiler-Atherton
The details, as they say, are too dense to include here, but I have no doubt that you'll be able to find references on Weiler-Atherton for years to come. Essentially, you split all the points into those that are entering the final polygon or exiting the final polygon, then you form a graph out of all the points, and then walk the graph in the appropriate directions in order to extract all the polygon pieces you want. By changing the way you define and treat the "entering" and "exiting" polygons, you can achieve several possible polygon intersections (AND, OR, XOR, etc.).
It's actually fairly implementable, but like with any computational geometry code, the devil is in the degeneracies.
You may also want to have a look at the NetTopologySuite or even try importing it into Sql server 2008 & it's spatial tools.
Clipper is an open source freeware polygon clipping library (written in Delphi and C++) that does exactly what you're asking - http://sourceforge.net/projects/polyclipping/
In my testing, Clipper is both significantly faster and far less prone to error than GPC (see more detailed comparisons here - http://www.angusj.com/delphi/clipper.php#features). Also, while there's source code for both Delphi and C++, the Clipper library also includes a compiled DLL to make it very easy to use the clipping functions in other (Windows) languages too.
A polygon is fully described by an ordered list of points (P1, P2, ..., Pn). The edges are (P1 - P2), (P2 - P3), ..., (Pn - P1). If you have two polygons A and B which overlaps, there will be a point An (from the list on points describing polygon A) which lies within the area surrounded by polygon B or vice versa (a point of B lies in A). If no such point is found, then the polygons does not overlap. If such a point is found (i.e. Ai) check the adjacent points of the polygon A(i-1) and A(i+1). Repeat until you find a point outside the area or all points are checked (then the first polygon lies completly within the second polygon). If you found a point outside then you can calculate the crossing point. Find the corresponding edge of polygon B and follow it with resersed roles = now check if the points of polygon B lie within polygon A. This way you can build a list of points which describe the overlapping polygon. If needed you should check if the polygons are identical, (P1, P2, P3) === (P2, P3, P1).
This is just an idea and there maybe better ways. If you find a working and tested solution I would recommend that you use it...
narozed
Try to use GIS tools for that, such as ArcObjects, TopologySuite, GEOS, OGR, etc. I'm not sure if all of these distributions are availuable to .net, but they all do the same.
This academic paper explains how to do this.
If you dare to take a look to other people's GPL C++ code, you can see how do they do it in Inkscape:
http://bazaar.launchpad.net/~inkscape.dev/inkscape/trunk/view/head:/src/2geom/shape.cpp (line 126)