Matlab: normalized cut implementation - matlab

I have implemented "normalized cut" segmentation. The change here is that, instead of giving an image as input, I have given an matrix of image. As my output looks odd to me. I need to know whether my implementation is correct or not.
Code:
clear all
tic;
% im = imread('lena.pgm');
im =[94 122 99 101 111 101;
99 92 103 87 107 116;
93 109 113 84 86 106;
5 17 6 54 56 53;
13 11 5 56 44 50;
0 10 5 49 42 51];
% resizing to avoid out of memory error
% cim=imresize(im,[100 100]);
cim=im;
[r, c]=size(cim);
ind=find(cim);
lind=length(ind);
[I,J]=ind2sub([r,c],ind);
% % I've used linear indexing to speed up the partitioning
% vectoring the pixel nodes
for i=1:lind
V1(i)=double(cim(ind(i)));
end
% normalizing to [0-1] scale
V=(V1./255);
% w is the weight matrix (similarity matrix or adjacency matrix)
w=zeros(lind,lind);
% r, sigmaI, sigmaX values
rad=4.5;
sigi=10;
sigx=25;
% computing the weight matrix
for i=1:lind
x1=I(i,1);
y1=J(i,1);
for j=1:lind
if (i==j)
w(i,j)=1;
else
x2=I(j,1);
y2=J(j,1);
dist=((x1-x2)^2 + (y1-y2)^2);
if sqrt(dist)>=rad
dx=0;
else
dx=exp(-((dist)/(sigx^2)));
end
pdiff=(V(i)-V(j))^2;
di=exp(-((pdiff)/(sigi)^2));
w(i,j)=di*dx;
end
end
end
d=zeros(lind,lind);
s=sum(w,2);
% the diagonal matrix for computing the laplacian matrix
for i=1:lind
d(i,i)=s(i);
end
A=zeros(lind,lind);
A=(d-w); % A is the laplacian matrix
% vt has the eigen vectors corresponding to eigen values in vl
% other eigs / eig functions in matlab can be used but I'm using the
% function to compute the 5 smallest eigenvectors
[vt,vl]=eigs(A,d,5,'sm');
% se has the second smallest eigen vector, third and so on
se=vt(:,2:4);
% % % % % Simultaneous 'k' partitions
k=6;
id=kmeans(se,k);
imp=cell(1,k);
pic=cell(1,k);
for i=1:k
imp{1,i}= find(id(:,1)==i);
mat=zeros(100,100);
in=imp{1,i};
mat(in)=cim(in);
pic{1,i}=uint8(mat);
% figure,imshow(pic{1,i});
end
% pic has the sub graphs or partitiond sub images
figure;
subplot(2,4,1);imshow(uint8(im));title('Original image');
subplot(2,4,2);imshow(uint8(cim));title('Preprocessed image');
subplot(2,4,3);imshow(pic{1,1});title('Partition 1');
subplot(2,4,4);imshow(pic{1,2});title('Partition 2');
subplot(2,4,5);imshow(pic{1,3});title('Partition 3');
subplot(2,4,6);imshow(pic{1,4});title('Partition 4');
subplot(2,4,7);imshow(pic{1,5});title('Partition 5');
subplot(2,4,8);imshow(pic{1,6});title('Partition 6');
toc;
Output:
Thanks in advance.

Related

Matlab calculating line parameter x for 10 layers in the given wavelength range

