georeferenced points in python, if we know relative coordinates - coordinates

I have a square with relative coordinates (that are known)
(x1,y2)--------(x2,y2)
| |
| |
(x1,y1)--------(x1,y2)
Those points have known GPS coordinates (in projected system).
What kind of transformation do I need to apple to x1,y1,x2,y2, so I can bring the relative coordinates to absolute?
In other words, if x1=0, y1=0, x2=20,y=20 and I know that (x1,y1)-->(utm_x,utm_y)
P.S.
Apparently, I do not care about the corners, But in my square grid, there are 100s of xy pairs, that need to be rotated.
EDIT:
I think I figure it out
I calculate the arctan between the two points
l1=np.abs(x[4]-x[1])
l2=np.abs(y[4]-y[1])
alpha=np.arctan2(l2,l1)
Every point(p1,p2) along the grid
new_x=p1*np.cos(-alpha) - (p2)*np.sin(-alpha) + x[4]
new_y=p1*np.sin(-alpha) + p2*np.cos(-alpha) + y[4]

Ok, see the solution in the edited post.
I calculate the arctan between the two points (x4,y4) (x1,y1) from GPS coordinates
l1=np.abs(x[4]-x[1])
l2=np.abs(y[4]-y[1])
alpha=np.arctan2(l2,l1)
Every point(p1,p2) along the grid
new_x=p1*np.cos(-alpha) - (p2)*np.sin(-alpha) + x[4]
new_y=p1*np.sin(-alpha) + p2*np.cos(-alpha) + y[4]
Pay attention to direction of bearing.

Related

Moving least squares fitting for point displacements having issues

Explanation of the problem:
I have points with (x,y,z) coordinates at two+ distinct times. For convenience, they can be imagined as irregularly spaced points along the surface of an inverted paraboloid.
There is some minimal thickness to the paraboloid. The paraboloid changes shape slightly as time proceeds (like a balloon inflating) and when it does so, all of the points move.
By substracting the coordinates at time2 - time1, I can get the displacement vectors at each point.
It is important to note (and I suspect this might be the source of the problem) that at the first time point, the x and y coordinates range from 0 to 2000, and the z coordinates are all within a narrower range - say 350 to 450. During the deformation, each point has an x component of displacement, y component, and z component.
The x and y components are small (~50 at most), while the z component is the largest (goes up to 400 near the center, much less near the edges).
Using weighted moving least squares at the location of each point, I am trying to fit the components of displacements to a second degree polynomial surface in terms of the original x,y,z coordinates of the point: eg.
x component of
displacement = ax^2 + bxy + cx + dy^2.. + hz^2 + iz + j
I use the lsqr function in MATLAB,like so, looping through each point for each time interval:
Ux = displacements{k,1}(:,1);
Cx = lsqr((adjust_B_matrix'*W*adjust_B_matrix),(adjust_B_matrix'*W*Ux),1e-7,10000);
W is the weight matrix, and adjust_B_matrix is the matrix of all (x,y,z) coordinates at time 1, shifted so that they're all centered around the point at which I'm trying to fit the function.
What is going wrong?
It's just not working -- once I have the functions, they're re-centered around the actual coordinates of the points.
But once I plot the resulting points (initial pointx + displacementx, initial pointy + displacementy, initial pointz + displacementz) by plugging in the coordinates at time 1 into the now-discovered functions, it just spits out a surface that looks just like the surface at time 1.
What might be going wrong? Things I have tried:
It's not an issue with the code itself- I generated 'fake' data using a grid of points and it worked perfectly. The predicted locations were superimposed with the actual coordinates and I was able to get back the function I started with. But in my trial example, I used x,y,z from 0 to 5, evenly spaced.
Global fitting works (but I need local fitting...).
I tried MATLAB's curve fitting toolbox and just tried to fit one of the displacements to only x and y coordinates, globally. It worked perfectly.
I think I shouldn't have a singular matrix issue because I use a large radius (around 75-80) points in the calculations, somewhat dispersed in 3D space.
Suspicions:
I think it has to do with the uneven distribution of initial (x,y,z) coordinates, but I don't know why or how to fix the issue, or even what method I can use.
If you read this far, thank you so much. Any advice would be greatly appreciated.
Figure for reference:
green = predicted points at time 2. Overlapping mostly with red, the actual coordinates of the points at time 1.
blue is the correct coordinates of points at time 2 (this is where the green ones should be if things were working).
image
Updated link for files:
http://a.tmp.ninja/eWfkNmFZyTFk.zip
Contents - code, sample data (please load the .mat files).
I can't actually access the code you posted, so here's some general suggestions.
It does look like the curve fitting toolbox has tools that do exactly what you are looking for, checkout the bottom of this page: https://www.mathworks.com/help/curvefit/polynomial.html#bt9ykh.
It looks like for whatever your learned function for the displacement is just very small or zero everywhere. I suspect the issue is just a minor typo/error on your part somewhere in your pipeline, possibly translating what you have to work with the fit function will reveal the issue.
This really shouldn't be the issue, but in the future if you had much more unbalanced data you could normalize it all before fitting (x_norm = (x - x_mu)/x_std).
Also, I don't think this is your problem either, but you can check if your matrix is close to singular by checking the condition number using the cord() function. So you could check cond(adjust_B_matrix'Wadjust_B_matrix). Second, If you check the documentation for lsqr there is an option to get a debug return flag, that is worth checking too.

