I have 4 3d points (x,y,z), and I want to know if those points are close to be coplanar. I constructed 3 vectors AB, AC and AD and calculated the absolute value of the determinant which is here the same as the volume. I know that if the volume is 0 then the points are coplanar, but I want also to know if those points are closely coplanar ( I may choose a threshold for instance).
Any help will be appreciated,
Use some normalization of the volume (determinant).
For example, divide it by some function of tetrahedron facets' area (I chose arbitrary one to keep dimension)
Vnorm = Abs (V) / (S1 + S2 + S3 + S4)3/2
Another approach: divide squared distance from D vertice to ABC plane by ABC area (or distance by ABC perimeter)
You can compute the cross-product of vectors AB and AC, obtaining a N1 vector, normal to (ABC) plane. In the same way, compute the cross-product of vectors AB and AD obtaining a N2 vector, normal to (ABD) plane.
The scalar product N1.N2 = |N1|.|N2|.cos(X) where X is the angle between the two normal vectors. X should be zero if your points are exactly coplanar. You can compute X with Arccos function. Unities for X are radians. If X is lower than pi/180 for example you have an angle lower than 1 degree, so points nearly coplanar. You have to decide the exact desired threshold for this angle.
Related
I am not sure if a question like this was asked before but i searched and didn't found what i am looking for.
I know how to determine if a point is to the left or right of a 2D line. but suppose we have a vector in 3D. of course a 3D vector passes through infinite planes, but suppose we chose one plane of them in which we are interested, and we have a specific point on this plane which we want to know if it lies to the left or right or on our vector (with respect to the chosen plane). how to do this ?
You should explicitly define orientation of that plane - for example, define main (forward) normal N - like OZ axis is normal for OXY plane.
If you have A,B,C triangle and claim that it is oriented counterclockwise, you can calculate forward plane normal as N = AB x BC
For points A, B, D in given plane calculate mixed product (vector product of AB and AD, then scalar product of result and N)
mp = (AB x AD) . dot. N
Sign of this value is positive, if vectors AB, AD, N form right-handed triplet and D lies left to AB direction
An intuitive solution is to define a coordinate system for the plane as follows. Let's normalize the 3d vector in your question and call the resulting unit vector v, and let x be a point on your plane, whose unit normal we will denote as n. You can now chose a coordinate system centered at x, that is made by the three 3*1 unit vectors v, n and b=v.crossProduct(n).
The idea is that if you express a point in this coordinate system, then if its b coordinate is negative, you can says that it is, say, on the left. So, if its b coordinate is positive, it will be on the right.
Obviously, if you have a point q expressed in this coordinates system, you can write its expression q_w in world coordinates using
q_w=R*q+x
where the rotation matrix R is the matrix whose columns are the unit axes of the plane coordinate system:
R=[v n b]
So, if you have a point Q in world coordinates, using the inverse of the relation above, you compute transpose(R)*(Q-x), and look at whether the b coordinate is positive or negative.
This is easy to find the 2D unit tangent from the unit normal vector. Just make the x component of the unit tangent vector equal to the negative of the y component of the unit normal vector,
and make the y component of the unit tangent vector equal to the x component of the unit normal vector:
ut =〈−uny, unx〉
But how unit tangent from the unit normal vector is obtained in 3D with xyz components?
I'm not entirely sure if I understand your question correctly.
What I understand is that you have a vector (x,y,z) and you want to find the vectors perpendicular to this vector?
Vectors perpendicular to each other are vectors for which the dot product equals zero.
One is (-y,x,0) (if not both x and y are zero). Call it b1.
Another one is obtained computing the cross product of (x,y,z) and (-y,x,0). Call it b2.
The set of all vectors perpendicular to (x,y,z) is the set of linear combination of b1 and b2.
I have a three points (A,B,C) that denote objects moving in 2D space. For each node I know its position and its velocity vector. All three objects are moving in the same direction.
I would like to know whether a point C (x3, y3) approximates a "positive" extension to the line formed by points A(x1, y1) and B(x2, y2). That is, I would like to know whether point C is "ahead" of point B (i.e "A->B->C" and not "C->A->B").
I know that checking if points A, B, C are collinear will give me an indication of all three points are lying on the same line, however, i cannot figure out whether point C approximates a positive extension to the line.
Any suggestion would be highly appreciated.
You can calculate the scalar product of the difference vectors AB and BC. If that is positive, then C is what you call 'in front of B. It may be way off to the left or right, though.
The scalar product would be calculated as
(b1-a1)x(c1-b1) + (b2-a2)x(c2-b2).
when A=(a1, a2), B=(b1, b2), C= (c1,c2) - it is the cos of the angle between the two vectors times the lengths of the vectors, and cos is positive for angles less than 90 degree.
If I have two vector coordinates representing positions on the surface of the earth where the center of the earth is (0,0,0) and the Up vector is (0,0,1);
What is the best way to calculate a 3d plane that is running along the two vectors (the direction v2 - v1) but back by a set number of meters (just imagine a virtual clip plane that is behind the two vectors and running parallel to them).
well, you do the cross product of v1 and v2 to get the normal of your plane (don't forget to normalize if you want to), then the 4th element of your plane would just be 0 (because it crosses 0,0,0).
and then you want to project the plane in a certain direction based on the UP vector, not the plane's normal?
in that case I think you would just get the dot product of the normal and the up vector, then multiply the inverse of the dot (1/dot) by the number of units you want to project along the up vector and set that as your 4th element?
to clarify, that creates a plane where the two vectors, and the center of the earth are points on the plane, the plane can then be projected up or down by a certain amount in the UP direction.
Planes are usually described by a normal vector N, and as all points x,y,z fitting the equation Ax + By + Cz + D = 0. (A,B,C) is the normal vector. It doesn't even need to be normalized (unit length) if you choose D. Sounds like you want a plane to which v1 and v2 are parallel (and v2-v1 too). For that, make N perpendicular to v1 and v2 by setting it to the cross product of v2 x v1. Then pick a point in (x,y,z) coordinates that you know the plane should pass through. Plug N and (x,y,z) into the equation and compute D.
1- Find the Normal vector N = V1 X V2
2-Select a point that you want your plane tuch P0 ==>R0
3- All the other points(P==>R) in the plane follow N(R-R0)=0
See the link
Let's say I have two points in 3D space (a and b) and a fixed axis/unit vector called n.
I want to create a rotation matrix that minimizes the euclidan distance between point a (unrotated) and the rotated point b.
E.g:
Q := matrix_from_axis_and_angle (n, alpha);
find the unknown alpha that minimizes sqrt(|a - b*Q|)
Btw - If a solution/algorithm can be easier expressed with unit-quaternions go ahead and use them. I just used matrices to formulate my question because they're more widely used.
Oh - I know there are some degenerated cases ( a or b lying exactly in line with n ect.) These can be ignored. I'm just looking for the case where a single solution can be calculated.
sounds fairly easy. Assume unit vector n implies rotation around a line parallel to n through point x0. If x0 != the origin, translate the coordinate system by -x0 to get points a' and b' relative to new coordinate system origin 0, and use those 2 points instead of a and b.
1) calculate vector ry = n x a
2) calculate unit vector uy = unit vector in direction ry
3) calculate unit vector ux = uy x n
You now have a triplet of mutually perpendicular unit vectors ux, uy, and n, which form a right-handed coordinate system. It can be shown that:
a = dot(a,n) * n + dot(a,ux) * ux
This is because unit vector uy is parallel to ry which is perpendicular to both a and n. (from step 1)
4) Calculate components of b along unit vectors ux, uy. a's components are (ax,0) where ax = dot(a,ux). b's components are (bx,by) where bx = dot(b,ux), by = dot(b,uy). Because of the right-handed coordinate system, ax is always positive so you don't actually need to calculate it.
5) Calculate theta = atan2(by, bx).
Your rotation matrix is the one which rotates by angle -theta relative to coordinate system (ux,uy,n) around the n-axis.
This yields degenerate answers if a is parallel to n (steps 1 and 2) or if b is parallel to n (steps 4, 5).
I think you can rephrase the question to:
what is the distance from a point to a 2d circle in 3d space.
the answer can be found here
so the steps needed are as following:
rotating the point b around a vector n gives you a 2d circle in 3d space
using the above, find the distance to that circle (and the point on the circle)
the point on the circle is the rotated point b you are looking for.
deduce the rotated angle
...or something ;^)
The distance will be minimized when the vector from a to the line along n lines up with the vector from b to the line along n.
Project a and b into the plane perpendicular to n and solve the problem in 2 dimensions. The rotation you get there is the rotation you need to minimize the distance.
Let P be the plane that is perpendicular to n.
We can find the projection of a into the P-plane, (and similarly for b):
a' = a - (dot(a,n)) n
b' = b - (dot(b,n)) n
where dot(a,n) is the dot-product of a and n
a' and b' lie in the P-plane.
We've now reduced the problem to 2 dimensions. Yay!
The angle (of rotation) between a' and b' equals the angle (of rotation) needed to swing b around the n-axis so as to be closest to a. (Think about the shadows b would cast on the P-plane).
The angle between a' and b' is easy to find:
dot(a',b') = |a'| * |b'| * cos(theta)
Solve for theta.
Now you can find the rotation matrix given theta and n here:
http://en.wikipedia.org/wiki/Rotation_matrix
Jason S rightly points out that once you know theta, you must still decide to rotate b clockwise or counterclockwise about the n-axis.
The quantity, dot((a x b),n), will be a positive quantity if (a x b) lies in the same direction as n, and negative if (a x b) lies in the opposite direction. (It is never zero as long as neither a nor b is collinear with n.)
If (a x b) lies in the same direction as n, then b has to be rotated clockwise by the angle theta about the n-axis.
If (a x b) lies in the opposite direction, then b has to be rotated clockwise by the angle -theta about the n-axis.