Assume we have a point cloud A of size 4xN including some points A1,...,An in 3D space. each point is a 4x1 vector (x,y,z,1). this point cloud is fully known. we have the points' position in space.
Then, someone applies an arbitrary 4x4 rigid transformation matrix T to the point cloud. so the result would be a new point cloud B = TA. obviously, each point in B have a correspondence in A. so for example, B1 corresponds to A1, and Bn corresponds to An.
Now the problem is that we need to obtain the transformation matrix. But the only information we have is the euclidian distance between A and B. in particular, we have N distances A1B1, A2B2, ..., AnBn.
How can we obtain the transformation matrix T by only knowing the euclidian distance between the corresponding points?
take a look at the following figure as an illustration:
Related
For 2-dimensional sampled curves (an array of 2D points) there exists the Rahmer-Douglas-Peucker algorithm which only keeps "important" points. It works by calculating the perpendicular distance of each point (or sample) to a line that connects the first and the last point of. If the maximum distance is larger than a value epsilon the point is kept and the array is split into 2 parts. For both parts the operation is repeated (maximal perpendicular distance, if larger than epsilon etc.) The smaller epsilon the more detail is kept.
I am trying to write a function that can also do this for higher arrays of higher dimensional points. But I am unsure how to define distance. Or if this is actually a good idea.
I guess there exist lots of complicated and elegant algorithms that fit the curves to beziers and NURBS and what not. But are there also relatively simple ones?
I would prefer not to use beziers, but simply to identify "important" N-dimensional points.
You could extend your 2D algorithm using algebra and the L2 norm. Let's say you want to calculate the distance from a point X to a line segment PQ (where X, P and Q are defined as N-dimensional vectors).
First you can calculate the vector "proj" as:
Then, the distance is the module of the vector V = PX-proj.
For this calculation you only need the dot product between vectors, and that is well defined for N-dimensional spaces.
Using this approach I have successfuly used Rahmer-Douglas-Peucker algorithm in 3D.
I have a situation in my game. I am experimenting with terrain generation.
I have a bunch of peaks, whose position and elevation i know.
I have a point which is surrounded by all these peaks. I know its position. I am trying to calculate the elevation of this point.
I would like to calculate the height of this point, based on how close/far it is to each of these peaks, and the elevation of each of these peaks.
Example:
Peak 1 is at (0,0), with an elevation of 500
Peak 2 is at (100,100), with an elevation of 1000
Peak 3 is at (0,100), with an elevation of 750
If my point is at (99,99), i want the elevation of this point to be as close to 1000.
What is the name of this problem?
If you already have a solution to this, that too will be much appreciated.
Note: In addition, it will be helpful if the formula/equation also allows me to generate negative elevations. for example, a point midway between all the peaks could as well be under sea level. Any formula i can menatally think of usually gives me just positive results. I assume some kind of 'Slope' must be considered to allow this.
One equation i though of so far is
P1.height * (Sum of all distances - distance from P1)/(Sum of all distances) +
P2.height * (Sum of all distances - distance from P2)/(Sum of all distances) +
... Pn.height * (Sum of all distances - distance from Pn)/(Sum of all distances)
Thank you.
To draw the peaks your game needs to convert the coordinates of the peaks to screen coordinates.
Such calculation is usually done by multiplying a matrix with the vector containing the coordinates (in java AWT such matrix would be called a transform).
What you need is the inverse of that matrix so that you can apply it to your screen coordinates.
So the solution is:
get the matrix that is used for rendering the terrain
calculate the inverse matrix
apply it to your screen coordinates
And it might even be more efficient not to use the original matrix to calculate the inverse matrix but use the parameters (zero point, scale factors and rotation angle) which were used to calculate the original matrix. The same parameters can be used to calculate the inverse matrix.
This question is more about math than programming. I am programming a function which takes a square of geographical distance between 2 points with known latitude and longitude as an argument. There's a straightforward way to compute it: calculate dot-product, then take arccos, and multiply by Earth radius. Then square the result and you get the square of geographical distance assuming Earth is a sphere (which is acceptable approximation in my case).
However I would like, if possible, to avoid an expensive arccos() call, especially given that I can easily obtain the square of the tunnel distance (by either Pythagorean theorem or the dot product).
I also read here http://en.wikipedia.org/wiki/Geographical_distance#Tunnel_distance about underestimation formula which I can use to get tunnel distance from geographical distance. In my case however, I need the opposite (tunnel to geographical), and for the square. I played with Taylor series and got a rough approximation:
G square = T2 / (1 - (T2/R2)/12.0) // here G2 is square of geographical distance, T2-square of tunnel, R2-square of Earth radius. I also was able to get a more accurate formula:
G square = T2 / (1 - (T2/R2)/12.0 - ((T2/R2)^2)/240.0).
This last formula gives error of only 3.8mm for G=1000 km, and less than 50cm for G=2000 km.
However, I still cannot mathematically prove this formula, at least when using Taylor series. Wonder if it's possible to get the mathematical proof and also expansion of this formula for larger values of G/T. Thanks!
Why tunnel distance from geo distance?. There is no geo distance. There are many possibilities to calculate a distance between two points on earth.
Just take the two lat/lon cooridnates, and then calculate the distance between them using a simmple cyclindrical projection.
This needs only a cos(centerLatitude), and a multiplication with a factor. (meters_per_degree)
See also Cyclindrical equi distant projection. Up to some kilomters (abou 10 to 100) this gives sufficient accuracy.
I have a set of points (with unknow coordinates) and the distance matrix. I need to find the coordinates of these points in order to plot them and show the solution of my algorithm.
I can set one of these points in the coordinate (0,0) to simpify, and find the others. Can anyone tell me if it's possible to find the coordinates of the other points, and if yes, how?
Thanks in advance!
EDIT
Forgot to say that I need the coordinates on x-y only
The answers based on angles are cumbersome to implement and can't be easily generalized to data in higher dimensions. A better approach is that mentioned in my and WimC's answers here: given the distance matrix D(i, j), define
M(i, j) = 0.5*(D(1, j)^2 + D(i, 1)^2 - D(i, j)^2)
which should be a positive semi-definite matrix with rank equal to the minimal Euclidean dimension k in which the points can be embedded. The coordinates of the points can then be obtained from the k eigenvectors v(i) of M corresponding to non-zero eigenvalues q(i): place the vectors sqrt(q(i))*v(i) as columns in an n x k matrix X; then each row of X is a point. In other words, sqrt(q(i))*v(i) gives the ith component of all of the points.
The eigenvalues and eigenvectors of a matrix can be obtained easily in most programming languages (e.g., using GSL in C/C++, using the built-in function eig in Matlab, using Numpy in Python, etc.)
Note that this particular method always places the first point at the origin, but any rotation, reflection, or translation of the points will also satisfy the original distance matrix.
Step 1, arbitrarily assign one point P1 as (0,0).
Step 2, arbitrarily assign one point P2 along the positive x axis. (0, Dp1p2)
Step 3, find a point P3 such that
Dp1p2 ~= Dp1p3+Dp2p3
Dp1p3 ~= Dp1p2+Dp2p3
Dp2p3 ~= Dp1p3+Dp1p2
and set that point in the "positive" y domain (if it meets any of these criteria, the point should be placed on the P1P2 axis).
Use the cosine law to determine the distance:
cos (A) = (Dp1p2^2 + Dp1p3^2 - Dp2p3^2)/(2*Dp1p2* Dp1p3)
P3 = (Dp1p3 * cos (A), Dp1p3 * sin(A))
You have now successfully built an orthonormal space and placed three points in that space.
Step 4: To determine all the other points, repeat step 3, to give you a tentative y coordinate.
(Xn, Yn).
Compare the distance {(Xn, Yn), (X3, Y3)} to Dp3pn in your matrix. If it is identical, you have successfully identified the coordinate for point n. Otherwise, the point n is at (Xn, -Yn).
Note there is an alternative to step 4, but it is too much math for a Saturday afternoon
If for points p, q, and r you have pq, qr, and rp in your matrix, you have a triangle.
Wherever you have a triangle in your matrix you can compute one of two solutions for that triangle (independent of a euclidean transform of the triangle on the plane). That is, for each triangle you compute, it's mirror image is also a triangle that satisfies the distance constraints on p, q, and r. The fact that there are two solutions even for a triangle leads to the chirality problem: You have to choose the chirality (orientation) of each triangle, and not all choices may lead to a feasible solution to the problem.
Nevertheless, I have some suggestions. If the number entries is small, consider using simulated annealing. You could incorporate chirality into the annealing step. This will be slow for large systems, and it may not converge to a perfect solution, but for some problems it's the best you and do.
The second suggestion will not give you a perfect solution, but it will distribute the error: the method of least squares. In your case the objective function will be the error between the distances in your matrix, and actual distances between your points.
This is a math problem. To derive coordinate matrix X only given by its distance matrix.
However there is an efficient solution to this -- Multidimensional Scaling, that do some linear algebra. Simply put, it requires a pairwise Euclidean distance matrix D, and the output is the estimated coordinate Y (perhaps rotated), which is a proximation to X. For programming reason, just use SciKit.manifold.MDS in Python.
The "eigenvector" method given by the favourite replies above is very general and automatically outputs a set of coordinates as the OP requested, however I noticed that that algorithm does not even ask for a desired orientation (rotation angle) for the frame of the output points, the algorithm chooses that orientation all by itself!
People who use it might want to know at what angle the frame will be tipped before hand so I found an equation which gives the answer for the case of up to three input points, however I have not had time to generalize it to n-points and hope someone will do that and add it to this discussion. Here are the three angles the output sides will form with the x-axis as a function of the input side lengths:
angle side a = arcsin(sqrt(((c+b+a)*(c+b-a)*(c-b+a)*(-c+b+a)*(c^2-b^2)^2)/(a^4*((c^2+b^2-a^2)^2+(c^2-b^2)^2))))*180/Pi/2
angle side b = arcsin(sqrt(((c+b+a)*(c+b-a)*(c-b+a)*(-c+b+a)*(c^2+b^2-a^2)^2)/(4*b^4*((c^2+b^2-a^2)^2+(c^2-b^2)^2))))*180/Pi/2
angle side c = arcsin(sqrt(((c+b+a)*(c+b-a)*(c-b+a)*(-c+b+a)*(c^2+b^2-a^2)^2)/(4*c^4*((c^2+b^2-a^2)^2+(c^2-b^2)^2))))*180/Pi/2
Those equations also lead directly to a solution to the OP's problem of finding the coordinates for each point because: the side lengths are already given from the OP as the input, and my equations give the slope of each side versus the x-axis of the solution, thus revealing the vector for each side of the polygon answer, and summing those sides through vector addition up to a desired vertex will produce the coordinate of that vertex. So if anyone can extend my angle equations to handling beyond three input lengths (but I note: that might be impossible?), it might be a very fast way to the general solution of the OP's question, since slow parts of the algorithms that people gave above like "least square fitting" or "matrix equation solving" might be avoidable.
As far as I know, Direct3D works with an LH coordinate system right?
So how would I get position and x/y/z axis (local orientation axis) out of a LH 4x4 (world) matrix?
Thanks.
In case you don't know: LH stands for left-handed
If the 4x4 matrix is what I think it is (a homogeneous rigid body transformation matrix, same as an element of SE(3)) then it should be fairly easy to get what you want. Any rigid body transformation can be represented by a 4x4 matrix of the form
g_ab = [ R, p;
0, 1]
in block matrix notation. The ab subscript denotes that the transformation will take the coordinates of a point represented in frame b and will tell you what the coordinates are as represented in frame a. R here is a 3x3 rotation matrix and p is a vector that, when the rotation matrix is unity (no rotation) tells you the coordinates of the origin of b in frame a. Usually, however, a rotation is present, so you have to do as below.
The position of the coordinate system described by the matrix will be given by applying the transformation to the point (0,0,0). This will well you what world coordinates the point is located at. The trick is that, when dealing with SE(3), you have to add a 1 at the end of points and a 0 at the end of vectors, which makes them vectors of length 4 instead of length 3, and hence operable on by the matrix! So, to transform point (0,0,0) in your local coordinate frame to the world frame, you'd right multiply your matrix (let's call it g_SA) by the vector (0,0,0,1). To get the world coordinates of a vector (x,y,z) you multiply the matrix by (x,y,z,0). You can think of that as being because vectors are differences of points, so the 1 in the last element goes the away. So, for example, to find the representation of your local x-axis in the world coordinates, you multiply g_SA*(1,0,0,0). To find the y-axis you do g_SA*(0,1,0,0), and so on.
The best place I've seen this discussed (and where I learned it from) is A Mathematical Introduction to Robotic Manipulation by Murray, Li and Sastry and the chapter you are interested in is 2.3.1.