Arrange the vertices of a 3D convex polygonal plane in counter clockwise direction in MATLAB

I have a convex polygon in 3D. For simplicity, let it be a square with vertices, (0,0,0),(1,1,0),(1,1,1),(0,0,1).. I need to arrange these vertices in counter clockwise order. I found a solution here. It is suggested to determine the angle at the center of the polygon and sort them. I am not clear how is that going to work. Does anyone have a solution? I need a solution which is robust and even works when the vertices get very close.
A sample MATLAB code would be much appreciated!
This is actually quite a tedious problem so instead of actually doing it I am just going to explain how I would do it. First find the equation of the plane (you only need to use 3 points for this) and then find your rotation matrix. Then find your vectors in your new rotated space. After that is all said and done find which quadrant your point is in and if n > 1 in a particular quadrant then you must find the angle of each point (theta = arctan(y/x)). Then simply sort each quadrant by their angle (arguably you can just do separation by pi instead of quadrants (sort the points into when the y-component (post-rotation) is greater than zero).
Sorry I don't have time to actually test this but give it a go and feel free to post your code and I can help debug it if you like.
Luckily you have a convex polygon, so you can use the angle trick: find a point in the interior (e.g., find the midpoint of two non-adjacent points), and draw vectors to all the vertices. Choose one vector as a base, calculate the angles to the other vectors and order them. You can calculate the angles using the dot product: A · B = A B cos θ = |A||B| cos θ.
Below are the steps I followed.
The 3D planar polygon can be rotated to 2D plane using the known formulas. Use the one under the section Rotation matrix from axis and angle.
Then as indicated by #Glenn, an internal points needs to be calculated to find the angles. I take that internal point as the mean of the vertex locations.
Using the x-axis as the reference axis, the angle, on a 0 to 2pi scale, for each vertex can be calculated using atan2 function as explained here.
The non-negative angle measured counterclockwise from vector a to vector b, in the range [0,2pi], if a = [x1,y1] and b = [x2,y2], is given by:
angle = mod(atan2(y2-y1,x2-x1),2*pi);
Finally, sort the angles, [~,XI] = sort(angle);.
It's a long time since I used this, so I might be wrong, but I believe the command convhull does what you need - it returns the convex hull of a set of points (which, since you say your points are a convex set, should be the set of points themselves), arranged in counter-clockwise order.
Note that MathWorks recently delivered a new class DelaunayTri which is intended to superseded the functionality of convhull and other older computational geometry stuff. I believe it's more accurate, especially when the points get very close together. However I haven't tried it.
Hope that helps!
So here's another answer if you want to use convhull. Easily project your polygon into an axes plane by setting one coordinate zero. For example, in (0,0,0),(1,1,0),(1,1,1),(0,0,1) set y=0 to get (0,0),(1,0),(1,1),(0,1). Now your problem is 2D.
You might have to do some work to pick the right coordinate if your polygon's plane is orthogonal to some axis, if it is, pick that axis. The criterion is to make sure that your projected points don't end up on a line.

HTML5 Canvas: get curve's coordinates

I have a quadratic curve in canvas (defined by start, end and control point). What I need is to get more of the curve's coordinates (eg. the middle, quarters etc.). With that, I'd be able (after a few iterations of finding coordinates) to animate an object based on this curve (I know it can be done easily with SVG, but that's not an option).
image taken from http://www.html5canvastutorials.com/tutorials/html5-canvas-quadratic-curves/
Is there an easy way to do this? When I checked for bisecting curve on google, the only thing I found was some complicated Math including drawing, which is out of the question.
These functions may be of interest to you:
Kinetic.Path.getPointOnCubicBezier = function(pct, P1x, P1y, P2x, P2y, P3x, P3y, P4x, P4y)
Kinetic.Path.getPointOnQuadraticBezier = function(pct, P1x, P1y, P2x, P2y, P3x, P3y)
I am seeking a similar solution for bezier curves. How do I get a list of the coordinates on the curve?
To solve your problem, perhaps you could plugin the x-coordinate (or y-coordinate) into the quadratic equation:
y = a*x^2 + b*x + c
I can't seem to find a function that returns the coordinates of the curve. It would be nice to get a list of the coordinates for any curve / shape.

Get intermediate points over a MKPolyline

I have a MKPolyline with two points (a start and an ending point), on a MKMapView. Is there any way to get some intermediate points (or coordinates) along with the line, or to split the line in many segments?
I want something like this: http://i.imgur.com/qcbS9.png, where the black endpoints are the starting and ending points of the line and red points are the ones who I want to get. Sorry for the bad drawing, but I made it in an online drawing tool.
Thank you
Are the lines you're interpolating quite short, geographically? If so you can just scale linearly along the line. If you want 10 segments then work out the difference between the start and end point's latitude values and same for the longitude. After your existing start point the next point will be (lat + 0.1*latDif, lng + 0.1*lngDif), then (lat + 0.2*latDif, lng + 0.2*lngDif). All pretty simple so long as you're prepared to assume the coordinates exist in a uniform grid, which they don't really but it might be fine if you're using it on a city-scale map.

Dividing a geographic region

I have a certain geographic region defined by the bottom left and top right coordinates. How can I divide this region into areas of 20x20km. I mean in practial the shape of the earth is not flat it's round. The bounding box is just an approximation. It's not even rectangular in actual sense. It's just an assumption. Lets say the bottomleft coordinate is given by x1,y1 and the topright coordinate is given by x2,y2, the length of x1 to x2 at y1 is different than that of the length between x1 to x2 at y2. How can I overcome this issue
Actually, I have to create a spatial meshgrid for this region using matlab's meshgrid function. So that the grids are of area 20x20km.
meshgrid(x1:deltaY:x2,y1:deltaX:y2)
As you can see I can have only one deltaX and one deltaY. I want to choose deltaX and deltaY such that the increments create grid of size 20x20km. However this deltaX and deltaY are supposed to vary based upon the location. Any suggestions?
I mean lets say deltaX=del1. Then distance between points (x1,y1) to (x1,y1+del1) is 20km. BUt when I measure the distance between points (x2,y1) to (x2, y1_del1) the distance is < 20km. The meshgrid function above does creates mesh. But the distances are not consistent. Any ideas how to overcome this issue?
Bear in mind that 20km on the surface of the earth is a REALLY short distance, about .01 radians - so the area you're looking at would be approximated as flat for anything non-scientific. Assuming it is scientific...
To get something other than monotonic steps in meshgrid you should create a function which takes as its input your desired (x,y) and maps it relative to (x_0,y_0) and (x_max,y_max) in your units of choice. Here's an inline function demonstrating the idea of using a function for meshgrid steps
step=inline('log10(x)');
[x,y]=meshgrid(step(1:10),step(1:10));
image(255*x.*y)
colormap(gray(255))
So how do you determine what the function should be? That's hard for us to answer exactly without a little more information about what your data set looks like, how you're interacting with it, and what your accuracy requirements are. If you have access to the actual location at every point, you should vary one dimension at a time (if your data grid is aligned with your latitude grid, for example) and use a curve fit with model selection techniques (akaike/bayes criterion) to find the best function for your data.