I know how to calculate the line parameter defined as x below for one layer, considering the given wavelength range 50 to 550 um. Now I want to repeat this calculation for all 10 layers. all the other parameters remain as a constant while temperature varies from layer 1 to 10.Any suggestion would be greatly appreciated.
wl=[100 200 300 400 500]; %5 wavelengths, 5 spectral lines
br=[0.12 0.56 0.45 0.67 0.89]; % broadening parameter for each wavelength
T=[101 102 103 104 105 106 107 108 109 110];% temperature for 10 layers
wlall=linspace(50,550,40);%all the wavelength in 50um to 550 um range
% x is defined as,
%(br*wl/(br*br + (wlall-wl)^2))*br;
%If I do a calculation for the first line
((br(1)*T(1)*wl(1))./(br(1)*br(1)*(T(1)) + (wlall(:)-wl(1)).^2))*br(1)*T(1)
%Now I'm going to calculate it for all the lines in the first layer
k= repmat(wlall,5,1);
for i=1:5;
kn(i,:)=(br(i)*T(1)* wl(i)./(br(i)*br(i)*T(1) + (k(i,:)-
wl(i)).^2))*br(i)*T(1);
end
%Above code gives me x parameter for all the wavelengths in the
%given range( 50 to 550 um) in the first layer, dimension is (5,40)
% I need only the maximum value of each column
an=(kn(:,:)');
[ll,mm]=sort(an,2,'descend');
vn=(ll(:,1))'
%Now my output has the dimension , (1,40) one is for the first layer, 40 is
%for the maximum x parameter corresponding to each wavelength in first layer
%Now I want to calculate the x parameter in all 10 layers,So T should vary
%from T(1) to T(10) and get the
%maximum in each column, so my output should have the dimension ( 10, 40)
You just need to run an extra 'for' loop for each value of 'T'. Here is an example:
clc; close all; clear all;
wl=[100 200 300 400 500]; %5 wavelengths, 5 spectral lines
br=[0.12 0.56 0.45 0.67 0.89]; % broadening parameter for each wavelength
T=[101 102 103 104 105 106 107 108 109 110];% temperature for 10 layers
wlall=linspace(50,550,40);%all the wavelength in 50um to 550 um range
% x is defined as,
%(br*wl/(br*br + (wlall-wl)^2))*br;
%If I do a calculation for the first line
((br(1)*T(1)*wl(1))./(br(1)*br(1)*(T(1)) + (wlall(:)-wl(1)).^2))*br(1)*T(1)
%Now I'm going to calculate it for all the lines in the first layer
k= repmat(wlall,5,1);
for index = 1:numel(T)
for i=1:5
kn(i,:, index)=(br(i)*T(index)* wl(i)./(br(i)*br(i)*T(index) + (k(i,:)- wl(i)).^2))*br(i)*T(index);
end
an(:, :, index) = transpose(kn(:, :, index));
vn(:, index) = max(an(:, :, index), [], 2);
end
vn = transpose(vn);

plot a curve as smaller parts, matlab

I have a sequence of points i wish to plot, but the resultant curve could be broken at places if the points are too far apart.
So in the 1D CASE :
1 2 3 7 9 11 12 16 18 19
Would be like :
1-2-3 7-9-11-12 16-18-19
or : seq1 seq2 seq3
I want to plot my sequence as discrete parts seq1 seq2 and seq3 which are not connected.
I am not too sure how to go about this
sea the code snippet below for a solution of your problem. I tried to explain as much in the code as possible, but don't hesitate to ask, if anything is not clear.
% constants, thresold defintion
T = 4;
% your data
a = [1 2 3 7 9 11 12 16 18 19 24 25 26 28 35 37 38 39];
% preparing the x-axis
x = 1:length(a);
% Getting the differences between the values
d = diff(a);
% find the suggested "jumps/gaps", greater/equal than the threshold
ind = find(d>=T);
figure;
hold on;
% Plotting the first part of a
y = nan*ones(1,length(a));
y(1:ind(1)) = a(1:ind(1));
plot(x,y);
% Plotting all parts in between: go through all found gaps
% and plot the corresponding values of "a" between them
for j=2:length(ind)
y = nan*ones(1,length(a));
y(ind(j-1)+1:ind(j)) = a(ind(j-1)+1:ind(j));
plot(x,y);
end;
% Plotting the last part of a
y = nan*ones(1,length(a));
y(ind(j)+1:end) = a(ind(j)+1:end);
plot(x,y);

Fitting the Cluster Number Based on the Centroid

I'm working with k-means in MATLAB. Here is my code:
load cobat.txt; % read the file
k=input('Enter a number: '); % determine the number of cluster
isRand=0; % 0 -> sequeantial initialization
% 1 -> random initialization
[maxRow, maxCol]=size(cobat);
if maxRow<=k,
y=[m, 1:maxRow];
else
% initial value of centroid
if isRand,
p = randperm(size(cobat,1)); % random initialization
for i=1:k
c(i,:)=cobat(p(i),:) ;
end
else
for i=1:k
c(i,:)=cobat(i,:); % sequential initialization
end
end
temp=zeros(maxRow,1); % initialize as zero vector
u=0;
while 1,
d=DistMatrix3(cobat,c); % calculate the distance
[z,g]=min(d,[],2); % set the matrix g group
if g==temp, % if the iteration doesn't change anymore
break; % stop the iteration
else
temp=g; % copy the matrix to the temporary variable
end
for i=1:k
f=find(g==i);
if f % calculate the new centroid
c(i,:)=mean(cobat(find(g==i),:),1)
end
end
c
sort(c)
end
y=[cobat,g]
"cobat" is the file of mine. Here it looks:
65 80 55
45 75 78
36 67 66
65 78 88
79 80 72
77 85 65
76 77 79
65 67 88
85 76 88
56 76 65
"c" is the variable of centroid (the central of the cluster) per each cluster. "g" is the variable to show the cluster number. The problem is, I want to sort/fit the cluster number (small to big) based on the centroid (c). So, I try to sort(c), but it doesn't affect to the cluster number (g).
When I try to sort(g), it's sorted just not like what I want. I want the cluster number is sorted based on the centroid. Example; when I run the code with k=3, here is the final centroid
73.0000 79.0000 70.6667 %C 1
58.3333 73.3333 84.6667 %C 2
36.0000 67.0000 66.0000 %C 3
When I sort it, the number cluster is also "sorted",
36.0000 67.0000 66.0000 %C 3
58.3333 73.3333 70.6667 %C 2
73.0000 79.0000 84.6667 %C 1
I want it the number cluster is fit, like this.
36.0000 67.0000 66.0000 %C 1
58.3333 73.3333 70.6667 %C 2
73.0000 79.0000 84.6667 %C 3
It's fit, not sorted, so when this line 'y=[cobat,g]' is run, it changes too.
This seems easy, but tricky. I couldn't figure out. Anyone have any idea to solve it?
Thank you.
Use the sorted indices returned from sort or sortrow
[B,index] = sortrows( c ); % sort the centroids
g = g(index(end:-1:1)); % arrange the labels based on centroids' order

Saving quantized coefficients to file

I am trying to read an image, DCT transform it, quantize it, and then save the quantized coefficients to a file that will be read into a fractal encoding program.
When I decode the file (with the quantized coefficients), all I get is some grey screen. Is this due to the contents of the file or am I missing out on something else?
%% LOSSY COMPRESSION-DECOMPRESSION USNIG DISCRETE COSINE TRANSFORM TECHNIQUE.
function[]=dct11(filename,n,m)
% "filename" is the string of characters including Image name and its
% extension.
% "n" denotes the number of bits per pixel.
% "m" denotes the number of most significant bits (MSB) of DCT Coefficients.
% Matrix Intializations.
N=8; % Block size for which DCT is Computed.
M=8;
I=imread('Lenna.bmp'); % Reading the input image file and storing intensity values in 2-D matrix I.
I_dim=size(I); % Finding the dimensions of the image file.
I_Trsfrm.block=zeros(N,M); % Initialising the DCT Coefficients Structure Matrix "I_Trsfrm" with the required dimensions.
Norm_Mat=[16 11 10 16 24 40 51 61 % Normalization matrix (8 X 8) used to Normalize the DCT Matrix.
12 12 14 19 26 58 60 55
14 13 16 24 40 57 69 56
14 17 22 29 51 87 80 62
18 22 37 56 68 109 103 77
24 35 55 64 81 104 113 92
49 64 78 87 103 121 120 101
72 92 95 98 112 100 103 99];
save('LenaInitial.dat','I');
%% PART-1: COMPRESSION TECHNIQUE.
% Computing the Quantized & Normalized Discrete Cosine Transform.
% Y(k,l)=(2/root(NM))*c(k)*c(l)*sigma(i=0:N-1)sigma(j=0:M-1)y(i,j)cos(pi(2i+1)k/(2N))cos(pi(2j+1)l/(2M))
% where c(u)=1/root(2) if u=0
% = 1 if u>0
for a=1:I_dim(1)/N
for b=1:I_dim(2)/M
for k=1:N
for l=1:M
prod=0;
for i=1:N
for j=1:M
prod=prod+double(I(N*(a-1)+i,M*(b-1)+j))*cos(pi*(k-1)*(2*i-1)/(2*N))*cos(pi*(l-1)*(2*j-1)/(2*M));
end
end
if k==1
prod=prod*sqrt(1/N);
else
prod=prod*sqrt(2/N);
end
if l==1
prod=prod*sqrt(1/M);
else
prod=prod*sqrt(2/M);
end
I_Trsfrm(a,b).block(k,l)=prod;
end
end
% Normalizing the DCT Matrix and Quantizing the resulting values.
I_Trsfrm(a,b).block=round(I_Trsfrm(a,b).block./Norm_Mat);
% save ('LenaCompressed1.txt');
end
end
%Andrew added this
% save ('LenaCompressed.txt');
% zig-zag coding of the each 8 X 8 Block.
for a=1:I_dim(1)/N
for b=1:I_dim(2)/M
I_zigzag(a,b).block=zeros(1,0);
freq_sum=2:(N+M);
counter=1;
for i=1:length(freq_sum)
if i<=((length(freq_sum)+1)/2)
if rem(i,2)~=0
x_indices=counter:freq_sum(i)-counter;
else
x_indices=freq_sum(i)-counter:-1:counter;
end
index_len=length(x_indices);
y_indices=x_indices(index_len:-1:1); % Creating reverse of the array as "y_indices".
for p=1:index_len
if I_Trsfrm(a,b).block(x_indices(p),y_indices(p))<0
bin_eq=dec2bin(bitxor(2^n-1,abs(I_Trsfrm(a,b).block(x_indices(p),y_indices(p)))),n);
else
bin_eq=dec2bin(I_Trsfrm(a,b).block(x_indices(p),y_indices(p)),n);
end
I_zigzag(a,b).block=[I_zigzag(a,b).block,bin_eq(1:m)];
end
else
counter=counter+1;
if rem(i,2)~=0
x_indices=counter:freq_sum(i)-counter;
else
x_indices=freq_sum(i)-counter:-1:counter;
end
index_len=length(x_indices);
y_indices=x_indices(index_len:-1:1); % Creating reverse of the array as "y_indices".
for p=1:index_len
if I_Trsfrm(a,b).block(x_indices(p),y_indices(p))<0
bin_eq=dec2bin(bitxor(2^n-1,abs(I_Trsfrm(a,b).block(x_indices(p),y_indices(p)))),n);
else
bin_eq=dec2bin(I_Trsfrm(a,b).block(x_indices(p),y_indices(p)),n);
end
I_zigzag(a,b).block=[I_zigzag(a,b).block,bin_eq(1:m)];
end
end
end
end
end
% Clearing unused variables from Memory space
clear I_Trsfrm prod;
clear x_indices y_indices counter;
% Run-Length Encoding the resulting code.
for a=1:I_dim(1)/N
for b=1:I_dim(2)/M
% Computing the Count values for the corresponding symbols and
% savin them in "I_run" structure.
count=0;
run=zeros(1,0);
sym=I_zigzag(a,b).block(1);
j=1;
block_len=length(I_zigzag(a,b).block);
for i=1:block_len
if I_zigzag(a,b).block(i)==sym
count=count+1;
else
run.count(j)=count;
run.sym(j)=sym;
j=j+1;
sym=I_zigzag(a,b).block(i);
count=1;
end
if i==block_len
run.count(j)=count;
run.sym(j)=sym;
end
end
% Computing the codelength needed for the count values.
dim=length(run.count); % calculates number of symbols being encoded.
maxvalue=max(run.count); % finds the maximum count value in the count array of run structure.
codelength=log2(maxvalue)+1;
codelength=floor(codelength);
% Encoding the count values along with their symbols.
I_runcode(a,b).code=zeros(1,0);
for i=1:dim
I_runcode(a,b).code=[I_runcode(a,b).code,dec2bin(run.count(i),codelength),run.sym(i)];
end
end
end
% Saving the Compressed Code to Disk.
save ('LenaCompressed.txt','I_runcode');
% Clearing unused variables from Memory Space.
clear I_zigzag run;
Andrew, you use MATLAB's save statement to save the coefficients into a file ending with .txt. What does the "fractal encoding program" assume about the file format?
Your file will not be a text file. Check out the documentation of save. Perhaps you can use the '-ascii' flag.
Otherwise, you may have to write that file of coefficients yourself. To get you started, I'd say fprintf is worth a look.

How do I reproduce this heart-shaped mesh in MATLAB?

I want to plot a heart shape wireframe as shown in the following image
(source):
I have tried to make it by using this MATLAB program:
n=100;
x=linspace(-3,3,n);
y=linspace(-3,3,n);
z=linspace(-3,3,n);
[X,Y,Z]=ndgrid(x,y,z);
F=((-(X.^2) .* (Z.^3) -(9/80).*(Y.^2).*(Z.^3)) + ((X.^2) + (9/4).* (Y.^2) + (Z.^2)-1).^3);
isosurface(F,0)
lighting phong
caxis
axis equal
colormap('flag');
view([55 34]);
But I didn't get the desired shape of framework as shown in the figure.
I have identified the problem: to create a wireframe we usually use the command mesh(). But this plotting facility only allow us to plot a function of two variables such as z=f(x,y). But my program makes use of three variables: F(x,y,z).
How can I solve the problem?
Here's my best attempt at reproducing the entire figure:
Generating the contoured heart mesh:
I used the contourc function to generate a series of contours in the x-y, x-z, and y-z planes. Notice that in the image you want to reproduce, the mesh lines on the back-facing side of the heart are not rendered. The quickest and easiest way I could think of to reproduce that aspect of the plot was to use isosurface to render a white surface just beneath the inside surface of the mesh, blocking the view of the back side.
Here's the code for the function heart:
function heart
% Initialize the volume data, figure, and axes:
[X,Y,Z] = meshgrid(linspace(-3,3,101));
F = -X.^2.*Z.^3-(9/80).*Y.^2.*Z.^3+(X.^2+(9/4).*Y.^2+Z.^2-1).^3;
hFigure = figure('Position',[200 200 400 400],'Color','w');
hAxes = axes('Parent',hFigure,'Units','pixels',...
'Position',[1 1 400 400],'NextPlot','add',...
'DataAspectRatio',[1 1 1],'Visible','off',...
'CameraViewAngle',10,...
'XLim',[32 70],'YLim',[39 63],'ZLim',[34 73]);
view([-39 30]);
% Create and plot contours in the y-z plane:
for iX = [35 38 41 45 48 51 54 57 61 64 67]
plane = reshape(F(:,iX,:),101,101);
cData = contourc(plane,[0 0]);
xData = iX.*ones(1,cData(2,1));
plot3(hAxes,xData,cData(2,2:end),cData(1,2:end),'k');
end
% Create and plot contours in the x-z plane:
for iY = [41 44 47 51 55 58 61]
plane = reshape(F(iY,:,:),101,101);
cData = contourc(plane,[0 0]);
yData = iY.*ones(1,cData(2,1));
plot3(hAxes,cData(2,2:end),yData,cData(1,2:end),'k');
end
% Create and plot contours in the x-y plane:
for iZ = [36 38 40 42 44 46 48 50 52 54 56 58 60 62 64 66 69 71]
plane = F(:,:,iZ);
cData = contourc(plane,[0 0]);
startIndex = 1;
if size(cData,2) > (cData(2,1)+1)
startIndex = cData(2,1)+2;
zData = iZ.*ones(1,cData(2,1));
plot3(hAxes,cData(1,2:(startIndex-1)),...
cData(2,2:(startIndex-1)),zData,'k');
end
zData = iZ.*ones(1,cData(2,startIndex));
plot3(hAxes,cData(1,(startIndex+1):end),...
cData(2,(startIndex+1):end),zData,'k');
end
% Fill the inside of the mesh with an isosurface to
% block rendering of the back side of the heart:
p = patch(isosurface(F,-0.001));
set(p,'FaceColor','w','EdgeColor','none');
end
Putting the figure together:
To reproduce the entire figure I first generated the heart mesh using the heart function above, then added the other elements around it. I also used a few submissions from The MathWorks File Exchange:
arrow.m from Erik Johnson (to generate the arrows)
myaa.m from Anders Brun (to create a nice anti-aliased final image)
Here's the code for the function I_Heart_Math (which generates the above figure):
function I_Heart_Math
% Initialize heart plot and adjust figure and axes settings:
heart;
set(gcf,'Position',[200 200 700 300],'Name','Original image');
offset = get(gca,'CameraPosition')-get(gca,'CameraTarget');
offset = 35.*offset./norm(offset);
set(gca,'Position',[65 -9 300 300],'CameraViewAngle',6,...
'XLim',[21+offset(1) 70],'YLim',[16+offset(2) 63],...
'ZLim',[32 81+offset(3)]);
% Create the axes and labels, offsetting them in front of the
% heart to give the appearance they are passing through it:
arrowStarts = [81 51 51; 51 86 51; 51 51 32]+repmat(offset,3,1);
arrowEnds = [21 51 51; 51 16 51; 51 51 81]+repmat(offset,3,1);
arrow(arrowStarts,arrowEnds,5,40,40);
text('Position',[22 52 48]+offset,'String','x','FontSize',12);
text('Position',[50 17 49]+offset,'String','y','FontSize',12);
text('Position',[46.5 51 81.5]+offset,'String','z','FontSize',12);
% Create the equation text:
text('Position',[51 47 28],'FontName','Bookman','FontSize',8,...
'HorizontalAlignment','center',...
'String',{'(x^2+^9/_4y^2+z^2-1)^3-x^2z^3-^9/_{80}y^2z^3=0'; ...
'-3 \leq x,y,z \leq 3'});
% Create the large-type text:
hI = text('Position',[4 52 69.5],'String','I',...
'FontAngle','italic','FontName','Trebuchet MS',...
'FontSize',116,'FontWeight','bold');
hM = text('Position',[80.5 50 42.5],'String','Math',...
'FontAngle','italic','FontName','Trebuchet MS',...
'FontSize',116,'FontWeight','bold');
% Create an anti-aliased version of the figure too (the larger
% fonts need some adjustment to do this... not sure why):
set(hI,'Position',[4 52 68],'FontSize',86);
set(hM,'Position',[80.5 50 41],'FontSize',86);
myaa;
set(hI,'Position',[4 52 69.5],'FontSize',116);
set(hM,'Position',[80.5 50 42.5],'FontSize',116);
set(gcf,'Name','Anti-aliased image');
end
A very elegant solution is given by #gnovice. I though I extend it by adding the other elements to replicate the figure pointed by the OP. I also added some cool animations!
% volume data
[X,Y,Z] = meshgrid(linspace(-3,3,101));
F = -X.^2.*Z.^3 - (9/80).*Y.^2.*Z.^3 + (X.^2 + (9/4).*Y.^2 + Z.^2 - 1).^3;
% initialize figure
hFig = figure('Menubar','none', 'Color','w');
pos = get(hFig, 'Position');
set(hFig, 'Position', [pos(1)-0.15*pos(3) pos(2) 1.3*pos(3) pos(4)]);
% initialize axes
hAxes = axes('Parent',hFig, 'DataAspectRatio',[1 1 1], ...
'XLim',[30 120], 'YLim',[35 65], 'ZLim',[30 75]);
view(-39,30);
axis off
% Fill the inside of the mesh with an isosurface to
% block rendering of the back side of the heart
patch(isosurface(F,-1e-3), 'FaceColor','w', 'EdgeColor','none')
hidden on % hidden surface removal
% contours in the y-z plane
for iX = [35 38 41 45 48 51 54 57 61 64 67]
plane = reshape(F(:,iX,:), [101 101]);
cData = contourc(plane, [0 0]);
xData = iX.*ones(1,cData(2,1));
line(xData, cData(2,2:end), cData(1,2:end), ...
'Color','r', 'Parent',hAxes)
pause(.1)
end
% contours in the x-z plane
for iY = [41 44 47 51 55 58 61]
plane = reshape(F(iY,:,:), [101 101]);
cData = contourc(plane, [0 0]);
yData = iY.*ones(1,cData(2,1));
line(cData(2,2:end), yData, cData(1,2:end), ...
'Color','r', 'Parent',hAxes)
pause(.1)
end
% contours in the x-y plane
for iZ = [36 38 40 42 44 46 48 50 52 54 56 58 60 62 64 66 69 71]
plane = F(:,:,iZ);
cData = contourc(plane, [0 0]);
startIndex = 1;
if size(cData,2) > (cData(2,1)+1)
startIndex = cData(2,1)+2;
zData = iZ.*ones(1,cData(2,1));
line(cData(1,2:(startIndex-1)), cData(2,2:(startIndex-1)), zData, ...
'Color','r', 'Parent',hAxes)
end
zData = iZ.*ones(1,cData(2,startIndex));
line(cData(1,(startIndex+1):end), cData(2,(startIndex+1):end), zData, ...
'Color','r', 'Parent',hAxes)
pause(.1)
end
% text
props = {'FontWeight','bold', 'FontAngle','italic', 'FontSize',100};
pause(.2)
text(7,50,70, 'I', props{:})
pause(.5)
text(80,50,43, 'Math', props{:})
pause(.2)
% xyz axes
line([20 80], [50 50], [52.5 52.5], 'Color','k')
line([50 50], [20 80], [52.5 52.5], 'Color','k')
line([50 50], [50 50], [30 80], 'Color','k')
text(20,50,50, 'x')
text(48,20,50, 'y')
text(45,50,80, 'z')
drawnow
% equation
props = {'FontSize',10, 'Interpreter','latex'};
text(20,65,30, '$(x^2+9/4y^2+z^2-1)^3 - x^2z^3-9/80y^2z^3=0$', props{:});
text(30,45,30, '$-3 \leq x,y,z \leq 3$', props{:});
drawnow
(The above GIF file was created using GETFRAME and IMWRITE).
This code plots the shaded surface:
% volume data
step = 0.05;
[X,Y,Z] = meshgrid(-3:step:3, -3:step:3, -3:step:3);
F = (-(X.^2).*(Z.^3)-(9/80).*(Y.^2).*(Z.^3))+((X.^2)+(9/4).*(Y.^2)+(Z.^2)-1).^3;
% shaded surface
isosurface(X,Y,Z,F,0)
lighting phong
axis equal
view(-39,30)
set(gcf, 'Color','w')
colormap flag
We could instead plot the wireframe only:
% volume data
step = 0.05;
[X,Y,Z] = meshgrid(-3:step:3, -3:step:3, -3:step:3);
F = (-(X.^2).*(Z.^3)-(9/80).*(Y.^2).*(Z.^3))+((X.^2)+(9/4).*(Y.^2)+(Z.^2)-1).^3;
% wireframe
patch(isosurface(X,Y,Z,F,0), 'FaceColor','w', 'EdgeColor','b')
daspect([1 1 1])
view(3)
axis tight equal
set(gcf, 'Color','w')