How to calculate coordinates of N equidistant points along a straight line between 2 coordinates on a map? - maps

I have two points on a map -
val point1 : LatLng(13.3016139,77.4219107)
val point2 : LatLng(14.1788932,77.7613413)
I want to calculate and find 100 equidistant points along a straight line between these two coordinates. How do I do that?
ps. I'm sure this has been asked before, I just can't find it.

Equidistant, and more importantly, straight by which projection?
usually, to find a distance in cartesian space one would use something like the
Haversine formula to find a value, as previously answered in stack answer: How to convert latitude or longitude to meters?
As for the equidistant part, once you have the distance decided as per your taste of the shape and radius of Earth at given points, a simple division will do. .
python 3.7
>>> dist = 5427 #just some number
>>> nbr_o_points = 101
>>> points = [(dist/nbr_o_points)*(i+1) for i in range(nbr_o_points)]
>>> [f'{p:.2f}' for p in points]
['53.73', '107.47', '161.20',..., '5319.53', '5373.27', '5427.00']
Now to transfer these distances from point a to b back onto the desired projection... This is not part of your question... Stack - how-to-determine-vector-between-two-lat-lon-points might help.
take the vector and multiply by the dists in points in order to get your coordinates.

This is how I solved it -
fun findEquidistantPoints(latLng1: LatLng, latLng2: LatLng, pointCount: Int): ArrayList<LatLng> {
if (pointCount < 0)
throw IllegalArgumentException("PointCount cannot be less than 0")
val points = ArrayList<LatLng>()
val displacement = latLng1.displacementFromInMeters(latLng2)
val distanceBetweenPoints = displacement / (pointCount + 1)
for (i in 1..pointCount) {
val t = (distanceBetweenPoints * i) / displacement
points.add(LatLng(
(1 - t) * latLng1.latitude + t * latLng2.latitude,
(1 - t) * latLng1.longitude + t * latLng2.longitude
))
}
return points
}

Related

Take numbers form two intervals in concentric spheres in Julia

