How to plot a marker away from another marker by 100 metres in Mapbox Leaflet? - leaflet

I am trying to plot a marker using Leaflet and then another marker away from the the first one by 100 metres. Plotting a marker is easy:
var marker = L.marker([0, 0]).addTo(map);
But now how do I plot another marker away from this one by a 100 metres?
Is there a way to convert metres to long and lat and then plotting it?
Or is there a better way already that I am not aware of?

I've forked your fiddle to show an example. It's based on these answers:
https://gis.stackexchange.com/questions/25877/how-to-generate-random-locations-nearby-my-location
var r = 100/111300 // = 100 meters
, y0 = original_lat
, x0 = original_lng
, u = Math.random()
, v = Math.random()
, w = r * Math.sqrt(u)
, t = 2 * Math.PI * v
, x = w * Math.cos(t)
, y1 = w * Math.sin(t)
, x1 = x / Math.cos(y0)
newY = y0 + y1
newX = x0 + x1

Related

Detect user is outside the GoogleMap route (perpendicular distance to path)

I am creating a simple navigation application using GoogleMap.
When the user set the start location and destination location I am drawing the path using polylines.
If the user deviate from the path, I want to redraw the path based on current user location.
Problem I have is how to detect user is not in the current route?
I am using
https://maps.googleapis.com/maps/api/directions/json?
to get the directions.
Is there a function in that to detect whether user is outside the route?
I also have the list of coordinates used to draw the poly lines.
Can they be used to detect user moved outside the current route ?
Based on an example I found in web, I created this method. The example is not designed to for the map coordinates.
Function for finding the distance between a point and an edge in java
Is there a better way of doing this?
static double perpendicularDistance(LatLng point, LatLng start, LatLng end) {
double x = point.longitude;
double y = point.latitude;
double x1 = start.longitude;
double y1 = start.latitude;
double x2 = end.longitude;
double y2 = end.latitude;
double A = x - x1;
double B = y - y1;
double C = x2 - x1;
double D = y2 - y1;
double dot = A * C + B * D;
double len_sq = C * C + D * D;
double param = -1;
if (len_sq != 0) //in case of 0 length line
param = dot / len_sq;
double xx, yy;
if (param < 0) {
xx = x1;
yy = y1;
} else if (param > 1) {
xx = x2;
yy = y2;
} else {
xx = x1 + param * C;
yy = y1 + param * D;
}
var dx = x - xx;
var dy = y - yy;
// one degree is equivalent to 111km approximately
return (sqrt(dx * dx + dy * dy)).abs() * 111000;
}
May be you need to get coordinates of user everytime he/she walks, and check if that coordinates lies in the list of coordinates which you have.
You can get location using https://pub.dev/packages/location.
These is just a thought, I can be wrong.
You can use this package
https://pub.dev/packages/google_maps_utils
with this method to check if you are not near of your route:
/// Computes whether the given point lies on or near a polyline, within a specified
/// tolerance in meters. The polyline is composed of great circle segments if geodesic
/// is true, and of Rhumb segments otherwise. The polyline is not closed -- the closing
/// segment between the first point and the last point is not included.
static bool isLocationOnPathTolerance(Point point, List<Point> polyline,
bool geodesic, double tolerance
)
Where point is, a class to represent two dimensional positions, for example;
var rightBottom = const Point(200, 400);
As you can see, you can send the tolerance for the distance in meters.

Unknown error in code to find the angle necessary for a rocket to land on the moon

