Use $within with a buffered MondoDB Linestring - mongodb

I need to evaluate the proximity of a Point to a LineString using MongoDB.
Because the $near operator can only compare a Point to another Point, I need to generate a polygon out of the LineString, so I can use the $within operator. The distance between the LineString and the edges of the polygon should represent the radius I want to search in, such as represented in red below:
What might be a useful algorithm in order to accomplish this?

I think much easier would be to write your own function
To find (perpendicular) distance between point and line and then creating thickness of poly-line by polygon means.
Where:
P0,P1 are line endpoints
P is point
d is distance between them
Line is defined as: p(t)=P0+(P1-P0)*t where t=<0.0,1.0>
So the function should do this:
create perpendicular line
q(t)=P+DQ*u where u=(-inf,+inf)
DQ is perpendicular vector to (P1-P0)
In 2D you can obtain it easily like this (x,y) -> (y,-x). In higher dimensions use cross product with some non coplanar vectors.
compute line vs. line intersection
there are tons of stuff about this so google or solve the equation yourself here you can extract mine implementation.
now after successful intersection
just compute d as distance between P and intersection point. Do not forget that parameter t must be in range. If not (or if no intersection) then return min(|P-P0|,|P-P1|)
[hints]
t and u parameters can be obtained directly from intersection test so if the perpendicular vector to (P1-P0) is normalized to size = 1 then the abs(u) parameter of intersection point is the distance
[notes]
I am not familiar with mongodb so if you have no means to use own tests inside then this answer is of coarse obsolete.

Unfortunately, MongoDB provides very basic geospatial query, so you should create the buffer by your own. You can read how to do it here: Computing a polygon that surrounds a multi-point line
If you have longitude/latitude coordinates like WGS84 you must adjust this code; Read here how to calculate distance between point on a sphere https://en.wikipedia.org/wiki/Haversine_formula

Related

Optimizing computation of distance to triangle using barycentric coordinates

Building on the discussions here and here. I'm trying to compute the shortest distance between a 3D line and a 3D triangle.
I'm using barycentric coordinates to determine whether or not the point is inside the triangle. So given a triangle defined by vertices UVW and a line defined by point AB, I first compute the intersection of line AB with the plane defined by UVW. Let's call this intersection P and assume I've already done the checks to verify whether or not the point actually intersects the plane at all.
I then compute barycentric coordinates (S,T) such that S is defined along the edge UV and T is defined along the edge UW. Naturally, if 0≤S and 0≤T and S+T≤1 then P is on the triangle (or its edge) and my distance to the triangle is obviously zero.
If that's not true then P is outside the triangle and I need to compute the distance. The guidance of from the first link says to project point P onto all three edges to get three candidate points. Adding those points to the three triangle's vertices, you then have six points to test against.
Isn't it easier than that, though? If T<0, then don't you already know that UV is the closest edge and you only have to test against the projection of P onto that line? Similarly, if S<0 then UW would be the closest edge. If T>0 and S>0 then VW is the closest edge.
Thus based on the signs of S and T you already know the closest edge and only have to compute the distance from P to its projection onto that edge. If the projection isn't inside the triangle, then the closest point is either vertex. Thus your computations are about 1/3 of the proposed methods.
Am I missing something here, or is this a valid optimization? I'm fairly new to barycentric coordinates and their attributes.
It turns out that the problem of closest distance from a point and from a line are very similar and can both be reduced to a pure 2D problem.
Distance from a point
By Pythagoras, the squared distance from a point to a point of the triangle is the sum of the squared distance to the plane of support of the triangle and the squared distance of the projection of the point to that plane.
The latter distance is precisely the distance from the normal line to the triangle.
Distance from a line
Looking in the direction of the line, you see the projected triangle and the line is reduced to a single point. The requested 3D distance is equal to the 2D distance seen on the projection.
To obtain the desired coordinates, you use an auxiliary coordinate frame such that Z is in the direction of the line (and XY is a perpendicular plane); for convenience, choose the origin of the new frame to be on the line. Then by just ignoring Z, you get a planar problem in XY. The change of coordinates is an affine tranformation.
Point vs. triangle
Consider the three triangles formed by the origin (projection of the point/line) and a pair of triangle vertices (taken in cyclic order). The signed area of these triangles is a mere 2x2 determinant.
If the three areas have the same sign, the point is inside. Otherwise, the signs tell you where you are among the six surrounding regions, either past an edge or past a vertex.
On the upper figure, the point is inside (three positive areas). On the other figure, it is outside of the top-right edge (one negative area). Also note that dividing an area by the length of the corresponding side, you get the distance to the side. (Factor 2 omitted.)
The total work is
compute the affine frame;
convert the coordinates of the 3 or 4 points;
compute the three signed areas;
if inside, you are done;
otherwise, if in an edge region, compute a distance to a line and two distances to points;
otherwise you are in a vertex region, compute two distances to lines and one distance to vertex.

