How can I calculate a tangent vector at a point in 3D dimensions? - matlab

On the z=0 plane, I have a point A(a1,b1,0). And there is another point B(a2,b2,0) which I consider it as the center of a circle. I connect AB together and then draw a circle with radius AB. There is another point C(a3,b3,c3) in the 3D zone.
How can I find the tangent vector of AC on the circle with radius AB?Ie means that I need to calculate the tangent vector of AC at point A.

If you mean tangent to the circle at point A, then it is unique vector perpendicular to vector AB and is NOT dependent on any other point in 3D like point C. It should be easy to calculate.
On other hand project of AC on the plane is easy to calculate but it is NOT guaranteed to be tangent vector that you are looking for.

Related

Optimizing computation of distance to triangle using barycentric coordinates

Building on the discussions here and here. I'm trying to compute the shortest distance between a 3D line and a 3D triangle.
I'm using barycentric coordinates to determine whether or not the point is inside the triangle. So given a triangle defined by vertices UVW and a line defined by point AB, I first compute the intersection of line AB with the plane defined by UVW. Let's call this intersection P and assume I've already done the checks to verify whether or not the point actually intersects the plane at all.
I then compute barycentric coordinates (S,T) such that S is defined along the edge UV and T is defined along the edge UW. Naturally, if 0≤S and 0≤T and S+T≤1 then P is on the triangle (or its edge) and my distance to the triangle is obviously zero.
If that's not true then P is outside the triangle and I need to compute the distance. The guidance of from the first link says to project point P onto all three edges to get three candidate points. Adding those points to the three triangle's vertices, you then have six points to test against.
Isn't it easier than that, though? If T<0, then don't you already know that UV is the closest edge and you only have to test against the projection of P onto that line? Similarly, if S<0 then UW would be the closest edge. If T>0 and S>0 then VW is the closest edge.
Thus based on the signs of S and T you already know the closest edge and only have to compute the distance from P to its projection onto that edge. If the projection isn't inside the triangle, then the closest point is either vertex. Thus your computations are about 1/3 of the proposed methods.
Am I missing something here, or is this a valid optimization? I'm fairly new to barycentric coordinates and their attributes.
It turns out that the problem of closest distance from a point and from a line are very similar and can both be reduced to a pure 2D problem.
Distance from a point
By Pythagoras, the squared distance from a point to a point of the triangle is the sum of the squared distance to the plane of support of the triangle and the squared distance of the projection of the point to that plane.
The latter distance is precisely the distance from the normal line to the triangle.
Distance from a line
Looking in the direction of the line, you see the projected triangle and the line is reduced to a single point. The requested 3D distance is equal to the 2D distance seen on the projection.
To obtain the desired coordinates, you use an auxiliary coordinate frame such that Z is in the direction of the line (and XY is a perpendicular plane); for convenience, choose the origin of the new frame to be on the line. Then by just ignoring Z, you get a planar problem in XY. The change of coordinates is an affine tranformation.
Point vs. triangle
Consider the three triangles formed by the origin (projection of the point/line) and a pair of triangle vertices (taken in cyclic order). The signed area of these triangles is a mere 2x2 determinant.
If the three areas have the same sign, the point is inside. Otherwise, the signs tell you where you are among the six surrounding regions, either past an edge or past a vertex.
On the upper figure, the point is inside (three positive areas). On the other figure, it is outside of the top-right edge (one negative area). Also note that dividing an area by the length of the corresponding side, you get the distance to the side. (Factor 2 omitted.)
The total work is
compute the affine frame;
convert the coordinates of the 3 or 4 points;
compute the three signed areas;
if inside, you are done;
otherwise, if in an edge region, compute a distance to a line and two distances to points;
otherwise you are in a vertex region, compute two distances to lines and one distance to vertex.

Intersection between two 3D surfaces

I have two independent 3D shapes; one is a square and another is a cone.
Let's assume the cone lies inside the square. How can I find out that the surface of the cone touches the square's surface when I move the cone in any direction?
It will be helpful if anyone can suggest an algorithm to check whether the surface touches another shape.
I am working with MATLAB, but the underlying logic will be appreciated in any language will be appriciated.
https://in.mathworks.com/matlabcentral/answers/367565-findout-surface-to-surface-intersection-between-two-3d-shapes
There is a relatively easy solution, thanks to the fact that the truncated cone is a convex shape, and finding its AABB is not so hard.
First rotate space so that the cube become axis aligned (and the cone in arbitrary position). Then to find the AABB of the base, is suffices to get the maxima an minima of the coordinates, using the parametric equation, C + R cos t + R' sin t, where C is the position vector of the center, and R, R' two orthogonal radii. You find the limit angles by canceling the derivative.
After finding the extrema on the three coordinates, the global bounding box is the one that surrounds these six points plus the apex.
By comparing the AABB to the cube, you can tell what distance remains before a collision, in any direction.

How to rotate a 3D plane?

