问题
for a geo-based online game I'm looking for an algorithm which finds the shortest distance between a specified point and a known path connected by x/y-coordinates, so that I can kill all redundant points/nodes. A link or keyword for this algorithm would help me a lot! thanks for reading
For better understanding:
回答1:
Are you wanting to calculate this in order to say something like "if the point-to-path distance is zero, then remove the point"? If so, then there is probably an easier way to remove redundant nodes. Take the points three at a time (call them A
, B
, and C
). Calculate the angle between A
and B
, as well as the angle between B
and C
. If the two angles are the same, then point B
lies in the path between A
and C
and is redundant. You can use the 'atan2' function (or your language's equivalent) to do the angle calculations.
回答2:
This is a point-to-point path-finding algorithm that is commonly used in games:
A* search algorithm
You might need to apply it a number of times between your point and path, but it is generally very fast. The algorithm has some optimizations for map grids (where the distances between squares are integers). There's a description of this in: Real-Time Strategy Game Programming using MS DirectX 6.0 by Mickey Kawick.
Djikstra's algorithm is a good general purpose path-finding algorithm from a single source node to all other nodes in the graph. You can stop the algorithm when you've found what you need - which in your case would be when the algorithm had found the shortest path to every node on the path.
I don't know of a specific "shortest path from node to path" algorithm.
回答3:
This is my Java implementation for the nearest point on a path
private Point getNearestPoint(Point from, List<Point> to_path) {
int count = to_path.size();
if (count == 0)
return null;
if (count == 1)
return to_path.get(0);
double nearest_dist = Double.MAX_VALUE;
Point nearest_point = null;
for (int i = 1; i < count; i++) {
Point p1 = to_path.get(i-1);
Point p2 = to_path.get(i);
Point p = getNearestPointOnSegment(from, p1, p2);
if (p != nearest_point) {
double dist = dist(from, p);
if (dist < nearest_dist) {
nearest_dist = dist;
nearest_point = p;
}
}
}
return nearest_point;
}
private Point getNearestPointOnSegment(Point from, Point p1, Point p2) {
if (dist(p1, p2) < 1e3) {
Log.d(TAG, "Points are near");
return p1;
}
double d2 = dist2(p1, p2);
double t = ((from.x - p1.x) * (p2.x - p1.x) + (from.y - p1.y) * (p2.y - p1.y)) / d2;
if (t < 0) {
//Log.d(TAG, "p1");
return p1;
}
if (t > 1) {
//Log.d(TAG, "p2");
return p2;
}
//Log.d(TAG, "t:" + t);
return new Point((int)(p1.x + t * (p2.x - p1.x)),
(int)(p1.y + t * (p2.y - p1.y)));
}
private double dist(Point p1, Point p2) {
return Math.sqrt(dist2(p1, p2));
}
private double dist2(Point p1, Point p2) {
return sqr(p1.x - p2.x) + sqr(p1.y - p2.y);
}
private double sqr(double x) {
return x * x;
}
来源:https://stackoverflow.com/questions/3609049/shortest-distance-between-point-and-path