% Cartoon of the photoelectric effect

vid = VideoWriter('photoelectricEffect.mp4','MPEG-4');
vid.Quality = 100;
vid.FrameRate = 30;
open(vid);
figure('units','pixels','position',[0 0 1920 1080],'ToolBar','none');
set(0,'defaultfigurecolor',[1 1 1]);
set(gca,'linewidth',7);
lp = [7 5 4]; % Angle of lighting 
grey = [0.64 0.64 0.64];
myNickel = [0.44 0.46 0.44];
myBlue = [0.4 0.44 0.73];

r = 0:0.05:0.05; % For cone arrowhead 
[X,Y,Z] = cylinder(r,50); % Arrow head
discR = 3.2; % Radius of metal disc 
[XX,YY,ZZ] = cylinder(discR,300); % Metal disc circular side 
[a,b,c] = sphere(50); % Electron 
re = 0.1; % electron radius
theta = 0:pi/180:2*pi; % Used to draw circular surface of metal sample 
circx = discR*cos(theta);
circy = discR*sin(theta);
circz = 0.0*circx;

% dark-red - red - orange - yellow - green - cyan - blue - violet custom colormap
rgb = customcolormap([0 0.14 0.28 0.43 0.57 0.72 0.86 1], {'#880000','#ff0000','#ff8800','#ffff00','#00ff00','#00cccc','#0000ff','#7f00ff'});
fliprgb = flip(rgb);
colormap(fliprgb);

xArrow = 0:1/180:1/4; % Quarter wavelength, 90 degrees for arrow head of photon symbol
yArrow = 0.0*xArrow;
zArrow = 0.5*(cos(2*pi*xArrow)).^2;
arrowLength = 0.23;
xCos = 0:1/180:3; % Wiggly part of incoming photon symbol
yCos = 0.0*xCos;

for lambda = 700:-1:350 % Deep red to near UV
    % Incident radiation color
    index = 1 + round(255*(700-lambda)/350);
    colNow = fliprgb(index,:);
    
    newplot
    hold off
    
    r2 = 0.02+0.0*xCos;
    [x,y,z] = cylinder(r2,40);
    for i = 1:41
        x(:,i) = 0.5*cos(2*pi*700*xCos'/lambda) + x(:,i);
    end
    wiggle1 = surf(x,y,z*3+1.4*(max(xArrow)*lambda/700)+arrowLength,...
        'FaceColor',colNow,'LineStyle',...
        'none','FaceLighting','flat','DiffuseStrength',1);
    rotate(wiggle1,[0 1 0],-50,[0,0,0]);
    
    hold on
    r3 = 0.02+0.0*xArrow;
    [x,y,z] = cylinder(r3,40);
    for i = 1:41
        x(:,i) = 0.5*(sin(2*pi*xArrow')).^2 + x(:,i);
    end
    wiggle2 = surf(x,y,z*0.25*1.4*(lambda/700)+arrowLength,...
        'FaceColor',colNow,'LineStyle',...
        'none','FaceLighting','flat','DiffuseStrength',1);
    rotate(wiggle2,[0 1 0],-50,[0,0,0]);
    
    arrowHead = surf(X,Y,Z*arrowLength,...
        'FaceColor',colNow,'LineStyle',...
        'none','FaceLighting','flat','DiffuseStrength',1);
    rotate(arrowHead,[0 1 0],-50,[0,0,0]);
    metalDisc = surf(XX,YY,ZZ-1,...
        'FaceColor',myNickel,'LineStyle',...
        'none','FaceLighting','gouraud','DiffuseStrength',1);
    fill3(circx,circy,circz,...
        myNickel,'LineStyle',...
        'none','FaceLighting','flat','DiffuseStrength',1);
    dumLine = plot3([0 0],[0 0],[-1 4.1],'Color','w');
    dumLine.Color(4) = 0.0; % alpha = 0; fully transparent
    
    if (lambda <= 580)
        LL = (580 - lambda)/50;
        LLx = LL*cosd(60);
        LLz = LL*sind(60);
        surf(re*a+LLx,re*b,re*c+LLz,...
            'FaceColor',myBlue,'LineStyle',...
            'none','FaceLighting','flat','DiffuseStrength',1);
        index = 1 + round(255*(580-lambda)/350);
        colNow = fliprgb(index,:);        
        mArrow3([-0.5*cosd(60) 0 -0.5*sind(60)],[(LL-re)*cosd(60) 0 (LL-re)*sind(60)],'color',...
            colNow,'stemWidth',0.016,'tipWidth',0.04);
    end
    axis equal 
    axis off
    axis tight
    light('Position',lp,'Style','infinite');
    set(gca, 'Projection','perspective');
    set(gca,'View',[64,17]);
    
    frame = getframe(gcf);
    writeVideo(vid,frame);
    hold off
end
% Output the movie as an mpg file
close(vid);