Find X location using 3 known (X,Y) location using trilateration - trilateration

trying to understand the maths behind trilateration, we have 3 access points (AP 1,2,3) and we know the centre coordinates of theses 3 (AP). Lost device (X) is the location where all 3 circle intersect.
example GRID = x=30, y=30.
Known Locations: AP1 = (5,5), AP2 = (5,15), AP3 = (20,10).
Unknown Location: X
Lets say X = (9,11)
how do we work out the intersection of all 3 circles by the maths.
your help is greatly appreciated.

Related

Pytorch parallel functional calls for multiple locations in a tensor

Does anyone know if there is a function in PyTorch that allows you to call a particular function for all the locations in a tensor where a condition is satisfied?
For example, for all the locations in a tensor where the value is equal to 100, a function has to be called without using any for loops. I want to modify other tensors for these locations. I know I can just get the list of locations and then call the function for each location but I want to avoid that. Thank you for your help.
Something like torch.where(a==100,function1())
Adding more details after the request in the comments:
function1(x,y): #(x,y) are co-ordinates
... some code based on (x,y)...
a[x,y] = 20
b[x,y] = 10
Let's assume we have 2 2D(single row) tensors a = [1 2 100 100 5 6 200 8 2] and b=[3 4 5 5 6 10 3 8 9].
Now I want to pass the coordinates of where a == 100 in our case (0,2) and (0,3) to function1 and modify the values of a and b at those locations. I hope this helps.

Retrieving JSON data from the osmbuildings.org data site