I need to find the angle of a rocket given the conditions in the code that enables it to land on the moon. The moon is taken as stationary at the given coordinates. I assumed the only way to try would just be calculating the different velocity components and then inputting them for each angle from the minimum to the maximum, which is what I've tried to do.
Not sure why this isn't working - it just runs forever and doesn't output anything.
Thank you.
I have
v = 0.0066;
for angle = 0:.5:180
init_vel = [v*cosd(angle), v*sind(angle)];
init_pos = [3.7,0];
t = 10;
moon_pos = [0,222];
%simulate rocket
[tout, pos] = simulaterocketmovement(init_pos, init_vel, moon_pos, t);
if(length(tout)<99999)
break;
end
end
disp(angle);
plot(pos(:,1),pos(:,2));
where
function [ tout , pos ] = simulaterocketmovement ( init_pos , init_vel , moon_pos , t)
%Defining initial variables for later use
G = 9.63*10^-7;
Me = 83.3;
%Defining the two vectors we will use
x = init_pos(1);
y = init_pos(2);
vx = init_vel(1);
vy = init_vel(2);
%Need to create a seperate function that integrates to find the
%acceleration using Euler's second order method.
function a = acc(x,y)
ax = -(G*Me*x)/((x^2 + y^2)^1.5) - (G*(x-moon_pos(1)))/(((moon_pos(1)-x)^2 + (moon_pos(2)-y)^2)^1.5);
ay = -(G*Me*y)/((x^2 + y^2)^1.5) - (G*(y-moon_pos(2)))/(((moon_pos(1)-x)^2 + (moon_pos(2)-y)^2)^1.5);
%After finding the vector components, we put them in an acceleration vector.
a = [ax,ay];
end
%Now we find the values which result in the rocket landing on the moon. The
%range of values lie between xmin and xmax, and ymin and ymax. The +/-
%represents that the rocket can land anywhere on the moon's surface.
xmax = moon_pos(1) + 1;
xmin = moon_pos(1) - 1;
ymax = moon_pos(2) + 1;
ymin = moon_pos(2) - 1;
%For each time taken, to find the x and y values we need to use a while
%loop which works until the rocket is in the range of values for it to
%land on the moon.
while((x(end) > xmax) || (x(end) < xmin) || (y(end) < ymin) || (y(end) > ymax) )
%We assign temporary new values of x and y.
x(end+1) = x(end) + t*vx;
y(end+1) = y(end) + t*vy;
%Then we find the values of acceleration for both the old and new x and y
aold = acc(x(end-1), y(end-1));
anew = acc(x(end), y(end));
%Using this to find the new velocities
vxnew = vx + t*(aold(1)+anew(1))/2;
vynew = vy + t*(aold(2)+anew(2))/2;
%Final, more accurate values for x and y
x(end) = x(end-1) + t*(vxnew + vx)/2;
y(end) = y(end-1) + t*(vynew + vy)/2;
%And updating these as the new velocities
vx = vxnew;
vy = vynew;
end
%Then we construct a vector for the time steps, for the entire journey.
tout = 0:t:((length(x)-1)*t);
%And then create a position vector which includes the x and y positions.
pos = zeros(length(x),2);
pos(:,1) = x;
pos(:,2) = y;
end

Coordinates of the edge of a Mobius strip

