% Program to animate crystal movements in a four-bounce mono 
clear; close all; 

figure('units','pixels','position',[0 0 1920 1080],'ToolBar','none'); 
vid = VideoWriter('fourbounceMovement.mp4','MPEG-4'); 
vid.FrameRate = 30;    % Default 30
vid.Quality = 100;    % Default 75
open(vid); 
set(0,'defaultfigurecolor',[1 1 1]);
set(gca,'linewidth',7); 

% Some dimensions of the mono 
h= 0.1; % beam half height 
d = 1; % channel height 
thSt = 35; % starting angle 
thEnd = 15; % ending angle 
thStep = -0.25; % angle step size 
mirrorX = 4.25; % mirror plane of two crystals in the four-bounce configuration 

fwd = [thSt:thStep:thEnd]; 

X1x = [-1.5 1.0 1.0 -1.5]; % x-coords X1 first channel cut
X1y = [0 0 -0.5 -0.5]; % y-coords X1 first channel cut
X2x = [-1 4.5 4.5 -1]; % x-coords X2 first channel cut
X2y = [1 1 1.5 1.5]; % y-coords X2 first channel cut
Brix = [-1 1 1 -1]; % x-coords bridge piece first channel cut
Briy = [0 0 1 1]; % y-coords bridge piece first channel cut 
mirX1x = 2*mirrorX - [-1.5 1.0 1.0 -1.5]; % x-coords X1 second channel cut
mirX2x = 2*mirrorX - [-1 4.5 4.5 -1]; % x-coords X2 second channel cut
mirBrix = 2*mirrorX - [-1 1 1 -1]; % x-coords bridge piece second channel cut

% Create rgb progression through a rainbow 
bot = 0:8:120; % 0 to 7f in 16 steps 
top = 128:8:248; % 80 to ff 
all = 0:16:240; % 0 to ff 
botc = 0*all; % vector of zeros 
midc = botc + 127; % vector of 127s 
topc = botc + 255; % vector of 255s 
rcomp = [top topc topc flip(all) botc botc bot flip(bot)]/256; % R in rgb 
gcomp = [botc bot top flip(top) midc flip(bot) botc botc]/256; % G in rgb 
bcomp = [botc botc botc botc bot midc midc flip(bot)]/256; % B in rgb 

grey = [0.5 0.5 0.5]; 
dkgrey = [0.3 0.3 0.3]; 

% for th = [fwd flip(fwd)]

for th = [fwd flip(fwd)]
    newplot 
    hold on
    OA = d/sind(th); 
    BLx = -h/tand(th); 
    BLy = -h; 
    BRx = h/tand(th); 
    BRy = h; 
    TLx = BLx + OA*cosd(2*th); 
    TLy = BLy + OA*sind(2*th); 
    TRx = BRx + OA*cosd(2*th);
    TRy = BRy + OA*sind(2*th);
    X2 = fill(X2x,X2y,grey,'LineStyle','none'); 
    rotate(X2,[0 0 1],th,[0,0,0]);
    Bridge = fill(Brix,Briy,dkgrey,'LineStyle','none'); 
    rotate(Bridge,[0 0 1],th,[0,0,0]);

    for ii = -h:h/10:h
        axis off
        axis equal
        x = [-4,ii/tand(th)];
        y = [ii,ii];
        colIndex = round(6*(1 + (ii+h)*90));
        plot(x,y,'color',[rcomp(colIndex),gcomp(colIndex),bcomp(colIndex)],'LineWidth',2);
    end
    beamColInd = round(abs((thSt - th)/(thSt - thEnd))*120) + 1;
    monoBeam1 = fill([BLx BRx TRx TLx],[BLy BRy TRy TLy],...
        [rcomp(beamColInd),gcomp(beamColInd),bcomp(beamColInd)],'LineStyle','none');
    set(monoBeam1,'facealpha',.5)
    

    X1 = fill(X1x,X1y,grey,'LineStyle','none');
    rotate(X1,[0 0 1],th,[0,0,0]); 
    
    % Second channel-cut crystal 
    BLx = 2*mirrorX - BLx; 
    BLy = -h; 
    BRx = 2*mirrorX - BRx; 
    BRy = h; 
    TLx = 2*mirrorX - TLx; 
    TLy = BLy + OA*sind(2*th); 
    TRx = 2*mirrorX - TRx;
    TRy = BRy + OA*sind(2*th);
    mirX2 = fill(mirX2x,X2y,grey,'LineStyle','none'); 
    rotate(mirX2,[0 0 1],-th,[2*mirrorX,0,0]);
    Bridge = fill(mirBrix,Briy,dkgrey,'LineStyle','none'); 
    rotate(Bridge,[0 0 1],-th,[2*mirrorX,0,0]);
    mirX1 = fill(mirX1x,X1y,grey,'LineStyle','none');
    rotate(mirX1,[0 0 1],-th,[2*mirrorX,0,0]); 
    monoBeam2 = fill([TLx TRx 2*mirrorX-TRx 2*mirrorX-TLx TLx],...
        [TLy TRy TRy TLy TLy],[rcomp(beamColInd), gcomp(beamColInd),...
        bcomp(beamColInd)],'LineStyle','none');
    set(monoBeam2,'facealpha',.5) 
    monoBeam3 = fill([BLx BRx TRx TLx],[BLy BRy TRy TLy],[rcomp(beamColInd),...
        gcomp(beamColInd),bcomp(beamColInd)],'LineStyle','none');
    set(monoBeam3,'facealpha',.5)
    monoBeam4 = fill([BLx BRx 11.85 12 11.85 BLx],[BLy BRy BRy BRy-h BLy BLy],...
        [rcomp(beamColInd), gcomp(beamColInd),bcomp(beamColInd)],'LineStyle','none');
    set(monoBeam4,'facealpha',.5)
    viscircles([0 0],0.044,'LineWidth',4,'Color','k');
    viscircles([2*mirrorX 0],0.044,'LineWidth',4,'Color','k');
    
    xlim([-4 12]);
    ylim([-1.5 4]);
        
    hold off 
    % Store the frame
    frame = getframe(gcf);
    writeVideo(vid,frame);
end
% Output the movie as an mpg file
close(vid);