I am trying to retrieve building data from osmbuildings.org
The osmbuildings documentation (https://osmbuildings.org/documentation/data/) features an example URL (https://data.osmbuildings.org/0.2/anonymous/tile/15/17605/10743.json) that returns the JSON file for buildings that are located in Berlin at roughly 52°32'30.6"N 13°25'23.2"E coordinates.
Can I use this same site to get a JSON file for buildings in a different location? For example, I believe the X,Y coordinates using XYZ tile coordinates would be 25835 and 5221 for a location in Singapore for a zoom of 15 and the corresponding url would be https://data.osmbuildings.org/0.2/anonymous/tile/15/25835/5221.json.
However, when I put this into the web browser, I don't get the json file like in the Berlin case. Can someone please explain?
I also tried different zoom values at the same location:
https://data.osmbuildings.org/0.2/anonymous/tile/16/51672/8779.json
And at a slightly different location with fewer buildings:
https://data.osmbuildings.org/0.2/anonymous/tile/16/51666/9459.json
If you do not get the JSON file, you are probably getting an empty reply. This is likely because your specified tile does not contain any building data.
This can have various reasons, e.g. there are regions where no building data is available. In your case however, it seems to me that your conversion into X,Y coordinates is not correct for Singapore.
In my following example, I use the coordinates for the Singapore Marina Bay (https://www.openstreetmap.org/#map=15/1.2742/103.8617).
I converted the lon/lat to tile numbers using the formula from the OSM wiki (https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames). In pseudo code:
n = 2 ^ zoom
xtile = n * ((lon_deg + 180) / 360)
ytile = n * (1 - (ln(tan(lat_rad) + sec(lat_rad)) / π)) / 2
= n * (1 - (ln(tan(lat_rad) + (1 / cos(lat_rad))) / π)) / 2
Filling in the according lon = 103.8617 and lat = 1.2742 and zoom = 15, you get:
n = 2^15
= 32768
xtile = 32768 * ((103.8617 + 180) / 360)
= 25837.722737778
ytile = 32768 * (1 - (ln(tan(1.2742) + (1 / cos(1.2742))) / π)) / 2
= 16268.009923134
Disregarding the decimals, we get X = 25837 and Y = 16268. Making this into a link (according to https://osmbuildings.org/documentation/data/), we get
https://data.osmbuildings.org/0.2/anonymous/tile/15/25837/16268.json
which does return JSON data for some 40 buildings.
This also worked fine for me on other zoom levels. E.g. zooming in on the famous "Marina Bay Sands" (https://www.openstreetmap.org/#map=17/1.28338/103.86148) and calculating the link according to the pseudo-code above, I get:
https://data.osmbuildings.org/0.2/anonymous/tile/17/103350.810851556/65068.69652388.json
which returns a JSON that contains named buildings such as "Marina Bay Sands Tower 1", "Marina Bay Sands Tower 2", etc., which shows it worked as intended.

Problem with combining ForwardDiff and PyPlot in Julia 1.0.5

In Julia 1.0.5, I have a function f(x::Vector{<:Real}), defined as
f(x::Vector{<:Real}) = (x[1] - 2)^2 + ( x[2] - 1 )^2
The signature is like this, because I would like to use it with the ForwardDiff package, and it works with it just fine. I give the function to ForwardDiff.gradient, and everything works like a charm.
However, I would also like to do some visualizations with PyPlot, using this same function f. Namely, I would like to draw its contour with contourf. For this purpose, I have constructed two vectors X::Vector{<:Real} and Y::Vector{<:Real}, and would like to call the same function f with them to produce the contour.
However, making the call f.([X, Y]) is not broadcasting the vectors as I would like, as I get the error
LoadError: MethodError: no method matching (::getfield(Main, Symbol("#f#1044")))(::Int64)
Closest candidates are:
f(!Matched::Array{#s25,1} where #s25<:Real)
This of course prevents me from using the contourf function, as it needs the values of f on a 2D-grid.
Do I need to define an entirely different f(x::Vector{<:Real}, y::Vector{<:Real}) to be able to plot the contour as I would like, or is there an alternative where I can avoid this?
this problem can be resolved by the power of multiple dispatch:
f(x::Vector{<:Real}) = (x[1] - 2)^2 + ( x[2] - 1 )^2
f(x::Real,y::Real) = f([x,y])
nx = 10
ny = 20
X = rand(nx) #mesh of x points
Y = rand(ny) #mesh of y points
Z = f.(transpose(X),Y) #nx x ny matrix
for the two argument gradient:
two_point_gradient(f,x,y) = ForwardDiff.gradient(f,[x,y])
G = two_point_gradient.(f,transpose(X),Y) #returns a vector of gradients, where G[i..] = gradient(f,X[i..],Y[i...])

Dividing N points in a 2-D graph into 2 groups

Suppose there are N points in a 2-D graph.Each point has some weight attached to it.I am required to draw a straight line such a way that the line divides the points into 2 groups such that total weight(sum of weight of points in that group) of part with smaller weight be as many as possible.My task is to find this value.How to go about it ?
Note:No three points lie on the same line.
This is not a homework or part of any contest.
You could just scan over all angles and offsets until you find the optimal solution.
For ease of computation, I would rotate all the points with a simple rotation matrix to align the points with the scanline, so that you only have to look at their x coordinates.
You only have to check half a circle before the scanline doubles up on itself, that's an angle of 0 to PI assuming that you're working with radians, not degrees. Also assuming that the points can be read from the data as some kind of objects with an x, y and weight value.
Pseudocode:
Initialize points from input data
Initialize bestDifference to sum(weights of points)
Initialize bestAngle to 0
Initialize bestOffset to 0
Initialize angleStepSize to an arbitrary small value (e.g. PI/100)
For angle = 0:angleStepSize:PI
Initialize rotatedpoints from points and rotationMatrix(angle)
For offset = (lowest x in rotatedpoints) to (highest x in rotatedpoints)
weightsLeft = sum of the weights of all nodes with x < offset
weightsRight = sum of the weights of all nodes with x > offset
difference = abs(weightsLeft - weightsRight)
If difference < bestDifference
bestAngle = angle
bestOffset = offset
bestDifference = difference
Increment angle by stepsize
Return bestAngle, bestOffset, bestDifference
Here's a crude Paint image to clarify my approach:

Create a function to generate random points in a parallelogram

I hope someone can help me here, I have been asked to write some code for an Lua script for a game. Firstly i am not an Lua Scripter and I am defiantly no mathematician.
What i need to do is generate random points within a parallelogram, so over time the entire parallelogram becomes filled. I have played with the scripting and had some success with the parallelogram (rectangle) positioned on a straight up and down or at 90 degrees. My problem comes when the parallelogram is rotated.
As you can see in the image, things are made even worse by the coordinates originating at the centre of the map area, and the parallelogram can be positioned anywhere within the map area. The parallelogram itself is defined by 3 pairs of coordinates, start_X and Start_Y, Height_X and Height_Y and finally Width_X and Width_Y. The random points generated need to be within the bounds of these coordinates regardless of position or orientation.
Map coordinates and example parallelogram
An example of coordinates are...
Start_X = 122.226
Start_Y = -523.541
Height_X = 144.113
Height_Y = -536.169
Width_X = 128.089
Width_Y = -513.825
In my script testing i have eliminated the decimals down to .5 as any smaller seems to have no effect on the final outcome. Also in real terms the start width and height could be in any orientation when in final use.
Is there anyone out there with the patients to explain what i need to do to get this working, my maths is pretty basic, so please be gentle.
Thanks for reading and in anticipation of a reply.
Ian
In Pseudocode
a= random number with 0<=a<=1
b= random number with 0<=b<=1
x= Start_X + a*(Width_X-Start_X) + b*(Height_X-Start_X)
y= Start_Y + a*(Width_Y-Start_Y) + b*(Height_Y-Start_Y)
this should make a random point at coordinates x,y within the parallelogram
The idea is that each point inside the parallelogram can be specified by saying how far you go from Start in the direction of the first edge (a) and how far you go in the direction of the second edge (b).
For example, if you have a=0, and b=0, then you do not move at all and are still at Start.
If you have a=1, and b=0, then you move to Width.
If you have a=1, and b=1, then you move to the opposite corner.
You can use something like "texture coordinates", which are in the range [0,1], to generate X,Y for a point inside your parallelogram. Then, you could generate random numbers (u,v) from range [0,1] and get a random point you want.
To explain this better, here is a picture:
The base is formed by vectors v1 and v2. The four points A,B,C,D represent the corners of the parallelogram. You can see the "texture coordinates" (which I will call u,v) of the points in parentheses, for example A is (0,0), D is (1,1). Every point inside the parallelogram will have coordinates within (0,0) and (1,1), for example the center of the parallelogram has coordinates (0.5,0.5).
To get the vectors v1,v2, you need to do vector subtraction: v1 = B - A, v2 = C - A. When you generate random coordinates u,v for a random point r, you can get back the X,Y using this vector formula: r = A + u*v1 + v*v2.
In Lua, you can do this as follows:
-- let's say that you have A,B,C,D defined as the four corners as {x=...,y=...}
-- (actually, you do not need D, as it is D=v1+v2)
-- returns the vector a+b
function add(a,b)
return {x = a.x + b.x, y = a.y + b.y} end
end
-- returns the vector a-b
function sub(a,b)
return {x = a.x - b.x, y = a.y - b.y} end
end
-- returns the vector v1*u + v2*v
function combine(v1,u,v2,v)
return {x = v1.x*u + v2.x*v, y = v1.y*u + v2.y*v}
end
-- returns a random point in parallelogram defined by 2 vectors and start
function randomPoint(s,v1,v2)
local u,v = math.random(), math.random() -- these are in range [0,1]
return add(s, combine(v1,u,v2,v))
end
v1 = sub(B,A) -- your basis vectors v1, v2
v2 = sub(C,A)
r = randomPoint(A,v1,v2) -- this will be in your parallelogram defined by A,B,C
Note that this will not work with your current layout - start, width, height. How do you want to handle rotation with these parameters?