I have a 3d plane (made up of number of points) which is rotated at weird angle. I want to make it flat i.e lie on xy-plane. I have plane equation but I think my calculated angles are not correct or might be using wrong rotation matrix. By wrong rotation matrix is that I meant that I am not sure about which axis should I rotate. attached is the picture of my plane:
I tried to calculate by using following formulas:
theta=-acosd((dot(n1,n2))/(norm(n1)*norm(n2)));
Calculate spherical angles: theta and phi;
both methods are giving same angle, I rotated my plane first about z-axis and then about y-axis. The resulted plane is almost flat but it still has some anlge.
I tried both rotation matrix and Rodrigues' rotation matrix. It would be really helpful if someone could suggest how to rotate this plane to make it flat.
When a plane is not parallel to the xy-plane, then it's normal vector will not be parallel to the z-axis. So the cross product of the normal vector and the z-axis (unit) vector will be non-zero. This vector is in the plane and parallel to the xy-plane. Take it as rotation axis. The rotation angle to make the plane parallel to the xy-plane is the same as the angle between the normal vector and the z-axis.

I need to fit a best circle to the 3D data in matlab

Basically, I have a many irregular circle on the ground in the form of x,y,z coordinates (of 200*3 matrix). but I want to fix a best circle in to the data of x,y,z coordinates (of 200*3 matrix).
Any help will be greatly appreciated.
I would try using the RANSAC algorithm which finds the parameters of your model (in your case a circle) given noisy data. The algorithm is quite easy to understand and robust against outliers.
The wikipedia article has a Matlab example for fitting a line but it shouldn't be too hard to adapt it to fit a circle.
These slides give a good introduction to the RANSAC algorithm (starting from page 42). They even show examples for fitting a circle.
Though this answer is late, I hope this helps others
To fit a circle to 3d points
Find the centroid of the 3d points (nx3 matrix)
Subtract the centroid from the 3D points.
Using RANSAC, fit a plane to the 3D points. You can refer here for the function to fit plane using RANSAC
Apply SVD to the 3d points (nx3 matrix) and get the v matrix
Generate the axes along the RANSAC plane using the axes from SVD. For example, if the plane norm is along the z-direction, then cross product between the 1st column of v matrix and the plane norm will generate the vector along the y-direction, then the cross product between the generated y-vector and plane norm will generate a vector along the x-direction. Using the generated vectors, form a Rotation matrix [x_vector y_vector z_vector]
Multiply the Rotation matrix with the centroid subtracted 3d points so that the points will be parallel to the XY plane.
Project the points to XY plane by simply removing the Z-axes from the 3d points
fit a circle using Least squares circle fit
Rotate the center of the circle using the inverse of the rotation matrix obtained from step 5
Translate back the center to the original location using the centroid
The circle in 3D will have the center, the radius will be the same as the 2D circle we obtained from step 8, the circle plane will be the RANSAC plane we obtained from step 3

find area of 3D polygon

Given a matrix nx3 that represents n points in 3D space. All points lie on a plane. The plane is given by its normal and a point lying on it. Is there a Matlab function or any Matlabby way to find the area directly from the matrix?
What i was trying to do is write a function that first computes the centroid,c, of the n-gon. Then form triangles : (1,2,c),(2,3,c),...,(n,1,c). Compute their area and sum up. But then i had to organise the polygon points in a cyclic order as they were unordered which i figured was hard. Is there a easy way to do so?
Is there a easier way in Matlab to just call some function on the matrix?
Here is perhaps an easier method.
First suppose that your plane is not parallel to the z-axis.
Then project the polygon down to the xy-plane simply by removing the 3rd coordinate.
Now compute the area A' in the xy-plane by the usual techniques.
If your plane makes an angle θ with the xy-plane, then your 3D
area A = A' / cos θ.
If your plane is parallel to the z-axis, do the same computation
w.r.t. the y-axis instead, projecting to the xz-plane.
To project from 3D to the plane normal to N, take some non-parallel vector A and compute the cross products U = N x A and V = N x U. After normalizing U and V, the dot products P.U and P.V give you 2D coordinates in the plane.
Joseph's solution is even easier (I'd recommend to drop the coordinate with the smallest absolute cosine).
You said the points all lie on a plane and you have the normal. You should then be able to reproject the 3-D points into 2-D coordinates in a new 2-D basis. I am not aware of a canned function in Matlab to do this , but coding it should not be difficult, this answer from Math.SE and this Matlab Central post should help you.
If you already solved the problem of finding the coordinates of the points in the 2-D plane they are in, you could use the Matlab boundary or convex hull function to compute the area of the boundary or convex hull enclosing the points.
[k,v]= boundary(x,y)
or
[k,v] =convhull(x,y)
where k is the vector of indices into points x,y, that define the boundary or convex hull, v is the area enclosed, and x, y are vectors of the x and y coordinates of your points.
What you were describing with trying to find triangles with the points sounds like a first attempt toward Delaunay triangulation. I think more recent versions of Matlab have functions to do Delaunay triangulation as well.