Rotate nxn matrix around x-axis by an angle theta in Matlab - matlab

I have nxn matrix in 2D space; I would like to rotate the matrix around the x-axis using matlab. Where the x-axis pass through the center of the matrix (pass through the point [n/2 n/2].
I found the Matlab function B = rot90(A) which rotate the matrix A by 90 degree. But I’m looking for a method that rotate matrix A by any given angle (e.g. 30, 45, 170 degree) around the x-axis.

You can as well try imrotate(). This function is from the Image Processing Toolbox, but since its main input is a matrix (either real or logical) it'll work also for non picture-related matrices (I've tried with a magic matrix).
The syntax is:
B=imrotate(A,theta);
where A is you matrix, B is the rotated version of A and theta is the rotation in degrees. The rotation is performed in counterclockwise direction around its center point; to rotate the matrix clockwise, specify a negative value for theta.

Related

About imgradient function in Matlab

I am having doubt to the used equation in the function of imgradient.
In the line of 127:
Gdir = atan2(-Gy,Gx)*180/pi; % Radians to degrees
Why the Gy have to be negative?
The y-axis is inverted in images (it increases downward instead of upward). This causes the angles to increase clockwise instead of counter-clockwise as you're used to. By flipping the y component of the gradient, this line computes an angle in the "normal" sense.
Using the graph that #Dan linked in his comment:
In this graph, y increases upward, and angles increase counter-clockwise. In an image, the coordinate system is flipped. This leads to counter-intuitive angles. Hence they invert the y axis to compute the angle.

Conversion between co-ordinate systems

I have a set of data coordinates in 3D with respect to an Origin, say O1, and another set of data that represents the same movements but in 2D with respect to an Origin, say O2. What can I do to calculate the transformations that are required to implement on the 3D set to be able to compare the data points(2D vs 3D) in a 2D frame?
Setup of data generation
If the measurements are at the same times, then the following might work. I have not actually tried it and make no claim that it is the best solution, but it seems doable. Basically, after adjusting the coordinates so that they have the same origin, you want to minimize the following 2-norm:
|| vec(A*x) - vec(P*B*y) ||
where x is the 2xN array of the 2-D locations, A is a 2x2 rotation matrix that rotates x by the unknown angle theta, P is a 2x3 projection matrix that projects a 3x1 vector onto its first two dimensions (viz., just throws out the third value), B is a 3x3 rotation matrix, and y is the 3xN array of the 3-D locations.
The unknowns in the above are theta in the 2-D rotation matrix, and the three rotation angles needed to define B. The four angles that minimize the above should (at least I think) give you the rotation matrices needed to align the coordinate systems.

How do axis-angle rotation vectors work and how do they compare to rotation matrices?

