I have 2 sets of points that are restricted to live on the 3D unit sphere, call them {pi} and {qi} (I'll assume correspondence is known). The goal is to register one set to the other, through rotations and translations. Typically I would have used a transformation of the form:
P = RQ + T
where R is a rotation matrix and T a translation vector.
But in this case there is an extra constraint that all points must live on the sphere, how can I include this condition.
Assuming the sets are 'rigid', so you can slide and rotate the whole set on the sphere, but can not change distances between points within a set, all possible transformations are rotations.
Whenever you rotate the set relative to some axis, points move in planes perpendicular to the axis. So all displacements are vectors normal to the axis vector. So each two displacement vectors should make a vector product parallel to the axis vector.
Now, if you already know the correspondence between P and Q points, calculate displacement vectors di from each qi to a corresponding pi and calculate some vector products:
di × dj = (pi - qi) × (pj - qj)
If they have directions close enough to each other, you can assume you have the rotation axis.
Now for each pair or pi,qi find a point ti on an axis such that the PQT triangle is normal to the axis. The angle at the T vertex defines the rotation to slide qi to pi. If all respective angles are equal, you're done. Otherwise you'll have to seek some approximate solution...
Related
I have a 3d plane at the world origin that is aligned with the world X/Y plane (facing the Z axis). I then have four 3d vertex positions for a new plane transformed into some location in 3d space.
Both planes have the same winding order for all 4 vertices.
I have a guarantee that the 4 corners are planar and there is no skewing (the plane may have still been scaled individually on the x/y axes).
How can I create a 4x4 transformation matrix given the final 4 corners of this plane?
Assume that the plane looks like this:
Construct a "local basis" of the plane, with the:
X-axis parallel to AD / BC
Y-axis parallel to AB / CD
Z-axis parallel to the normal
Origin O at the center of the quad
The transformation matrix can be decomposed into 3 components:
1 – Scale
Since the original quad has dimensions of 1x1 units, the scaling factor along the X and Y local axes are simply the side lengths, i.e. the lengths of AD and AB respectively. Ignore the Z scaling factor since the quad is planar.
Therefore the scaling component is given by:
2 - Rotation
The rotational component can be directly constructed from the local basis axes X, Y, Z; each vector (normalized) is the corresponding column of the matrix.
Therefore the rotational component is given by:
3 - Translation
This is the easiest one; the translation vector is simply the absolute coordinate of the quad's center O, and is equal to the last column of the matrix.
Therefore the translational component is given by:
The final matrix can be obtained by multiplying the above in the following order:
i.e. the components are applied in the order 1 ⇨ 2 ⇨ 3.
Say I have a set of points from a sensor which are all within a margin of error on a 2D plane somewhere in the 3D space. How would I go on about transforming the coordinates of the points onto a 2d coordinate system, so that for example the convex hulls of the points or the distances between the points don't change?
Assuming you know the equation of the plane (otherwise you can fit it by least-square or other), construct a new coordinate frame as follows:
get the normal vector,
form the cross product with an arbitrary vector having a different direction;
form the cross product of the normal and the second vector,
normalize all three and name the new axis z, x, y.
This creates an orthonormal basis to which you will transform the points. This corresponds to a rigid transform, that preserves all distances. You can drop the z to get the orthogonal projections of the points to the plane.
here is a problem that will turn your brain inside out, I'm trying to deal with it for a quite some time already.
Suppose you have sphere located in the origin of a 3d space. The sphere is segmented into a grid of equidistant points. The procedure that forms grid isn't that important but what seems simple to me is to use regular 3d computer graphics sphere generation procedure (The algorithm that forms the sphere described in the picture below)
Now, after I have such sphere (i.e. icosahedron of some degree) I need a computationally trivial procedure that will be capable to snap (an angle) of a random unit vector to it's closest icosahedron edge points. Also it is acceptable if the vector will be snapped to a center point of triangle that the vector is intersecting.
I would like to emphasise that it is important that the procedure should be computationally trivial. This means that procedures that actually create a sphere in memory and then involve a search among every triangle in sphere is not a good idea because such search will require access to global heap and ram which is slow because I need to perform this procedure millions of times on a low end mobile hardware.
The procedure should yield it's result through a set of mathematical equations based only on two values, the vector and degree of icosahedron (i.e. sphere)
Any thoughts? Thank you in advance!
============
Edit
One afterthought that just came to my mind, it seems that within diagram below step 3 (i.e. Project each new vertex to the unit sphere) is not important at all, because after bisection, projection of every vertex to a sphere would preserve all angular characteristics of a bisected shape that we are trying to snap to. So the task simplifies to identifying a bisected sub triangle coordinates that are penetrated by vector.
Make a table with 20 entries of top-level icosahedron faces coordinates - for example, build them from wiki coordinate set)
The vertices of an icosahedron centered at the origin with an
edge-length of 2 and a circumscribed sphere radius of 2 sin (2π/5) are
described by circular permutations of:
V[] = (0, ±1, ±ϕ)
where ϕ = (1 + √5)/2
is the golden ratio (also written τ).
and calculate corresponding central vectors C[] (sum of three vectors for vertices of every face).
Find the closest central vector using maximum of dot product (DP) of your vector P and all C[]. Perhaps, it is possible to reduce number of checks accounting for P components (for example if dot product of P and some V[i] is negative, there is no sense to consider faces being neighbors of V[i]). Don't sure that this elimination takes less time than direct full comparison of DP's with centers.
When big triangle face is determined, project P onto the plane of that face and get coordinates of P' in u-v (decompose AP' by AB and AC, where A,B,C are face vertices).
Multiply u,v by 2^N (degree of subdivision).
u' = u * 2^N
v' = v * 2^N
iu = Floor(u')
iv = Floor(v')
fu = Frac(u')
fv = Frac(v')
Integer part of u' is "row" of small triangle, integer part of v' is "column". Fractional parts are trilinear coordinates inside small triangle face, so we can choose the smallest value of fu, fv, 1-fu-fv to get the closest vertice. Calculate this closest vertex and normalize vector if needed.
It's not equidistant, you can see if you study this version:
It's a problem of geodesic dome frequency and some people have spent time researching all known methods to do that geometry: http://geo-dome.co.uk/article.asp?uname=domefreq, see that guy is a self labelled geodesizer :)
One page told me that the progression goes like this: 2 + 10·4N (12,42,162...)
You can simplify it down to a simple flat fractal triangle, where every triangle devides into 4 smaller triangles, and every time the subdivision is rotated 12 times around a sphere.
Logically, it is only one triangle rotated 12 times, and if you solve the code on that side, then you have the lowest computation version of the geodesic spheres.
If you don't want to keep the 12 sides as a series of arrays, and you want a lower memory version, then you can read about midpoint subdivision code, there's a lot of versions of midpoint subdivision.
I may have completely missed something. just that there isn't a true equidistant geodesic dome, because a triangle doesn't map to a sphere, only for icos.
In three.js, the constructor for the Math Plane takes 2 inputs:
normal -- (Vector3) normal vector defining the plane pointing towards the origin
constant -- (Float) the negative distance from the origin to the plane along the normal vector
Can someone provide an illustration or explain how this works? I can understand given a point and normal how to construct a plane, or 3 co-planar points, but can't figure out how a normal vector and constant can be used.
TL:DR?
Mathy-ness and linear algebra
So planes in 3 dimensional space can be defined as a 2-dimensional infinite rectangle that falls on 3 points (what you know)
It can also be defined by a perpendicular (normal) vector and a constant of how far from the origin the plane is.
Three.js take the normal vector (a vector that is perpendicular to the plane you want) and basically applies linear algebra to find the plane, then moves it the constant distance away from the origin.
Math Calculation Explanation:
If we have a vector A and B that are orthogonal (perpendicular) then their dot product is 0. SO if we use this principle we can actually take a known Vector X and find 2 orthogonal Vectors Y and Z that will be co-planar (due to orthogonality properties) by backwards solving X (dot) Y = 0 and X (dot) Z = 0
Now we have 2 co-planar vectors to make our plane that we set the distance of the constant away from the origin
(think how vectors have an origin and an endpoint. If the co-planar vectors share an origin, then we have 3 points: 2 ends, and 1 origin, aka 3 points to make a plane.)
Math Theory Explanation on why this works ahead:
I can't draw very well (without pen and paper to show), but basically, think about a vector in 3D space. Now think about all the vectors that can be perpendicular to it. Basically, that creates an infinite amount of perpendicular vectors rotated in a circle perpendicularly to the original, and if we span them infinitely, we have created a plane.
If you ever have an opportunity to take a linear algebra class, I would highly recommend it. It is extremely interesting, very related to computer graphics, and explains a lot of 3D space math that THREEjs uses
What is the unit to measure distence between any 2 points in an image of a spherical object.
For example the distance between the 2 red points on the tennis ball.
NOTE: As a matter of fact, the "Euclidean distance" cannot be used, since ball is non-Euclidean. Ball is almost spherical, the imaging system projects the ball surface on a plane, where the image elements are not equispaced, neither represent equal areas. The true Euclidean distance depends on the actual position of the points with respect to the camera.
General idea
Supposing the picture takes an isometric projection of space, we can measure coordinates on the picture as if they were coordinates on a plane.
From there we can transform them into an arbitrary ball-centric spherical coordinate system, and then we'll easily get the distance between them.
Definitions
Let us suppose you know the radius r of the sphere. We'll use a coordinate system centered at the center of the sphere, with x the direction orthonormal to the plane projection induced by the picture (thus the vector comes right out of the photo). Then the directions y and z are in the picture, let's take y horizontal and z vertical. See drawing for reference.
Then the spherical coordinate system induced by this is such that we have a distance to the centre which is always r on the sphere, and 2 angles theta and phi :
(source: motionscript.com)
.
Now we can convert each point into spherical coordinates and compute the distance between them.
Convert to spherical coordinates
For each point, the z coordinate is the vertical distance on the picture between the point and the horizontal line that cuts the ball in two equal halves. Express it in terms of r, the radius of the ball, thus z = c * r, with c in [-1,1], negative if the point is below the line, positive if above.
We know that z = r * cos(theta), so theta = arccos(c). Since theta is in [0,Π], no special cases here.
Now measure y in the same way, which is the horizontal distance (to the right is positive) between the point and the vertical line cutting the ball in 2. With y = r * b, and b in [-1,1].
We need theta's sine, which is sin(theta) = sqrt(1 - c*c), then it comes that phi = arcsin( b / sqrt(1 - c*c) ). Because we can see the point on the picture, we know that it has x > 0 by definition of our coordinate system. That means that phi is in [-Π/2,Π/2], so again, no tricks or surprises in the trigonometry here.
Distance between points on a sphere
Well everything is explained in this math exchange question, because most great-arc distances are expressed in terms of latitude and longitude, which use different conventions.
Now we replace elements of the formula in term of the c1, c2, b1 and b2 we previously computed :
The formula you eventually get is , where cos-1 is also known as the arccos function.
I won't delve into the detail (especially because it's such a pain to include latex from a mobile app), but the steps are :
expand the difference inside the cosine
in the only non-trivial term transform the phi's cosines with sqrt(1-sin2)
push both sin(theta) of that term inside the square root, some multiplying with the sin(phi) will give you the b squared terms
express remaining squared sines under the square root as 1-cos2
The final unit of measure will be in whatever unit you express r.
As you can see, you only need the radius at the end, after the arccos (for bs and cs, you only need the size of r and respectively ys and zs on the picture, not in the physical world).
Then, if you are only going to compare distances of points on that same sphere, you may simplify by r, and compare the angles between points at the center of the sphere (i.e. use only the arccos's result without multiplying by r), since these angles are proportional to the arc's distances on the sphere. Your unit of measurement would then be in radians.