How to find closest points between two convex hull in MATLAB?

In part of an Artificial Neural Network matlab code, I want to find nearest points of two convex polygons.
I saw
dsearchn(X,T,XI)
command's description here, but that finds closest points between two sets of points, and polygons (like convexs) have infinites points.
So can you suggest any way/idea?
Notice: I'm using MATLAB 2014a. I have the coordinate of each convex's vertex point.
If you are not happy with what is provided by dsearchn, then, If I were you, I would do one of two following:
Find Nearest Neighbours on the vertices (for example which vertex of
polygon A is the NN of a given vertex of polygon B).
Pick a random point inside polygon A (you may want to compute the
convex hull of A, but you may skip that and take into account only
the vertices you know already). That random point is the query. Find
an NN of that point from the vertices of polygon B.
You may want to ask in Software recommendations for more.
Edit:
Another approach is this:
Create a representative dataset of polygon A. Set the size of the dataset yourself and fill it with samples of points that lie inside the polygon. Choose them uniformly randomly inside the polygon.
Then take a point of polygon B (either a vertex or a random point inside polygon B) and that's the query point, for which you will seek Nearest Neighbour(s) inside the representative dataset of polygon A.
Of course that's just an approximation, but I can't think of something else now.
Notice that you can of course do the same for polygon B.
With This File in File Exchange, I've find the solution.
With a little code modification, I have drawn a perpendicular bisector which I wanted. Of course, this way is time consuming.

Find co-ordinates where LineString intersects a Polygon border in turfjs

Is there a way in Turfjs to determine the co-ordinates at which a LineString intersects with the border of a polygon?
There's a number of ways to find out if a point is within a polygon and a number of ways to find out if a point is on a line and so on, but I can't seem to figure out a way to ask "at what point does this line intersect this polygon's border".
I could enumerate the points in the polygon using a line intersection algorithm to find that point but I was wondering if there's a more "turf" way of doing this.
For context, I've loaded a GPX track and want to estimate the location/time at which the track enters/exits a defined area.
Because a GPX track only records locations at specific intervals it usually the case that pN recorded at time tN is outside the area and pN+1 recorded at time tN+1 is inside the area.
If I can get the point at which line (pN, pN+1) intersects the polygon's border I can estimate the exact time the track crosses into the polygon.
Ultimately, turfjs does not seem to have an API for doing this.
I was able to get the answer I wanted by enumerating the points in the polygon from the GeoJSON object to construct a sequence of line segments and then I used maxogden/geojson-js-utils linesIntersect function to test for intersection points.
I don't see a Turf function that does exactly that, but there is intersect, which finds the area of intersection between two polygons.
You could:
Construct a polygon by joining the line to itself reversed (so ABC becomes ABCBA)
Find the intersection of ABCBA and P, the original polygon using Intersect.
The intersection should be a zero-area polygon that is the part of ABCBA inside P. Somehow compute the length of it (strangely there's no perimeter function).
Subtract that length from the original length of ABC.
Not exactly elegant, true. :)
EDIT
Tried this. Turns out Turf-intersect doesn't return intersections if one of the polygons is zero-area.

