Let's consider a linestring as a list of points, I named it trail. I need to detect which point is close enough to this trail. I have another linestring called interest points, which I need to return the closest index point from trail linestring. I want to mention that these interest points are not included in trail linestring, so I will somehow evaluate the index point in this trail by giving that interest point. The resulted interest point will get the value existing in the trail list.
[EDIT]:
I will convert this problem using plain numbers. I find that is easy.
Input list [0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5].
Input number: 3.30
I can easly see that conditon: list[n] < number < list[n+1]
Then I can check the costs:
cost1 = number - list[n]
cost2 = list[n+1] - number.
Then I can get the index of N if (cost1 < cost2) return N else return N+1.
[IMPORTANT]:
Point objects are not comparable as numbers, this drive me to a blind spot.
If you only need to do this once, or speed is not really important, and your trace doesn't tend to loop back on itself so that detecting the closest two points could differ from detecting the line segment between them, then it's pretty easy.
First, you need a distance squared formula for points (this takes the place of the difference of plain numbers):
def dSq(x0: Double, y0: Double, x1: Double, y1: Double) =
(x1 - x0)*(x1 - x0) + (y1 - y0)*(y1 - y0)
Note that you have no real advantage for using plain distance over distance squared, except that you have to calculate an extra square root. (But feel free to def d(...) = sqrt(dSq(...)) and use that instead.)
Now you find the distances from your trace to your target point:
val ds = trace.map(p => dSq(target.x, target.y, p.x, p.y))
And you find the distances between pairs of points:
val pairDs = ds.sliding(2).map(xx => xx(0) + xx(1))
And you find the index of the smallest of these:
val smallest = pairDs.min
val index = pairDs.indexWhere(_ == smallest)
Then in your original list, the two points are index and index+1.
Alternatively, you could find the closest single point and then decide whether you want the next or previous one by comparing the distances to those. (Again, note that all of these are inexact--to really do it right you have to compute the point of closest approach of the point to the line segment between two points, which is a longer formula.)
If you have to do this a lot, then you'll want to have a faster way to ignore big distances that aren't relevant. One common way is to place a grid over your trace, and then make subtraces inside each grid element. Then, when given a point of interest, you first look up its grid location, then do the same searching trick just inside the grid. (You may need to search the 8 adjacent neighbors also depending on how you clip the points inside the grid.)
Related
i'm searching for a algorithm that take a matrix (in fact, a double entry array) and return an array of matrix that:
is square (WIDTH = HEIGHT)
all of the element in the matrix has the same value.
I don't know if that is clear, so imagine that you have a image made of pixels that is red, blue or green and i want to get an array that contained the least possible squares. Like the pictures shows
EDIT:
Ok, maybe it's not clear: I've a grid of element that can have some values like that:
0011121
0111122
2211122
0010221
0012221
That was my input, and i want in output somethings like that:
|0|0|111|2|1|
|0|1|111|22|
|2|2|111|22|
|00|1|0|22|1|
|00|1|2|22|1|
When each |X| is an array that is a piece of the input array.
My goal is to minimize the number of output array
This problem does not seem to have an efficient solution.
Consider a subset of instances of your problem defined as follows:
There are only 2 values of matrix elements, say 0 and 1.
Consider only matrix elements with value 0.
Identify each matrix element m_ij with a unit square in a rectangular 2D grid whose lower left corner has the coordinates (i, n-j).
The set of unit squares SU chosen this way must be 'connected' and must not have 'holes'; formally, for each pair of units squares (m_ij, m_kl) \in SU^2: (i, j) != (k, l) there is a sequence <m_ij = m_i(0)j(0), m_i(1)j(1), ..., m_i(q)j(q) = m_kl> of q+1 unit squares such that (|i(r)-i(r+1)| = 1 _and_ j(r)=j(r+1)) _or_ (i(r)=i(r+1) _and_ |j(r)-j(r+1)| = 1 ); r=0...q (unit squares adjacent in the sequence share one side), and the set SUALL of all unit squares with lower left corner coordinates from the integers minus SU is also 'connected'.
Slicing matrices that admit for this construction into a minimal number of square submatrices is equivalent to tiling the smallest orthogonal polygon enclosing SU ( which is the union of all elements of SU ) into the minimum number of squares.
This SE.CS post gives the references (and one proof) that show that this problem is NP-complete for integer side lengths of the squares of the tiling set.
Note that according to the same post, a tiling into rectangles runs in polynomial time.
Some hints may be useful.
For representation of reduced matrix, maybe a vector is better because it's needed to be stored (start_x,start_y,value ... not sure if another matrix very useful).
Step 1: loop on x for n occurrences (start with y=0)
Step 2: loop on y for/untill n occurrences. Most of cases here will be m lees then n.
(case m greater then n excluded since cannot do a square) Fine, just keep the min value[m]
Step 3: mark on vector (start_x,start_y, value)
Repeat Step 1-3 from x=m until end x
Step 4: End x, adjust y starting from most left_x found(m-in vector, reiterate vector).
...
keep going till end matrix.
Need to be very careful of how boundary are made(squares) in order to include in result full cover of initial matrix.
Reformulate full-initial matrix can be recomposed exactly from result vector.
(need to find gaps and place it on vector derived from step_4)
Note ! This is not a full solution, maybe it's how to start and figure out on each steps what is to be adjusted.
Given a set of coordinates representing a flight path, the exercice is to find the maximum distance (given a n number of points to pass through). To illustrate the problem we have a flight path represented on a 2D grid as the following:
.
Here is what the algorithm should do with a parameter n (integer).
The question is to find an algorithm that can scan through all the points and try by combination all the distances and return the length of the final path.
We already have a method that can get the distance of two points:
/**
* #return the distance between the two coordinates
*/
public double distance(Coordinate destination) {}
/**
* #return the farthest coordinate from start
*/
public Coordinate coordMax() {}
/**
* #return max distance using n points
* I would maybe try to go for a recursive solution
* and already have the 2 corner cases down.
*/
public double statMaxDistance(int n) {
if (n == 0)
return coordTable[0].distance(coordTable[coordTable.length - 1]);
if (n == 1)
return coordTable[0].distance(coordMax());
// TODO recursive step
return statMaxDistance();
}
The question is :
Is there a way to complete this task without iterating over each point of the whole path, one by one, trying all possible combinations, computing all possible distances to eventually end up with the farthest one ?
It would seem rather sensical to follow such an approach where only 1 or 2 points would shift along the whole path but such an algorithm would be quite greedy when computing the maximum distance given 3+ reference points.
This can be solved using a Dynamic Program. Assume that D[i][j] is the maximum distance you can get from the start point to the i-th intermediate point where the last point is j. Your solution will be D[n][endPoint].
So how to solve this? The first column D[0][...] is easy to calculate. This will just be the distances of the according point to the start point. The other columns are a bit trickier. You need to check all entries in the previous column where the last point is strictly before the current point. So, to calculate entry D[i][j], you have to calculate:
D[i][j] = max_{k < j} (D[i - 1][k] + distance(k, j))
This means: Iterate all possible k such that k is smaller than j (i.e. the point k is located before the current point j). Calculate the resulting distance as the sum of the distance up to k (this is the D[i - 1][k] part) and the distance from k to j. Put the maximum of these values into D[i][j]. You may also want to keep track of k if you need to reconstruct the path at the end (i.e. you are not just interested in the maximum distance). Note that there may be cells with no valid solutions (e.g. D[1][0] - you cannot get to point 0 as the second (index 1) intermediate point).
Do this for every intermediate point in every column up to D[n - 1][...]. The final step is to do this process once more for D[n][endPoint], which strictly speaking does not need to be located in the D array (because you are interested in only a single value, not an entire column).
Once you have calculated this value, that is your solution. If you want to find the actual path, you have to backtrack using the stored k values for every cell.
I have a code for calculating euclidean distance like this :
for(int j=0;j<inputdimension;j++){
distance += Math.pow((vector1[j] - vector2.get(j)), 2);
}
and i've an example of data with different array size that i want to calculate with this euclidean distance function for those two array. for example :
vector1[] = {0.5,0.1,0.3,1.5}
vector2[] = {1.4,3.2,3.4,0.1,7.8,0.2,8.3,8.4}
So far i've encountered example for calculating the euclidean distance with the same array size. So i come up with a solution to remove the remaining array so they go balance like this for example :
vector1[] = {0.5,0.1,0.3,1.5}
vector2[] = {1.4,3.2,3.4,0.1}
The problem is, i dont know if its right or not? is there any other way to balance this data?
The answer is simple. You cannot find euclidean distance between two points which have different number of dimensions. If you eliminate remaining array like that, the answer would be unrealistic and inconsistent. However you can add zeros to smaller array, if this is a must for you. The result will be better, but it will be still unrealistic in my opinion.
P.S. You need to use Math.sqrt(distance) method after for loop.
Original post:
I'm trying to find the outermost vertices of a convex polygon (with relation to a point P outside the polygon). For now, I'm only concerned with rectangles (however, I'd like an algorithm that works with any convex polygon).
My plan is to construct a line from external point P to central point C. From this line of reference, I will construct lines from point P to points 1, 2, 3 and 4. Since points 2 and 4 will have the largest (most positive) and smallest (most negative) angles from the line of reference, they will be identified as the outermost vertices.
Is this the best algorithm for the job? How does one calculate angles from a reference angle (preferably in Java)?
Update for clarification:
I've drawn the lines (line of reference in red). As you can see, the line from P to 2 creates the largest angle on one side of the line of reference, while the line from P to 4 creates the largest angle of the other side. Hence, these are the outermost vertices.
This is pretty much the convex hull problem. You would be looking for a set of vertices (x1, x2) around a polygon. The methodology that would be applied is called "quick-hull", analogous to quicksort (in that we divide our region of points every time we step through). It is also a safe assumption that P can be used as a mid-point between an arbitrary starting point and its parallel ending point, so you would get a convex hull around P.
It would take a while to produce some reliable Java to poke at (from my happenstance), but I think that the Wikipedia entry will give you a great starting point.
The use of trigonometry is extremely slow. You should use another angle comparison.
For an angle between two flat vectors:
cos(OA, OB) = (OAx * OBx + OAy* OBy) / sqrt((OAx2 + OAy2)* (OBx 2 + OBy2))
I think, you can compare angles having cosines.
I solved the problem as follows:
// code simplified for demonstration
double angleBetweenVertices;
double maxAngleBetweenVertices;
vectorA.setStartingPoint(outerPoint);
vectorA.setTerminationPoint(polygonCenter);
vectorB.setStartingPoint(outerPount);
// For each vertex, calculate the angle between the outer point, the polygon's center and the vertex
for (Point2D.Double vertex : vertices) {
vectorB.setTerminationPoint(vertex);
double angleBetweenVertices =
Math.toDegrees(
Math.atan2(
(vectorA.perpDotProduct(vectorB)),
(vectorA.dotProduct(vectorB))
)
);
// Update the min and Max
if (angleBetweenVertices >= maxAngleBetweenVertices) {
maxVertex = vertex;
maxAngleBetweenVertices = angleBetweenVertices;
} else if (angleBetweenVertices <= minAngleBetweenVertices) {
minVertex = vertex;
minAngleBetweenVertices = angleBetweenVertices;
}
}
If I have an object with properties of x an y, how can I tell which point in an array is the closest without using the distance formula?
You can't get an accurate result without using some variant of the distance formula. But you can save a few cycles by not taking the square root after the fact; the comparison will remain valid.
r = dx2 + dy2
If you don't care about the exact distance, you could perhaps take the difference between the x and y coordinates of your source and destination points to provide you with some ordering.
//The following code does not return the closest point,
//but it somewhat does what you need and complies with
//your requirement to not use the distance formula
//it finds the sum of x and y displacements
Point destination=...
Point nearestPoint= points.get(0);
for (Point p : points){
closenessCoefficient= Math.abs(destination.x-p.x) + Math.abs(a.destination-p.y);
nearestPoint=Math.Min(closenessCoefficient, nearestPoint);
}
return nearestPoint;
If you have to find exactly the closest neighbour, there is no way around evaluating the distance formula, at least for a couple of points. As already pointed out, you can avoid evaluating the expensive sqrt for most of the time when simply comparing the distance-squared r^2 = x^2 + y^2.
However, if you have a big number of points spread out over a large range of distances, you can first use an approximation like the ones shown here http://www.flipcode.com/archives/Fast_Approximate_Distance_Functions.shtml . Then you can calculate the real distance formula only for the points closest as given by the approximation. On architectures where also the multiplication is expensive, this can make a big difference. On modern x86/x86-64 architectures this should not matter much though.