I want to find the minimum distance between two polygons with million number of vertices(not the minimum distance between their vertices). I have to find the minimum of shortest distance between each vertex of first shape with all of the vertices of the other one. Something like the Hausdorff Distance, but I need the minimum instead of the maximum.
Perhaps you should check out (PDF warning! Also note that, for some reason, the order of the pages is reversed) "Optimal Algorithms for Computing the Minimum Distance Between Two Finite Planar Sets" by Toussaint and Bhattacharya:
It is shown in this paper that the
minimum distance between two finite
planar sets if [sic] n points can be
computed in O(n log n) worst-case
running time and that this is optimal
to within a constant factor.
Furthermore, when the sets form a
convex polygon this complexity can be
reduced to O(n).
If the two polygons are crossing convex ones, perhaps you should also check out (PDF warning! Again, the order of the pages is reversed) "An Optimal Algorithm for Computing the Minimum Vertex Distance Between Two Crossing Convex Polygons" by Toussaint:
Let P = {p1,
p2,..., pm} and Q = {q1, q2,...,
qn} be two intersecting polygons whose vertices are specified
by their cartesian coordinates in
order. An optimal O(m + n)
algorithm is presented for computing
the minimum euclidean distance between
a vertex pi in P and a
vertex qj in Q.
There is a simple algorithm that uses Minkowski Addition that allows calculating min-distance of two convex polygonal shapes and runs in O(n + m).
Links:
algoWiki, boost.org, neerc.ifmo.ru (in russian).
If Minkowski subtraction of two convex polygons covers (0, 0), then they intersect
Related
I've written a DFS algorithm which finds a path between to vertices in a graph but want to optimize it to return the path containing the minimum number of edges.
I wanted to just switch to a BFS algorithm, but I'm unsure of how I would need to modify it given the properties of my graph and the criteria the resulting path must meet.
The Graph:
Undirected, weighted and contains edges with positive weights, negative weights, and weights of 0.
The Path:
Cannot visit any vertex more than once. Total weight of the path must always be positive including the path up to any vertex before the vertex of the end of the path.
The weights can be thought of as the cost to use each path and the total weight as the amount available to use. Positive weights increase the amount available to use and negative weights cost their weight to use.
Any help would be appreciated, thanks!
BFS is applicable to unweighted graphs (or graphs where all edges have the same weight).
For weighted graphs one can use algorithms such as Dijkstra's (which is a "modified BFS"), or A* (which is a "modified Dijkstra's") .
However both Dijkstra's or A* do not work correctly with negative weights.
For graph with negative weights consider
Bellman–Ford algorithm.
Edit: If you only want to use the smallest number of edges whilst maintaining
Total weight of the path must always be positive including the path up
to any vertex before the vertex of the end of the path.
you can use BFS and use the weight just as selection criteria, meaning check before adding an edge to the queue. If adding it would make the total weight negative, do not add it.
I have a 2D array of size n representing n number of points in the 3D space, position[][] for XYZ (e.g. position[0][0] is X, position[0][1] is Y, and position[0][2] is Z coordinate of point 0.
What I need to do is to do clustering on the points, so to have n/k number of clusters of size k so that each cluster consists of the k closest points in the 3D space. For instance, if n=100 and k=5, I want to have 20 clusters of 5 points which are the closest neighbors in space.
How can I achieve that? (I need pseudo-code. For snippets preferably in Java)
What I was doing so far was a simple sorting based on each component. But this does NOT give me necessarily the closest neighbors.
Sort based on X (position[0][0])
Then sort based on Y (position[0][1])
Then sort based on Z (position[0][2])
for (int i=0; i<position.length; i++){
for (int j=i+1; j<position.length; j++){
if(position[i][0] > position[i+1][0]){
swap (position[i+1][0], position[i][0]);
}
}
}
// and do this for position[i][1] (i.e. Y) and then position[i+2][2] (i.e. Z)
I believe my question slightly differs from the Nearest neighbor search with kd-trees because neighbors in each iteration should not overlap with others. I guess we might need to use it as a component, but how, that's the question.
At start you do not have a octree but list of points instead like:
float position[n][3];
So to ease up the clustering and octree creation you can use 3D point density map. It is similar to creating histogram:
compute bounding box of your points O(n)
so process all points and determine min and max coordinates.
create density map O(max(m^3,n))
So divide used space (bbox) into some 3D voxel grid (use resolution you want/need) do a density map like:
int map[m][m][m]`
And clear it with zero.
for (int x=0;x<m;x++)
for (int y=0;y<m;y++)
for (int z=0;z<m;z++)
map[x][y][z]=0;
Then process all points determine its cell position from x,y,z and increment it.
for (int i=0;i<n;i++)
{
int x=(m-1)*(position[i][0]-xmin)/(xmax-xmin);
int y=(m-1)*(position[i][1]-ymin)/(ymax-ymin);
int z=(m-1)*(position[i][2]-zmin)/(zmax-zmin);
map[x][y][z]++;
// here you can add point i into octree belonging to leaf representing this cell
}
That will give you low res density map. The higher number in cell map[x][y][z] the more points are in it which means a cluster is there and you can also move point to that cluster in your octree.
This can be recursively repeated for cells that have enough points. To make your octree create density map 2x2x2 and recursively split each cell until its count is lesser then threshold or cell size is too small.
For more info see similar QAs
Finding holes in 2d point sets? for the density map
Effective gif/image color quantization? for the clustering
What you what is not Clustering. From what you said, I think you want to divided your N points into N/k groups, with each group have k points, while keeping the points in each cluster are closest in the 3D space.
Think an easy example, if you want to do the same thing one one dimension, that is, just sort the numbers, and the first k points into cluster 1, the second k points into cluster 2, and so on.
Then return the 3D space problem, the answer is the same. Just first find the point with minimum x-axis, y-axis and z-axis, altogether with its closest k-1 points into Cluster 1. Then for the lest points, find the minimum x-axis, y-axis and z-axis points, and k-1 closest points not clustered into Cluster 2, and so on.
Above process will get your results, but that maybe not meaningful in practice, maybe cluster algorithms such as k-means could help you.
How to decide heuristic cost for the cities connected with roads problem. The graph has non negative weighted unidirectional edges and no edge connects any vertex to itself. In this graph, there is only one edge between any two vertices. My aim is to get the shortest distance between single source and single destination.
If your edges lie in a Euclidian plane, your vertices correspond to roads, and the vertex cost is the length of the road, then the Euclidian distance or L2 norm is a good choice for the heuristic cost.
Here's why. But first, some quick terminology:
Let f(x) be the path cost, the calculated shortest distance from the start node to node x.
Let h(x) be the heuristic cost, an estimate of the distance to the goal from node x.
Because A* is a directed best-first search algorithm. At each step it moves to the node which minimizes h(x) + f(x) (and calculating h(x) requires that we have a goal node in mind).
For this approach to be guaranteed to find the correct shortest patch distance between the start and end nodes, h(x) must be an admissible heuristic. This essentially means that it must not overestimate the distance to the goal node.
Therefore, if your nodes are organized on a Euclidian plane, and your costs correspond to the L2 norm distance between the nodes, then the Euclidian distance or L2 norm between the current node x and the goal node is guaranteed to be an admissible heuristic (it's the shortest possible path between the two nodes, so any actual path along a series of vertices in your graph must be longer).
As a bonus, it's informative to note that Dijkstra's Algorithm is simply a special case of A* with h(x) = 0. For any node, we assume that the path to the goal is 0, which means we simply take the smallest possible step. This is certainly an admissible heuristic because the distance between any two nodes cannot be less than 0 (if we're assuming non-negative edge costs).
If you're trying to optimize for distance travelled, euclidean distance is a good baseline heuristic.
If you're given a weighted graph, use the edge weight as if it's the length of the segment. The shortest path in a weighted graph is the path with the lowest combined edge weight.
I need to find the minimum distance b/w two kdtree bounding box's of same tree in euclidean space. Suppose each box maintain a 5 elements. I need the minimum Euclidean distance using java.
double QHRect[][] = QNode.m_NodesRectBounds;
double RHRect[][] = RNode.m_NodesRectBounds;
QHRect[][]: 5.74842E-4,7.76626E-5,6.72655E-4,
0.5002329025,0.2499048942,0.25046735625
RHRect[][]:
0.75006193275,0.7495593574,0.75005675875,
0.999890963,0.999386589,0.99985146
There is nothing tricky about a Java implementation compared with any other language in this matter. You need to know the general algorithm to handle a problem like this. I believe it is this:
Enumerate all 12 vertices of the two bounding boxes (cubes).
Enumerate all 12 faces of the two bounding boxes.
Find the Euclidean distance between each vertex of one and face of the other. This is similar to the shortest distance between a point and a plane.
Of these 2*6*6=72 combinations, pick the smallest and you have your answer.
In the general version of the problem, you would also have to check for if the two bounding boxes intersect as well.
currently i have using a framework and it has a function called distance2D, and it has this description:
Calculate the Euclidean distance
between two points (considering a
point as a vector object). Disregards
the Z component of the vectors and is
thus a little faster.
and this is how i use it
if(g.getCenterPointGlobal().distance2D(target.getCenterPointGlobal()) > 1)
System.out.println("Near");
i have totally no idea what a Euclidean distance is, i am thinking that it can be used to calculate how far 2 points are? because i am trying to compare distance between 2 objects and if they are near within a certain range i want to do something. how would i be able to use this?
Euclidean distance is the distance between 2 points as if you were using a ruler. I don't know what are the dimensions of your Euclidean space, but be careful because the function you are using just takes in consideration the first two dimensions (x,y). Thus if you have a space with 3 dimensions(x,y,z) it will only use the first two(x,y of x,y,z) to calculate the distance. This may give a wrong result.
For what I understood, if you want to trigger some action when two points are within some range you should make:
<!-- language: lang-java -->
if(g.getCenterPointGlobal().distance2D(target.getCenterPointGlobal()) < RANGE)
System.out.println("Near");
The Euclidean distance is calculated tracing a straight line between two points and measuring as the hypotenuse of a imaginary isosceles triangle between the two lines and a complementary point. This measure is scalar, so it's a good metric for your calculations.
Euclidean geometry is a coordinate system in which space is flat, not curved. You don't need to care about non-Euclidean geometry unless for example you're dealing with coordinates mapped onto a sphere, such as calculating the shortest travel distance between two places on Earth.
I imagine this function will basically use Pythagoras' theorem to calculate the distance between the two objects. However, as the description says, it disregards the Z component. In otherwords, it will only give a correct answer if both points have the same Z value (aka "depth").
If you wish to compare distances and save time, use not the distance itself, but its square: (x1-x2)^2 + (y1-y2)^2. Don't take sqrt. So, your distances will work exactly as euclidian ones, but quickly.