Intersection of segment with polygon

I have to create a function in MATLAB that performs the following task:
Input:
p polygon in the form
p = [x1,y1; x2,y2; x3,y3; x4,y4...]
s struct with the segment from A to B
s = struct('A',[x,y],'B'[u,w])
Return:
1) An integer indicating how many intersections there are between the segment and the polygon (e.g., 0,1,2)
2) A new segment from A to B, where A is the first intersection or the initial point of the input segment and B the second point of the intersection or the last point of the segment input.
I have an idea on how to do it by using the function inpolygon. I have been reading how to use this function, and know that to use that, I should provide a query point and the coordinates of the polygon vertices. It will return 1 or 0 depending on whether it is inside or not.
My question is, how can I get the query point of the segment that is placed exactly in the boundary (in the case that the segment intersects with it)?
If you have the Mapping Toolbox installed, you could use polyxpoly. As this is a rather basic problem, there are quite a few free MATLAB-codes out there on the File Exchange. Here is what I found for the search term 'polygon intersect':
2D Polygon edges intersection by Bruno Luong
Find the intersection points of the edges of two 2D polygons, a simple function made to follow up a Newsgroup discussion
Curve Intersect 2 by Sebastian Hölz
This file is based on the Curve Intersect function by Duane Hanselman. It extends the scope of the function to handle arbitrary lines / polygons, which may also have vertical segments or segments with non-increasing x-values.
Curve intersections by NS
While a few other functions already exist in FEX that compute the
intersection points of curves, this short piece of code was written
with speed being the highest priority. No loops are used throughout,
taking full advantage of MATLAB's vectorization capabilities
Fast and Robust Curve Intersections by Douglas Schwarz
This function computes the (x,y) locations where two curves intersect. The curves can be broken with NaNs or have vertical segments. It is also very fast (at least on data that represents what I think is a typical application).
geom2d by David Legland
[...] derive new shapes: intersection between 2 lines, between a line and a circle, parallel and perpendicular lines

Calculate distance between coordinates but with restrictions

I managed to find the intersections of an arbitrary number of lines within a binary image.
Then i use a function where i detect the intersections between the lines. So now i have the coordinates of the intersections saved in an array.
Now i want to calculate the distance between the intersections(an imaginary line that connects all my intersections) but i want the distance calculation to traverse along the lines that are already on the binary image.
So the distance calculation cannot escape a line while calculating, instead it must ''walk along it''.
The imaginary path(of which eventually we calculate its distance) must walk along the already drawn lines.
EDIT** THIS IS MY INTERSECTION DETECTION ''ALGO''
clear all
pellara4=imread('C:/users/lemesios/desktop/pellara4.jpg');
blackwhitepellara=im2bw(pellara4,0.5);
I = blackwhitepellara;
C = corner(I);
num_of_rows=size(C,1);
num_of_cols=size(C,2);
for z =1:num_of_rows
k=C(z,2);
j=C(z,1);
if (I(k+1,j)==0)&& (I(k,j+1)==0) && (I(k-1,j)==0) && (I(k,j-1)==0)
imshow(I);
hold on
plot((j), (k), 'b*');
disp(k);
disp(j);
end
end
I feel this is similar to Dijkstra's algorithm. You can denote the intersection points by nodes. Then generate a mesh where each intersecting point is connected to every other intersecting point. Then if there exists a line in the binary image, assign a unit weight, otherwise assign inf i.e. infinite weight. When you have to measure distnace between m-th point and n-th point (say), then make m-th point as source and n-th point as destination and find the shortest path according to Dijkstra's algorithm.