I'm having a bit of trouble understanding how axis-angle rotation vectors are used when rotating a vector in 3D space. Why are these used and how do these relate to rotation matrices?
I also found a function called vrrotvec2mat that seems to do what I want but I can't understand the documentation. Specifically, can someone give a more clear explanation (with some example) of the input arguments r and options?
MathWorks explanations are very limited, as follows:
Convert rotation from axis-angle to matrix representation
m = vrrotvec2mat(r) returns a matrix representation of the rotation defined by the axis-angle rotation vector, r.
m = vrrotvec2mat(r,options) returns a matrix representation of rotation defined by the axis-angle rotation vector r, with the default algorithm parameters replaced by values defined in options.
The options structure contains the parameter epsilon that represents the value below which a number will be treated as zero (default value is 1e-12).
The rotation vector, r, is a row vector of four elements, where the first three elements specify the rotation axis, and the last element defines the angle.
To rotate a column vector of three elements, multiply it by the rotation matrix. >To rotate a row vector of three elements, multiply it by the transposed rotation matrix.
If you want to understand the vrrotvec2mat function, you need to know how axis-angle representations of rotations work before we delve into this function. Specifically, you're looking at understanding the Rodrigues Rotation formula, which is also known as the axis-angle rotation formula. I'll explain this to you with some introduction first.
In Linear Algebra, the most standard way to rotate a point, whether it's 2D or 3D is to use a rotation matrix where you pre-multiply (i.e. y = A*x where x is your point represented in a column vector) the 2D or 3D coordinate with this rotation matrix. This rotates the point around the origin of the coordinate system. You can also think of this as rotating a vector v where the tail is at the origin and the head is at the point in 2D or 3D space.
However, another way to do this is to provide what is known as the axis-angle representation which is only valid in 3D space. The axis is described by a unit vector k that describes an axis of rotation about which the vector v rotates by an angle around this axis by the right-hand rule.
Here's a pictorial example I got from Wikipedia:
Source: Rodrigues' Rotation formula
The vector k in our case is pointing straight up and the vector v is pointing on a 45 degree angle northwest. We wish to rotate this vector by an angle of 180 degrees around the axis defined by the vector k, and so if you do this, vrot is the resulting vector. v|| and v_|_ are the parallel and perpendicular projections of v with respect to the vector k. These are shown to derive the Rodrigues formula, which I won't go through here. I'll refer you to the article if you want a full derivation.
The reason why the Rodrigues rotation formula was proposed to rotate things is because very frequently, there are applications where you are rotating about an axis that is not centred at the origin, nor are you rotating with respect to a standard x,y and z axis.
In fact, if you look at the Wikipedia article, you don't need to convert to the matrix form to rotate things. You can use the unit vector and rotation angle directly to rotate your vector, which leads us to his rotation formula:
Source: Rodrigues' Rotation formula
The reason why vrrotvec2mat exists is because you can convert between the axis-angle representation of rotating a vector and a rotation matrix with a rotation with respect to the origin in Linear Algebra. You can then apply the same Linear Algebra theory to rotate a vector/point in 3D space given this rotation matrix. You can convert back and forth between a normal rotation matrix and the Rodrigues formula representation by using vrrotvec2mat and vrrotmat2vec respectively.
The axis-angle representation is essentially a 4 element vector where the first three elements are the x,y and z components of the unit vector k that defines your rotation axis and the last element is the rotation angle theta that rotates your vector with respect to this axis. vrrotvec2mat is no different here and requires a 4 element vector in the order that I just talked about. However, having a quick look at the source, theta is defined in radians.
If you want a concrete example of seeing this work, let's use the above diagram as an example. The unit vector k is pointing upwards on the z axis, and so the first three components are (0,0,1). We wish to rotate by 180 degrees, and so the fourth argument is pi... and so:
>> M = vrrotvec2mat([0 0 1 pi])
M =
-1.0000 -0.0000 0
0.0000 -1.0000 0
0 0 1.0000
This exactly defines a rotation of 180 degrees around the z-axis if you take a look at the standard rotation matrix in Cartesian space around the z axis. If you recall the rotation matrix for this, it's:
If you substitute theta = pi in the above matrix, you will get the same thing as M as seen in the vrrot2vec2mat function. However, ignore the sign of the first row, second column as it's due to numerical precision... which leads us to the second parameter options. Basically, when computing the rotation matrix values using the Rodrigues Rotation formula, there will be times where values in the matrix will be quite small. The options structure has a field called epsilon, where you can specify anything smaller than this threshold is considered zero after the matrix has been calculated. The default of 1e-12 is quite suitable IMHO.
If you'd like to change the default epsilon, simply create a structure that has a single element epsilon that changes this threshold and call the function with this additional second argument... so something like:
>> options.epsilon = 1e-15;
>> M = vrrotvec2mat([0 0 1 pi], options);
In any case, going back to what we were talking about, let's say our given vector v is with respect to the above figure and that it's pointing northwest - specifically at (x,y,z) = (1,0,1). If we use this rotation matrix and rotate this point, we should get it to be parallel to the xz plane and pointing in the opposite direction, and so we should get (x,y,z) = (-1,0,1):
>> M*[1;0;1]
ans =
-1.0000
0.0000
1.0000
You can also get the same result by using the Rodrigues Rotation formula:
>> v = [1;0;1];
>> k = [0;0;1];
>> theta = pi;
>> vrot = v*cos(theta) + cross(k,v)*sin(theta) + k*(k.'*v)*(1-cos(theta))
vrot =
-1.0000
0.0000
1.0000
All in all, it's just another way of rotating a vector around an arbitrary axis, not just limited to the standard x, y or z.

Quaternions vs Axis + angle

I have been trying to find the difference between the 2 but to no luck minus this
The primary diff erence between
the two representations is that a quaternion’s axis of rotation is scaled
by the sine of the half angle of rotation, and instead of storing the angle in the
fourth component of the vector, we store the cosine of the half angle.
I have no idea what
sine of the half angle of rotation
or
cosine of the half angle
means?
Quaternios and Axis-angle are both 4D representations of 3D rotations/orientations and both have pro's and cons.
Axis-angle: represents the rotation by its angle a and the rotation axis n. For example, a rotation of 180 degrees around the Y-Axis would be represented as a = 180, n= {0,1,0}. The representation is very intuitive, but for actually applying the rotation, another representation is required, such as a quaternion or rotation matrix.
Quaternion: represents a rotation by a 4D vector. Requires more math and is less intuitive, but is a much more powerful representation. Quaternions are easily interpolated (blending) and it is easy to apply them on 3D point. These formula's can easily be found on the web. Given a rotation of a radians about a normalized axis n, the quaternion 4D vector will be {cos a/2, (sin a/2) n_x, (sin a/2) n_y, (sin a/2) n_z}. That's where the sine and cosine of the half angle come from.
It means that if you, for example, want to make a 180deg rotation around the Z axis (0,0,1), then the quaternion's real part will be cos(180deg/2)=0, and its imaginary part will be sin(180deg/2)*(0,0,1)=(0,0,1). That's q=0+0i+0j+1k. 90-degree rotation will give you q=cos(90deg/2)+sin(90deg/2)*(0i+0j+1k)=sqrt(2)/2+0i+0j+sqrt(2)/2*k, and so on.
OTOH, if you're asking what sine and cosine are, check if your languange provides sin() and cos() functions (their arguments will probably be in radians, though), and check out http://en.wikipedia.org/wiki/Sine.

Creating a cylinder with axis centered differently

I know Matlab has a function called cylinder to create the points for a cylinder when number of points along the circumference, and the radius length. What if I don't want a unit cylinder, and also don't want it to center at the default axis (for example along z-axis)? What would be the easiest approach to create such a cylinder? Thanks in advance.
The previous answer is fine, but you can get matlab to do more of the work for you (because the results of cylinder separate x,y,z components you need to work a little to do the matrix multiplication for the rotation). To have the center of base of the cylinder at [x0 y0 z0], scaled by [xf yf xf] (use xf=yf unless you want an elliptic cylinder), use:
[x y z] = cylinder;
h=mesh(x*xf+x0,y*yf+y0,z*zf+z0)
If you also want to rotate it so it isn't aligned along the z-axis, use rotate. For example, to rotate about the x-axis by 90 degrees, so it's aligned along the y-axis, use:
rotate(h,[1 0 0],90)
Multiply the points by your favourite combination of a scaling matrix, a translation matrix, and a rotation matrix.