Here's an example image:
The blue tile at the top is the starting location and the blue tile at the bottom is the goal location. The green path is the path found between the two.
Astar doesn't seem to work well for this because I don't want the shortest path, but rather an L-shaped path. That is, the minimum edge length should always be 5, and it should look to minimize turns.
My current idea is something along these lines, but I'm not sure if it's ideal or if it will really work:
Move straight 5 tiles
Calculate the vector from the current location to the goal location
If, for example, the direction is mostly south, then travel straight south.
Every tile after 5 tiles straight, evaluate again which direction we should head.
If we decide to change directions, then continue in that direction for at least another 5 tiles until checking again
And then pretty much repeat steps 4 and 5 on loop until we're at the goal location.
It's okay for the pathfinding to sometimes fail if a path cannot be made, or for it to fail if the path exceeds a certain length. The above approach was the first thing that came to mind, but I'm not sure if it's ideal, or if it would even work without sometimes encountering an infinite loop condition where the path keeps going back and forth by getting stuck.
Related
I use OpeenStreetMap and the OpenLayers library, I need to build a route inside the polygon as in the mission planner program, here https://www.youtube.com/watch?v=MhHomssqD7k&ab_channel=AeroHawk at 2 minutes you can see how inside the polygon marked with red segments , the program automatically builds a route. How can I replicate this? What is this algorithm?
mission planer
I see you're talking about generating a drone flight path within a polygon, calculating the positions of way points.
Quite a fun challenge! I'll write out in words how the algorithm would work, but doing this in javascript would also be fun!
It should be possible to do this for a given (adjustable) angle of orientation, but I suggest you could simplify things initially by assuming the drone is to fly in passes orientated exactly East <-> West.
That also means the start way point is simply the northernmost corner of the polygon i.e. the vertex with the greatest latitude (Given a polygon with a northern edge like the one pictured, it doesn't matter which of the two top corners is the start point). Likewise the final way point is straightforward. The southernmost corner of the polygon.
We need to caculate all the waypoints in between. A series of locations on the left and right to create this laddered effect. Perhaps you'll want to start by building two lines (or ordered arrays of corner points) representing the left and right sides. The algrithm needs to "walk" down these sides, so maintain a lastLeft and lastRight point which are both intialised to the start of their lines. For both lines this is the start point at the top.
Each "walk step" down a line is going involve some calculation (sub-function!). They'll be a configured "gap" between the drone passes. This delta-latitude will be used at this point. For each walk step we're starting from the last point (lastLeft or lastRight) and so we've got a target latitude. targetLat = lastLeft.lat - gap. In a loop we can walk to the next point of the line (corner of the original polygon) if that lies within the gap, i.e. the latitude of that point is > targetLat. Another edge case is if the next point is actually the end point (break! we're done!). But otherwise we've got an edge that crosses the targetLat. We do the geometric calculation to find the point along the edge where it crosses the targetLat*. That point is our next way point!
*Geometric calculation to find the point along a line which has the targetLat? Possibly this part is do-able with something like TurfJS, although I couldn't tell you exactly which library call. But having worked out the rest of the algorithm, personally I'd probably just the code linear maths directly. You have known start and end to the line, therefore a known gradient. Take that and apply it to the known delta-lat to find the delta-lon.
We need to follow that algorithm for a "walk step", walking down the left line and then down the right line, and then down the right line and then down the left line, generating the ladder shaped series of way points all the way down to the end!
Eventually, I'd like to get to a place where I'm generating multiple fake "countries" on a fake "continent," but to start I boiled the problem down into something simple, and I'm already stuck at this first step:
Given an area (let's say 10 tiles x 10 tiles) and a number of polygons (let's say 6), I'm looking for a way to randomly give the polygons tile coordinates in a way that 6 polygons of approximately equal size (+/- 10% is fine, and honestly even planned) will fill up the entirety of the grid. Not the precise code per se, but even how I'd go about doing it on paper.
I've also thought about using a spiral. Starting from the approximate centre of the area (let's say [4, 4]), spiral around clockwise and cut off at 100 / 6 = ~16. While this seems like a really straight-forward approach, both on paper and in code, it certainly makes for weird-looking polygons:
And no matter how much I tweak some random variables (e.g., size of polygon, where I start, etc), it'll always look like that. In a variation, starting at the bottom left point and going up, then right, then down, then right, etc., yields the same:
To create something vaguely realistic, I'm thinking that I need to generate 6 centroids across my [10, 10] area, and then use the spiral method to create regions from that.
I find myself pretty quickly running into three problems:
How do I "equally space" out the centroids?
How do I handle the "overlap" areas, like shown with the ?s or ?!s (for the second pass-through)
How do I handle the "gap" areas, like shown with the letter G above?
And finally... is this centroid approach even the best method? I've heard of (and used, via 'clicking a button') k-means clustering... would it work to theoretically set my 100 points as input points and try to generate 6 clusters?
Any help would of course be much appreciated!
I'm not very experienced with this, but you could use a Voronoi triangulation. You would generate the points on your grid, spaced out randomly , then you would use a Voronoi diagram (https://en.wikipedia.org/wiki/Voronoi_diagram), to determine the countries. To make them more equal, you would use Lloyd relaxation (https://en.wikipedia.org/wiki/Lloyd's_algorithm) to equal them out.
I'm stuck at this Problem:
I have a 2D space from Coordinates -200,-200 (upper left) to 200,200 (bottom right).
Now i wanna add a point around the center (0,0) at a random position.
So far, so good. Just have to pick a random number from -200 to 200 for each x and y.
This should now be repeated until i have the desired amount of points.
But there are two Problems now:
I dont want two points to be at the same position. Is there any easier of faster way, than testing each point and if neccessary repeat the whole process?
I dont want the points to instantly spread over the whole map. They should gather at the center and move away only as soon as there is only some space left in the biggest "ring" of points around the center.But nonetheless the points should have some empty spaces between them from time to time.
The last condition is my biggest Problem. Does anyone have an idea how i can solve this?
At the moment im trying to do this in javascript, but if this works, i wanna save the points in a database with mysql and add one after another with php.
I don't think there is any way to avoid some sort of duplicate detection for a generated point unless you generate the entire map at once by iterating through every point and turn it on based upon the outcome of a random number. You can weight the chance of an appearance of a point based upon a distance formula from the center.
But, in general, there is nothing wrong with a Monte Carlo approach where you just generate an approximately normal distribution of points around the center. You can do this by just getting 3 random numbers for x and for y, adding them together and dividing by 3. This will give you a normal point cloud around the center. You can just throw out any duplicates.
I want to fake a simulation of a golf shot between the origin (where the ball lies), and a known result of the destination (where the shot finishes). I am determining the destination of the shot first with a random number. After that, I want to randomize a shot shape within certain bounds to make it interesting.
Is it possible to work backwards with arcade physics?
My current solution is to enumerate many paths before and then to randomly choose one. The problem with this strategy is that the distance of the shot can vary, so this greatly increases the amount of predetermined paths needed.
I'm working on a html map maker, and i'd like to offer our users the ability to create shapes quickly by clicking in a zone instead of having them define the shape manually.
First let's have a look at what we're doing for the moment. The user would like to map the area A. What he has to do is click multiple times on each point to define the boundaries of the shape.
I'd like to know is if there is an algorithm that would allow the user to click in the A area and could determine what points to dispose in order to create an near-optimal shape following the shape boundaries - based on the image contrast.
My first idea to handle this was to determine the furthest points up, left, down, right from the clicked point. Set these four points as our starting points. Then for each segment, subdivide it with a new point and move the new point along the vector normal until i hit a contrasted edge.
Of course, there are some limitations to this approach, but here is what i can assume
the shape can be convex, concave, etc...
the contrast should be black against white but to handle possible evolutions the contrast treshold should be configurable.
in the example i've been thinking about above, there would obviously be a limit to the subdivision depth in order not to kill the users machine
If any of you know about such an alogrithm, that would be really great.
Have a look at Region Growing algorithms. This is basically the same as the flood-fill algorithm described above by tokland in the basic case.
This seems like a hard problem (btw, I don't know about a specific algorithm for this). My 2 cents:
Use a flood-fill algorithm, but instead of getting the whole surface, get only the perimeter.
Take a starting point of the perimeter and go in one way; when you detect that the accumulated quadratic error between the virtual segment (current point - initial point) and the real perimeter goes over a threshold, put a point there and start again till you get to the starting point.
The first step seems pretty easy, the second is harder.
You may use an Edge Detection Algorithm (EDA).
In Javascript you may use Pixastic, or roll your own.
After being processed by the EDA, your image gets to:
After that, simply throw any line in any direction from your interior point to the first white pixel, and follow the contour.