I want to transform 3d mesh surface in a way that normal vector is parallel to z axis.
I try the following steps:
1- find the rotation angle using
atan2d(norm(cross(n,z)),dot(n,z));
where n is the normal vector and z is the z-axis
2- find axis of rotation using cross product of n and z
3- create rotation matrix
however the resulted transformation is wrong.
Thanks for your help
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 have yet to start creating the code because I am a little stuck and would like some help to guide me in the right direction. I have to use MATLAB to solve the following issue:
I am given the x,y,z of a 3D surface (about 300 points) that is tilted by an arbitrary angle theta about the x axis and tilted by an arbitrary angle alpha about the y axis. The goal is to tilt the surface so that all of the z values are the same, meaning that the surface is level.
I have tried using rotation matrices, but it has not worked out how I expected. Any suggestions and ideas are greatly appreciated.
It's not elegant, but you could try brute forcing the solution by rotating the graph in set increments about both the x and y axes. Then, simply take the solution where the maximum number of z-coordinates fall within a narrow range. This would mean that the surface is approximately level.
A similar approach but a bit more formal would be to calculated the vector parallel to the surface and knowing the direction of this vector, the rotation parameters got really easy to obtain by c=norm((a,b,c))*cos(angle).
If you have a plane-like surface, you could fit it the to a plane equation a*x+b*y+c*z+d=0 and the vector normal to plane is (a,b,c).
If you have another type of surface -- that is normally what one has -- you may still find the vector of the plane useful, as the plane may be parallel to the surface or may give the direction to compare to made the rotation.
Depending on how you implement it, it will just rotate having point of rotation at the origin (0,0,0). If you plane is far from the origin, both figures will be far from each other. A simple translation can solve it.
With some random point around a plane i got it:
With the code that i used.
n=300;
x= 20.*rand(n,1)-10; %interval
y= 20.*rand(n,1)-10; %interval
%if you want to plot a plane
z=(2*(y+rand(n,1)*0.3)+2*(x+rand(n,1)*0.3)-7)/.4+rand(n,1)*0.3;
figure()
plot3(x,y,z,'.')
hold on
%here i put the plane average data on zero
Centerplane=[mean(x) mean(y) mean(z)];
xc=x-mean(x);
yc=y-mean(y);
zc=z-mean(z);
%get the 'a' and 'b' component of the plane equation (z=a*x +b*y +d)
A=[xc yc]; B=zc;
r=A\B %%%Matlab!
r = vrrotvec( (([r(1) r(2) 1]/norm([r(1) r(2) 1]))),[0 0 1]);
RM=vrrotvec2mat(r); %get the rotation matrix
rdata=[xc,yc,zc]*RM; %rotate data
% put in the proper position back
rt_c_x=rdata(:,1)+mean(x);
rt_c_y=rdata(:,2)+mean(y);
rt_c_z=rdata(:,3)+mean(z);
%and plot
plot3(rt_c_x,rt_c_y,rt_c_z,'c.')
A=[x y]; B=z; %default data
r=A\B %%%Matlab!
r = vrrotvec( (([r(1) r(2) 1]/norm([r(1) r(2) 1]))),[0 0 1]);
RM=vrrotvec2mat(r); %get the rotation matrix
rdata2=[x,y,z]*RM; %rotate data
%and plot
plot3(rdata2(:,1),rdata2(:,2),rdata2(:,3),'g.')
xlabel('X')
ylabel('Y')
zlabel('Z')
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
I have a very basic question. I am analyzing a movie. In the movie I am fitting a curve to define an object and computing the first derivative of a curve at it's starting point. The first derivative is changing in each frame. I want to measire the first derivative in the from of angle given in degrees or radians. Is there a faster way to do it in MATLAB.
I know its a very simple question, but if someone can explain me the concept then that would be very helpful. Thanks
The derivative of the curve is defined as dy/dx the ratio between the change in X direction and Y direction. This ratio is also the tan of the angle between the curve and the X axis. Therefore, if you want the angle (in radians) all you need it compute atan of the derivative.