Here is a Octave/Matlab code for generating a Mobius strip.
u = linspace(0,2*pi,100);
v = linspace(-1.0,1.0,100);
[u,v] = meshgrid(u,v);
x = (1+v.*cos(u/2)).*cos(u);
y = (1+v.*cos(u/2)).*sin(u);
z = v.*sin(u/2);
plot3(x,y,z)
The output is as follow.
In this, strip, I need the edge coordinates (XYZ). How I can get the XYZ coordinates of the edge?
plot3(x([1 end],:).',y([1 end],:).',z([1 end],:).', "b")
I could do this using python as follows. See a related post here
bLength=1.6
numPoints=10
radius = bLength*numPoints / (2 * np.pi)
theta = np.linspace(0,2*np.pi,numPoints,endpoint=False)
dtheta=theta[1]-theta[0]
x0,y0=(radius * np.cos(theta)), (radius * np.sin(theta))
x1,y1=(radius * np.cos(theta+dtheta/2)) , (radius * np.sin(theta+dtheta/2))
cons0=np.ones(x0.shape)*0
cons1=np.ones(x1.shape)*2
np.savetxt('cooRing00.csv',np.c_[x0,y0,cons0],delimiter=' ',fmt='%10f')
np.savetxt('cooRing01.csv',np.c_[x1,y1,cons1],delimiter=' ',fmt='%10f')

How can I plot a 3D-plane in Matlab?

I would like to plot a plane using a vector that I calculated from 3 points where:
pointA = [0,0,0];
pointB = [-10,-20,10];
pointC = [10,20,10];
plane1 = cross(pointA-pointB, pointA-pointC)
How do I plot 'plane1' in 3D?
Here's an easy way to plot the plane using fill3:
points=[pointA' pointB' pointC']; % using the data given in the question
fill3(points(1,:),points(2,:),points(3,:),'r')
grid on
alpha(0.3)
You have already calculated the normal vector. Now you should decide what are the limits of your plane in x and z and create a rectangular patch.
An explanation : Each plane can be characterized by its normal vector (A,B,C) and another coefficient D. The equation of the plane is AX+BY+CZ+D=0. Cross product between two differences between points, cross(P3-P1,P2-P1) allows finding (A,B,C). In order to find D, simply put any point into the equation mentioned above:
D = -Ax-By-Cz;
Once you have the equation of the plane, you can take 4 points that lie on this plane, and draw the patch between them.
normal = cross(pointA-pointB, pointA-pointC); %# Calculate plane normal
%# Transform points to x,y,z
x = [pointA(1) pointB(1) pointC(1)];
y = [pointA(2) pointB(2) pointC(2)];
z = [pointA(3) pointB(3) pointC(3)];
%Find all coefficients of plane equation
A = normal(1); B = normal(2); C = normal(3);
D = -dot(normal,pointA);
%Decide on a suitable showing range
xLim = [min(x) max(x)];
zLim = [min(z) max(z)];
[X,Z] = meshgrid(xLim,zLim);
Y = (A * X + C * Z + D)/ (-B);
reOrder = [1 2 4 3];
figure();patch(X(reOrder),Y(reOrder),Z(reOrder),'b');
grid on;
alpha(0.3);
Here's what I came up with:
function [x, y, z] = plane_surf(normal, dist, size)
normal = normal / norm(normal);
center = normal * dist;
tangents = null(normal') * size;
res(1,1,:) = center + tangents * [-1;-1];
res(1,2,:) = center + tangents * [-1;1];
res(2,2,:) = center + tangents * [1;1];
res(2,1,:) = center + tangents * [1;-1];
x = squeeze(res(:,:,1));
y = squeeze(res(:,:,2));
z = squeeze(res(:,:,3));
end
Which you would use as:
normal = cross(pointA-pointB, pointA-pointC);
dist = dot(normal, pointA)
[x, y, z] = plane_surf(normal, dist, 30);
surf(x, y, z);
Which plots a square of side length 60 on the plane in question
I want to add to the answer given by Andrey Rubshtein, his code works perfectly well except at B=0. Here is the edited version of his code
Below Code works when A is not 0
normal = cross(pointA-pointB, pointA-pointC);
x = [pointA(1) pointB(1) pointC(1)];
y = [pointA(2) pointB(2) pointC(2)];
z = [pointA(3) pointB(3) pointC(3)];
A = normal(1); B = normal(2); C = normal(3);
D = -dot(normal,pointA);
zLim = [min(z) max(z)];
yLim = [min(y) max(y)];
[Y,Z] = meshgrid(yLim,zLim);
X = (C * Z + B * Y + D)/ (-A);
reOrder = [1 2 4 3];
figure();patch(X(reOrder),Y(reOrder),Z(reOrder),'r');
grid on;
alpha(0.3);
Below Code works when C is not 0
normal = cross(pointA-pointB, pointA-pointC);
x = [pointA(1) pointB(1) pointC(1)];
y = [pointA(2) pointB(2) pointC(2)];
z = [pointA(3) pointB(3) pointC(3)];
A = normal(1); B = normal(2); C = normal(3);
D = -dot(normal,pointA);
xLim = [min(x) max(x)];
yLim = [min(y) max(y)];
[Y,X] = meshgrid(yLim,xLim);
Z = (A * X + B * Y + D)/ (-C);
reOrder = [1 2 4 3];
figure();patch(X(reOrder),Y(reOrder),Z(reOrder),'r');
grid on;
alpha(0.3);

Finding min/max of quadratic bezier with CoreGraphics

I am using CoreGraphics to draw a quadratic bezier but want to computer the min/max value of the curve. I am not from a mathematical background so this has become a bit troublesome. Does anyone have any articles or ideas about how to solve this?
For a quadratic Bezier, this is actually quite simple.
Define your three control points as P0 = (x0,y0), P1 = (x1,y1) and P2 = (x2,y2). To find the extrema in x, solve this equation:
t = (x0 - x1) / (x0 - 2*x1 + x2)
If 0 <= t <= 1, then evaluate your curve at t and store the location as Px. Do the same thing for y:
t = (y0 - y1) / (y0 - 2*y1 + y2)
Again, if 0 <= t <= 1, evaluate your curve at t and store the location as Py. Finally, find the axis-aligned bounding box containing P0, P2, Px (if found) and Py (if found). This bounding box will also tightly bound your 2D quadratic Bezier curve.
Calculus gives the standard box of tricks for finding the min/max of continuous, differentiable curves.
Here is a sample discussion.
I have made a representation of this in javascript:
Jsfiddle link
function P(x,y){this.x = x;this.y = y; }
function pointOnCurve(P1,P2,P3,t){
if(t<=0 || 1<=t || isNaN(t))return false;
var c1 = new P(P1.x+(P2.x-P1.x)*t,P1.y+(P2.y-P1.y)*t);
var c2 = new P(P2.x+(P3.x-P2.x)*t,P2.y+(P3.y-P2.y)*t);
return new P(c1.x+(c2.x-c1.x)*t,c1.y+(c2.y-c1.y)*t);
}
function getQCurveBounds(ax, ay, bx, by, cx, cy){
var P1 = new P(ax,ay);
var P2 = new P(bx,by);
var P3 = new P(cx,cy);
var tx = (P1.x - P2.x) / (P1.x - 2*P2.x + P3.x);
var ty = (P1.y - P2.y) / (P1.y - 2*P2.y + P3.y);
var Ex = pointOnCurve(P1,P2,P3,tx);
var xMin = Ex?Math.min(P1.x,P3.x,Ex.x):Math.min(P1.x,P3.x);
var xMax = Ex?Math.max(P1.x,P3.x,Ex.x):Math.max(P1.x,P3.x);
var Ey = pointOnCurve(P1,P2,P3,ty);
var yMin = Ey?Math.min(P1.y,P3.y,Ey.y):Math.min(P1.y,P3.y);
var yMax = Ey?Math.max(P1.y,P3.y,Ey.y):Math.max(P1.y,P3.y);
return {x:xMin, y:yMin, width:xMax-xMin, height:yMax-yMin};
}