% function to draw Mandelbrot set with GUI controls
% mandel.m draws the Mandlebrot set. It takes a variable number of arguments.
% If you run it with no arguments (i.e., just type 'mandel'), you get the whole
% Mandelbrot set plotted in the square [-2.5, 1.5] x [-2,2].

% Note that there are crosshairs displayed in the figure that you can move
% with your mouse. If you use your left mouse button to click twice in the
% figure, once at the upper left and once at the lower right corner of a box
% inside the displayed figure, you will get a enlargement of that region
% (actually the region is automatically made into square).

% If you click the center mouse button you get prompted for a new `depth';
% (this is number of iterations it tries before giving up and coloring a pixel
% black) and a new value for 'pixels' (the size of a grid it uses; 10 gives a
% very rough figure and 1000 a more precise one; rough is faster and fine is
% better for a final product). Default for pixels is 500 (it uses a 500 x 500 grid).

% If you click in the figure with the right mouse button a separate window
% opens with the Julia set at that point. I have not implemented the enlargement
% feature here, although that would not be hard to do.

% If you run mandel(z,r) it draws the Mandelbrot set in a square with center
% z and side length r. Running mandel(z,r,p) does the same using a p x p grid of pixels

function mandel(varargin)
if nargin == 0
center=-.5;
radius=2;
n=2000;
elseif nargin==2
center=varargin{1};
radius=varargin{2};
n=500;
elseif nargin==3
center=varargin{1};
radius=varargin{2}
n=varargin{3};
else
return;
end

tic;
depth=50;
cx=real(center);
cy=imag(center);
delta=2*radius/n;
x1=cx-radius;
x2=cx+radius;
y1=cy-radius;
y2=cy+radius;
flag =1;
while flag==1
delta=(x2-x1)/n
x=[x1:delta:x2];
y=[y2:-delta:y1];
Lx=length(x);
Ly=length(y);
[X,Y] = meshgrid(x,y);
z0=X+i*Y;
size(z0);
z=zeros(Ly,Lx);
c=zeros(Ly,Lx);
for k=1:depth
z=z.^2+z0;
c(abs(z)<2)=k;
end
m=min(min(c));
M=max(max(c));
d=(M/(M-m))*(c-m);
image(d)
% choose how to label axes
axistype=1;
switch axistype
case 0 % no labels
axis off
case 1 % label with planar coordinates
horz=x1:(x2-x1)/4:x2;
for k=1:length(horz)
xlabels{k}=num2str(horz(k));
end
Lx;
xt=[[1:Lx/4:Lx],Lx];
xticks(xt)
xticklabels(xlabels)
vert=y2:(y1-y2)/4:y1;
for k=1:length(vert)
ylabels{k}=num2str(vert(k));
end
Ly;
yt=[[1:Ly/4:Ly],Ly];
yticks(yt)
yticklabels(ylabels)
case 2 % label with matrix coordiates
axis image
end % switch

% set colors to use
setc=flipud(jet(depth));
%colormap(jet(depth))
%colormap(hsv(depth))
%colormap(gray(depth))
%colormap(flipud(winter(depth)))
s=size(setc,1);
setc([s-1,s],:)=zeros(2,3);
colormap(setc)
% add a legend saying how colors give iterates
colorbar
toc;

% get data from mouse to draw new picture
[a(1),b(1),button]=ginput(1)
% if middle mouse button is hit, input new depth
depth=max(depth,min(min(c))+100);
switch button
case 1
[a(2),b(2)]=ginput(1);
case 2
depth=input('input new depth = ');
n=input('input new pixels = ');
case 3
z1=x1+delta*a(1);
z2=y2-delta*b(1);
fig=gcf;
julia(z1,z2);
figure(fig);
[a(1),b(1),button]=ginput(1)
[a(2),b(2)]=ginput(1);
end % switch
if button ~= 2
%[a,b]=ginput(2);
a=sort(a);
b=sort(b);
a2=x1+delta*a(2);
a1=x1+delta*a(1);
b1=y2-delta*b(2);
b2=y2-delta*b(1);
cx=(a1+a2)/2;
cy=(b1+b2)/2;
r=abs(a2-a1)/2;
x1=cx-r;
x2=cx+r;
y1=cy-r;
y2=cy+r;

end % if button
end % while
return;