I am doing an assignment for my course where I need to rotate a cube about a given axis. I can not use MATLAB functions, so I need to do it manually.
This is my attempt that is to no avail.
`
function [ CV ] = rotateCubeX( CV, degrees )
%CV = input vertices/Return val
%degrees = amount of degrees to rotate
alpha = degrees * pi/180;
rotate = zeros(3,3);
rotate(1,1) = 1;
rotate(2,2) = cos(alpha);
rotate(2,3) = -sin(alpha);
rotate(3,2) = sin(alpha);
rotate(3,3) = cos(alpha);
CV = CV * rotate;
end
Before:
25.2000 5.9000 2.5000
25.7000 5.9000 2.5000
25.7000 7.9000 2.5000
25.2000 7.9000 2.5000
25.2000 5.9000 2.8000
25.7000 5.9000 2.8000
25.7000 7.9000 2.8000
25.2000 7.9000 2.8000
After:
-10.3544 -23.7200 2.5000
-10.6536 -24.1205 2.5000
-9.0513 -25.3175 2.5000
-8.7521 -24.9169 2.5000
-10.3544 -23.7200 2.8000
-10.6536 -24.1205 2.8000
-9.0513 -25.3175 2.8000
-8.7521 -24.9169 2.8000
No change in image.
I am sure I am forgetting something silly.
What is the axis you expect to rotate about? How have you accounted for that in your code?
If you are trying to rotate about an arbitrary axis, then the general formula for rotation about an arbitrary axis is here. (look under Other Ways to Build a Rotation Matrix). Pay attention to handedness and whether you are using row-major or column major matrices!
Related
I used corrcoef function of matlab to find correlation between two images.
First I use Correlation between all corresponding points
A_2=double(imread('prometmonew1.tif'));
B_2=double(imread('lai5min1bas1.tif'));
R = corrcoef(A_2(:),B_2(:))
The result is
R =
1.0000 1.0000
1.0000 1.0000
but when I remove some parts of the images (backgrounds) and then I use this function again the correlation is different(the values of backgrounds are negative), how is it possible? whats wrong?
V=find(A_2>=0);
A=A_2(V);
V_1=find(B_2>=0);
B=B_2(V_1);
R = corrcoef(A,B)
R =
1.0000 0.3275
0.3275 1.0000
Thanks in advance
How to do linear interpolation for a vector corresponding to a constant section? For example we have a matrix of two column as follow.
Matrix =
125.2985 5.7057
125.2991 5.7098
125.2997 5.6880
125.3004 5.6739
125.3010 5.7140
125.3016 6.0141
125.3022 6.3620
125.3029 6.4793
125.3041 6.4665
125.3047 6.4646
125.3053 6.4844
125.3060 6.4743
125.3066 6.4865
125.3072 6.4878
125.3078 6.4975
125.3085 6.4952
125.3091 6.4958
125.3128 6.5867
125.3134 7.0733
125.3141 7.3427
125.3147 7.3238
125.3153 7.3093
125.3159 7.3188
125.3166 7.3436
A second matrix is as 'C'.
C =
125.2985 2.0000
125.3004 3.0000
125.3053 5.0000
125.3085 4.0000
125.3147 6.0000
125.3166 7.0000
Now I need to do interpolation of 'C(:,2)' values for 'Matrix(:,1)'. The out put result of linear interpolation is as follow
Cinter=interp1(C(:,1),C(:,2),Matrix(:,1),'linear')
Cinter =
2.0000
2.3158
2.6316
3.0000
3.2449
3.4898
3.7347
4.0204
4.5102
4.7551
5.0000
4.7813
4.5937
4.4063
4.2187
4.0000
4.1935
5.3871
5.5806
5.8065
6.0000
6.3158
6.6316
7.0000
But I want to do interpolation only for those data points where 'Matrix(:,2)' is fairly stable. The rest should be as NaN in the interpolated vector. The required output should be as follow instead of 'Cinter'. How to achieve this?
output1=
2.0000
2.3158
2.6316
3.0000
NaN
NaN
NaN
NaN
NaN
NaN
5.0000
4.7813
4.5937
4.4063
4.2187
4.0000
NaN
NaN
NaN
NaN
6.0000
6.3158
6.6316
7.0000
This also can be taken a step further to achieve a second desired output. Based on first 'output1' data points (NaN) at constant 'Matrix(:,2)' can be replaced by nearby 'C(:,2) value'. The second output would be as follow and how to get this?
output2=
2.0000
2.3158
2.6316
3.0000
3.0000
NaN
NaN
5.0000
5.0000
5.0000
5.0000
4.7813
4.5937
4.4063
4.2187
4.0000
4.0000
4.0000
NaN
6.0000
6.0000
6.3158
6.6316
7.0000
Thank you very much.
Best regards
To find stable regions, you could estimate derivatives (presumably first and/or second depending on what you mean by "stable") and then select only those within some range; e.g. using gradient for the first derivative:
stable = abs(gradient(Matrix(:,2),Matrix(:,1))) < 50;
Cinter = NaN(size(Matrix,1),1);
Cinter(stable) = interp1(C(:,1),C(:,2),Matrix(stable,1),'linear')
If you want to keep every point that has low slope on the left or on the right, you could try something like:
grad = diff(Matrix(:,2)) ./ diff(Matrix(:,1));
leftgrad = [0; grad];
rightgrad = [grad; 0];
stable2 = abs(leftgrad) < 50 | abs(rightgrad) < 50;
You could then use stable2 instead of stable above; if you insist on picking the value at the closest point (rather than the interpolated points), why not do:
boundary = stable2 & not(stable);
Cinter(boundary) = interp1(C(:,1),C(:,2),Matrix(boundary,1),'nearest')
I have a matrix with the first row and the first column are data. Based on the row and the column, I wanna to find values in the matrix.
For example, I have the matrix look like this
A =
0.1000 1.0000 10.0000 100.0000
1.0000 0.9000 0.4000 0.5000
If the row data is 1 (the second row) and the column data is 10 (the third column), then I get 0.4 value.
Is there a way to find that value?
In case of the row data is 0.2 and the column data is 0.2, for example. How can I find values from that matrix?
Thank you for your respond.
Exact match case
%// Inputs (Added One more row to original post to include multiple match case)
A =[
0.1000 1.0000 10.0000 10.0000
1.0000 0.9000 0.4000 0.5000
1.0000 0.6000 0.5000 0.6000]
row_data = 1.0;
column_data = 10.0;
Now, if you are looking to find the values corresponding to all the matches, use this -
value = A(find(A(:,1)==row_data),find(A(1,:)==column_data))
giving us -
value =
0.4000 0.5000
0.5000 0.6000
Otherwise, if you are looking to find the value corresponding to just the first match, use this -
value = A(find(A(:,1)==row_data,1),find(A(1,:)==column_data,1))
giving us -
value =
0.4000
Also, please be mindful of the precision issues involved with floating point numbers. This shouldn't be a problem here because we have specifically mentioned the numbers and no other calculations had been done between matching and inputting the inputs.
Inexact match case
For cases when there aren't exact matches available, you can use interpolation as shown in codes next -
x = A(1,2:end)
y = A(2:end,1)
[X,Y] = meshgrid(x,y)
V = A(2:end,2:end)
row_data = 1.0;
column_data = 10.0;
value = interp2(X,Y,V,column_data,row_data)
If your Xq or Yq values are outside the X and Y ranges respectively, you need to do extrapolation, for which I think you can use scatteredInterpolant instead of interp2.
I have two sets of data. Each of them is a matrix and they have two columns, first column represents index x and second represents y. I want to see how similar are the curves of these datasets. In other words I need to have the correlation of these two curves represented by two matrices.
Thanks for help.
You might be looking for the corr2 function which calculates the correlation coefficient for each corresponding values in your matrices:
CorrMatrix = corr2(A,B)
plot(x,CorrMatrix);
Is that what you meant? If not please don't hesitate to ask for more details.
For matrices of unequal size I think you only have these options:
If you have the Signal Processing Toolbox you can use the cross-correlation function xcorr2, otherwise you can do the following:
1)either you calculate the correlation of you data where you use a part of the larger matrix so that the number of elements are similar: (the values I use are really dummy values sorry.)
clear
clc
% Create dummy matrices of unequal sizes
x =1:10;
x2 = 1:6;
A(:,1) = x;
A(:,2) = sin(x);
B(:,1) = x2;
B(:,2) = cos(x2);
A,B
C = corr2(A(1:6,:),B)
A =
1.0000 0.8415
2.0000 0.9093
3.0000 0.1411
4.0000 -0.7568
5.0000 -0.9589
6.0000 -0.2794
7.0000 0.6570
8.0000 0.9894
9.0000 0.4121
10.0000 -0.5440
B =
1.0000 0.5403
2.0000 -0.4161
3.0000 -0.9900
4.0000 -0.6536
5.0000 0.2837
6.0000 0.9602
C =
0.9463
or 2)
After some googling I saw that a similar question was posted here, in which it said that you can play around with Fourier transforms to get the correlation:
Cross-correlation in matlab without using the inbuilt function?
I'm trying to make a stacked bar plot that should show how different types of rock are varying with depth. I have generated some fictive lithology series based on some real data and want to present them in a readable way. So now I have this matrix A:
A =
2.0000 65.0000
1.0000 19.5000
2.0000 0.5000
4.0000 1.5000
2.0000 58.0000
4.0000 2.0000
2.0000 22.5000
3.0000 7.0000
2.0000 14.5000
3.0000 12.5000
4.0000 2.5000
2.0000 31.5000
1.0000 20.0000
2.0000 20.0000
1.0000 15.5000
2.0000 66.0000
4.0000 0.5000
2.0000 2.5000
3.0000 8.0000
2.0000 61.0000
1.0000 17.5000
2.0000 8.0000
5.0000 19.5000
3.0000 24.5000
where the first column represents the different rock types and the second column the thickness (in meters) of each lithology layer. And now I want to plot this looking like a core-data log. So each rock type, from 1-5, should have one specific color, and the thickness of each colored bar should represent the thickness of that rock type. How can I achieve this?
Aggregate per type
You can find the total thickness of each rock type by using accumarray:
total_type_thickness = accumarray(A(:,1),A(:,2));
It sums up all values of the second column with equal number in the first column. So for your example data, this returns:
total_type_thickness =
72.5000
349.5000
52.0000
6.5000
19.5000
The difficult thing is displaying it as a single stacked bar, you can try using this workaround:
http://www.mathworks.com/matlabcentral/newsreader/view_thread/57304
which leaves you with an empty column, which you can hide by setting the x limits:
bar([total_type_thickness'; zeros(size(total_type_thickness'))],'stacked');
xlim([0.25 1.75])
% add a legend with 'Rock Type <ii>'
legend(arrayfun(#(ii) sprintf('Rock type %d',ii), 1:length(total_type_thickness), 'uni',false));
For now, I haven't found a better alternative, as matlab won't stack the bars if you input vector data, it plots the bars separately in that case..
Display all values, same color per type
For plotting all the data (all layers), you can use the same approach, but now set the color data manually with colormap:
N = size(A,1); % number of layers
M = max(A(:,1)); % number of different rock types
bar([A(:,2)' ; NaN(1,N)],'stacked','facecolor','flat');
xlim([0.25 1.75])
cc = jet(M); % create colormap with N different colors
colormap(cc(A(:,1),:)); % pick for each layer, the correct color and use it as a colormap
For easier adding a legend, I'll add M dummy values to the original data:
bar([NaN(1,M) A(:,2)' ; NaN(1,N+M)],'stacked','facecolor','flat');
xlim([0.25 1.75])
cc = jet(M); % create colormap with N different colors
colormap(cc([(1:M)' ;A(:,1)],:)); % pick for each layer, the correct color and use it as a colormap
Now the first M elements in the legend will correspond to Rock type 1,2,.. M:
legend(arrayfun(#(ii) sprintf('Rock type %d',ii), 1:length(total_type_thickness), 'uni',false));