I am trying to take numbers from two intervals in Julia. The problem is the following,
I am trying to create concentric spheres and I need to generate vectors of dimension equal to 15 filled with numbers taken from each circle. The code is:
rmax = 5
ra = fill(0.0,1,rmax)
for i=1:rmax-1
ra[:,i].=rad/i
ra[:,rmax].= 0
end
for i=1:3
ptset = Any[]
for j=1:200
yt= 0
yt= rand(Truncated(Normal(0, 1), -ra[i], ra[i] ))
if -ra[(i+1)] < yt <= -ra[i] || ra[(i+1)] <= yt < ra[i]
push!(ptset,yt)
if length(ptset) == 15
break
end
end
end
end
Here, I am trying to generate spheres with uniform random numbers inside of each one; In this case, yt is only part of the construction of the numbers inside the sphere.
I would like to generate points in a sphere with radius r0 (ra[:,4] for this case), then points distributed from the edge of the first sphere to the second one wit radius r1 (here ra[:,3]) and so on.
In order to do that, I try to take elements that fulfill one of the two conditions -ra[(i+1)] < yt <= -ra[i]
or ra[(i+1)] <= yt < ra[i], i.e. I would like to generate a vector with positive and negative numbers. I used the operator || but it seems to take only the positive part. I am new in Julia and I am not sure how to take the elements from both parts of the interval. Does anyone has a hit on how to do it?. Thanks in advance
I hope I understood you correctly. First, we need to be able to sample uniformly from an N-dimensional shell with radii r0 and r1:
using Random
using LinearAlgebra: normalize
struct Shell{N}
r0::Float64
r1::Float64
end
Base.eltype(::Type{<:Shell}) = Vector{Float64}
function Random.rand(rng::Random.AbstractRNG, d::Random.SamplerTrivial{Shell{N}}) where {N}
shell = d[]
Δ = shell.r1 - shell.r0
θ = normalize(randn(N)) # uniformly distributed N-dimensional direction of length 1
r = shell.r0 .* θ # scale to a point on the interior of the shell
return r .+ Δ .* θ .* .√rand(N) # add a uniformly random segment between r0 and r1
end
(See here for more info about hooking into Random. You could equally implement a new Distribution, but that's not really necessary.)
Most importantly, a truncated normal will not result in a uniform distribution, but neither will adding a uniform scaling into the right direction: see here for why the square root is necessary (and I hope I got it right; you should check the math once more).
Then we can just create a sequence of shell samples with nested radii:
rmax = 5
rad = 10.0
ra = range(0, rad, length=rmax)
ptset = [rand(Shell{2}(ra[i], ra[i+1]), 15) for i = 1:(rmax - 1)]
(This part I wasn't really sure about, but the point should be clear.)

Connecting random points in MATLAB without intersecting lines

I need help with solving this problem. I have randomly generated points (example on Picture #1) and I want to connect them with lines (example on Picture #2). Lines can't be intersected and after connection, the connected points should look like an irregular area.
%Generating random points
xn = randi([3 7],1,10);
yn = randi([3 6],1,10);
%Generated points
xn = [6,3,7,7,6,6,6,4,6,3];
yn = [5,3,4,3,3,6,5,4,6,3];
Picture #1:
Result should be like this:
Picture #2:
Any idea how to solve this?
I suppose for the general case it can be very difficult to come up with a solution. But, assuming your points are scattered "nicely" there is quite a simple solution.
If you sort your points according to the angle above the x axis of the vector connecting the point and the center of the point cloud then:
P = [xn;yn]; %// group the points as columns in a matrix
c = mean(P,2); %// center point relative to which you compute the angles
d = bsxfun(#minus, P, c ); %// vectors connecting the central point and the dots
th = atan2(d(2,:),d(1,:)); %// angle above x axis
[st si] = sort(th);
sP = P(:,si); %// sorting the points
And that's about it. To plot the result:
sP = [sP sP(:,1)]; %// add the first point again to close the polygon
figure;plot( sP(1,:), sP(2,:), 'x-');axis([0 10 0 10]);
This algorithm will fail if several points has the same angle w.r.t the center of the point cloud.
An example with 20 random points:
P = rand(2,50);
You could adapt the code from another answer I gave for generating random simple polygons of an arbitrary number of sides. The difference here is you already have your set of points chosen and thus implicitly the number of sides you want (i.e. the same as the number of unique points). Here's what the code would look like:
xn = [6,3,7,7,6,6,6,4,6,3]; % Sample x points
yn = [5,3,4,3,3,6,5,4,6,3]; % Sample y points
[~, index] = unique([xn.' yn.'], 'rows', 'stable'); % Get the unique pairs of points
x = xn(index).';
y = yn(index).';
numSides = numel(index);
dt = DelaunayTri(x, y);
boundaryEdges = freeBoundary(dt);
numEdges = size(boundaryEdges, 1);
while numEdges ~= numSides
if numEdges > numSides
triIndex = vertexAttachments(dt, boundaryEdges(:,1));
triIndex = triIndex(randperm(numel(triIndex)));
keep = (cellfun('size', triIndex, 2) ~= 1);
end
if (numEdges < numSides) || all(keep)
triIndex = edgeAttachments(dt, boundaryEdges);
triIndex = triIndex(randperm(numel(triIndex)));
triPoints = dt([triIndex{:}], :);
keep = all(ismember(triPoints, boundaryEdges(:,1)), 2);
end
if all(keep)
warning('Couldn''t achieve desired number of sides!');
break
end
triPoints = dt.Triangulation;
triPoints(triIndex{find(~keep, 1)}, :) = [];
dt = TriRep(triPoints, x, y);
boundaryEdges = freeBoundary(dt);
numEdges = size(boundaryEdges, 1);
end
boundaryEdges = [boundaryEdges(:,1); boundaryEdges(1,1)];
x = dt.X(boundaryEdges, 1);
y = dt.X(boundaryEdges, 2);
And here's the resulting polygon:
patch(x,y,'w');
hold on;
plot(x,y,'r*');
axis([0 10 0 10]);
Two things to note:
Some sets of points (like the ones you chose here) will not have a unique solution. Notice how my code connected the top 4 points in a slightly different way than you did.
I made use of the TriRep and DelaunayTri classes, both of which may be removed in future MATLAB releases in favor of the delaunayTriangulation class.

Ansi C re-evaluating of Y coordinates

Im trying to do a graph from evalued math function and this is last think I need to do. I have graph with limit coordinates -250:-250 left down and 250:250 right up. I have Y-limit function, which is defined as -10:10, but it could be user redefined and if it is redefined, I need to calculate new coordinates.
I have now field of y-coordinates with 20000 values and each of is multiply by:
ratioY = 25 / (fabs( up-limit - down-limit ) / 20) which will make coordinates adapt for new Y-limit (if limit is -5:5, graph looks 2x bigger), this works good, but now isnt graph exactly where it should be (see pictures). Simply 25 is multiplied for postscript coordinates and (up-limit - down-limit) / 20 is ratio for "zooming" Y coordinates. This works fine.
Now Im trying to "move coordinates" which will subtracted from revaluated value:
ycoor = (ycoor * ratioY) - move-coorY ;.
Now I have something like this:
move-coorY = 25* ( ( up-limit - down-limit) /2 );
and it doesnt work correctly. I need to do sin(0) start from 0.
This is a correct graph which is -10:10
(source: matematika.cz)
This is a bad graph which is -5:10
(source: matematika.cz)
Maybe its easier not to do this with fixed numbers (like your ratioY) but with two different coordinate systems. Physical coordinates are in your problem domain, i.e. they are the real values of your sine curves. Logical coordinates refer to the device, in your case they are the point values in Postscript, but they might be pixels on a HTML canvas or whatever.
I'll denote the physical coordinates of the first axis with a small x and the corresponding logical coordinate with a capital X. In each coordinate system we have:
Lower bound: x_min, X_max
Upper bound: x_max, X_max
Range: dx = x_max - x_min
dX = X_max - X_min
Then you can calculate your logical coordinates from the physical ones:
X(x) = X_min + (x - x_min) * dX / dx
This also works vice versa, which is not an issue for Postscript files, but max be useful for an intractive canvas where a mouse click should yield the physical coordinates.
x(X) = x_min + (X - X_min) * dx / dX
In your case, the ratio or scale factor is dX / dx, which you can calculate once for each axis. Let's plot the first point with y == 0 in your first graph:
y_min = -10
y_max = 10
dy = 20
Y_min = -250
Y_max = 250
dX = 500
Y(0) = -250 + (0 - (-10)) * 500 / 20
= -250 + 10 * 500 / 20
= 0
In the second graph, the logical coordinates are the same, but:
y_min = -5
y_max = 10
dy = 15
Y(0) = -250 + (0 - (-5)) * 500 / 15
= -250 + 5 * 500 / 15
= -83.3333
If you change the range of your graph, e.g. from (-10, 10) to (-5, 10), just adjust the physical coordinates. If you resize your graph, change the logical coordinates. (Also, calculating the point in the graph is the same as calculating the position of the tick mark for the axis. Strangely, you got the tick marks right, but not your graph. I think your problem was to account for the non-zero lower bound in both graph and curve data.)
Also, it's probably better to re-evaluate the logical coordinates when printing instead of transfroming them from a previous plot. You can do that on the fly, so that you only need to keep the physical data in an array.
(And lastly, I'll admit that I'm not entirely sure these two kinds of cooirdinates are called physical and logical. I know these terms are used, but it may be the other way round or they might even mean sonething different altogether.)
My friend did a well yob for me and programmed this...
double zeroPosition(double startY, double endY){
double range = endY - startY;
double topSize = endY / range;
return 250.0 - 500 * topSize;
}
This will calculate position of zero, which I just add to my Y position with ratio and It works exactly how I need!
But thanks M Oehm ;)

2d trilateration

I am writing some code to participate in an AI challenge. The main objective for the AI challenge is to take a simulated robot and navigate it through a maze to a destination zone. The secondary objective which is optional is to find a recharger placed in the maze at an unknown location. This is all done in a 2D grid.
My program can call a method to get a distance measurement from the recharger. So using trilateration I should be able to locate the recharger by calling this method, recording my ai's current position and the distance the recharger is away from that point 3 times over.
I found this example of trilateration on wikipedia http://en.wikipedia.org/wiki/Trilateration but this applies to a 3d space. I'm only dealing with a 2D space. Also I don't understand how to use the formula shown in Wikipedia, searching the web for a working example with numbers plugged in and boiling down to the final coordinates is scarce with Google searches.
I'm not a math major; I am just an enthusiast exploring AI problems.
An explanation and step by step example of how to calculate the problem is what I need as mathematics are not my strong point. Below is some sample data:
Point 1: x=39, y=28, distance=8
Point 2: x=13, y=39, distance=11
Point 3: x=16, y=40, distance=8
Any example using my sample data would be greatly appreciated. The programming to this will be very straight forward once I can wrap my head around the mathematics.
As the Wikipedia trilateriation article describes, you compute (x,y) coordinates by successively calculating: ex, i, ey, d, j, x, y. You have to be familiar with vector notation, so, for example, ex = (P2 - P1) / ‖P2 - P1‖ means:
ex,x = (P2x - P1x) / sqrt((P2x - P1x)2 + (P2y - P1y)2)
ex,y = (P2y - P1y) / sqrt((P2x - P1x)2 + (P2y - P1y)2)
Your data is:
P1 = (39, 28); r1 = 8
P2 = (13, 39); r2 = 11
P3 = (16, 40); r3 = 8
The calculation steps are:
ex = (P2 - P1) / ‖P2 - P1‖
i = ex(P3 - P1)
ey = (P3 - P1 - i · ex) / ‖P3 - P1 - i · ex‖
d = ‖P2 - P1‖
j = ey(P3 - P1)
x = (r12 - r22 + d2) / 2d
y = (r12 - r32 + i2 + j2) / 2j - ix / j

MATLAB: Interpolating to find the x value of the intersection between a line and a curve

Here is the graph I currently have
:
The Dotted Blue line represented the y value that corresponds to the x value I am looking for. I am trying to find the x values of the line's intersections with the blue curve(Upper).Since the interesections do not fall on a point that has already been defined, we need to interpolate a point that falls onto the Upper plot.
Here is the information I have:
LineValue - The y value of the intersection and the value of the dotted line( y = LineValue)
Frequency - an array containing the x value coordinates seen on this plot. The interpolated values of Frequency that corresponds to LineValue are what we are looking for
Upper/Lower - arrays containing the y value info for this graph
This solution is an improvement on Amro's answer. Instead of using fzero you can simply calculate the intersection of the line by looking for transition in the first-difference of the series created by a logical comparison to LineValue. So, using Amro's sample data:
>> x = linspace(-100,100,100);
>> y = 1-2.*exp(-0.5*x.^2./20)./(2*pi) + randn(size(x))*0.002;
>> LineValue = 0.8;
Find the starting indices of those segments of consecutive points that exceed LineValue:
>> idx = find(diff(y >= LineValue))
idx =
48 52
You can then calculate the x positions of the intersection points using weighted averages (i.e. linear interpolation):
>> x2 = x(idx) + (LineValue - y(idx)) .* (x(idx+1) - x(idx)) ./ (y(idx+1) - y(idx))
x2 =
-4.24568579887939 4.28720287203057
Plot these up to verify the results:
>> figure;
>> plot(x, y, 'b.-', x2, LineValue, 'go', [x(1) x(end)], LineValue*[1 1], 'k:');
The advantages of this approach are:
The determination of the intersection points is vectorized so will work regardless of the number of intersection points.
Determining the intersection points arithmetically is presumably faster than using fzero.
Example solution using FZERO:
%# data resembling your curve
x = linspace(-100,100,100);
f = #(x) 1-2.*exp(-0.5*x.^2./20)./(2*pi) + randn(size(x))*0.002;
VALUE = 0.8;
%# solve f(x)=VALUE
z1 = fzero(#(x)f(x)-VALUE, -10); %# find solution near x=-10
z2 = fzero(#(x)f(x)-VALUE, 10); %# find solution near x=+10
%# plot
plot(x,f(x),'b.-'), hold on
plot(z1, VALUE, 'go', z2, VALUE, 'go')
line(xlim(), [VALUE VALUE], 'Color',[0.4 0.4 0.4], 'LineStyle',':')
hold off
Are the step sizes in your data series the same?
Is the governing equation assumed to be cubic, sinuisoidal, etc..?
doc interpl
Find the zero crossings

Resources