Hertzian dipole electric fields produced by an oscillating electron
Matlab code

% Cartoon movie of electric-field vectors induced by a moving charge

% This version moves the electron perpendicularly out of the plane of the field grid

clear; close all;

vid = VideoWriter('electricField1.mp4','MPEG-4');

vid.Quality = 100;

frmRate = 30;

vid.FrameRate = frmRate;

open(vid);

figure('units','pixels','position',[0 0 3840 2160],'ToolBar','none');

set(0,'defaultfigurecolor',[1 1 1]); % white background = [1 1 1]

set(gca,'linewidth',7);

lp = [2 1 1];

myBlue = [0.5 0.55 0.88];

myBlue2 = [0.61 0.67 0.92];

pos1 = [-0.1 -0.2 1.2 1.5];

[xx,yy,zz] = sphere(70);

r = 0.5; % Radius of electron

ampl = 1.25;

lambda = 16; % Wavelength in terms of grid dimensions

% Want c to assume a value so that waves move one wavelength/second

c = lambda/frmRate; % c = f lambda; f = 1s = frmRate frames

xMx = 28;

yMx = 28;

x = linspace(-xMx,xMx,2*xMx+1);

y = linspace(-yMx,yMx,2*yMx+1);

[X,Y] = meshgrid(x,y);

Z = 0.0*X;

R = (X.^2 + Y.^2).^0.5; % Matrix of distances of each element in the meshgrid from (0,0)

phi = atan2(Y,X); % In-plane angle of base of E-field vectors in x-y plane

subplot('position',pos1);

for frm = 0:29 % Time in units of 1/frmRate

newplot

hold on

plot3(X,Y,Z,'.y')

axis equal

axis off

set(gca, 'Projection','perspective');

set(gca,'View',[44,40]);

set(gcf,'Color','k');

campos([43 41 25]);

xlim([-xMx-0.1 xMx+0.1]);

ylim([-yMx-0.1 yMx+0.1]);

zlim([-4*ampl 4*ampl]);

accz = sin(2*pi*c*frm/lambda); % Acceleration of electron in z-direction

posz = -sin(2*pi*c*frm/lambda); % Position of electron in z-direction

theta = atan2(posz,R); % Out-of-plane angle of E-field vectors away from vertical

accperp = -ampl*sin(2*pi*c*(frm - abs(R)/c)/lambda).*R./(posz^2 + R.^2).^0.5;

arrowsEnds = accperp.*cos(theta); % z-position of arrow end

Efield = accperp./R;

delxy = accperp.*sin(theta); % In-plane shift of arrow end w.r.t. arrow start

delx = delxy.*cos(phi);

dely = delxy.*sin(phi);

for ii = 1:2*xMx+1

for jj = 1:2*yMx+1

if (X(jj,ii) ~= 0) || (Y(jj,ii) ~= 0)

arrowStartx = X(jj,ii);

arrowStarty = Y(jj,ii);

arrowStartz = Z(jj,ii);

arrowEndx = arrowStartx + delx(jj,ii);

arrowEndy = arrowStarty + dely(jj,ii);

arrowEndz = arrowsEnds(jj,ii);

% Determine whether arrow has nonzero length because

% mArrow3 totally craps out if it is zero. Took me forever

% to debug!!

delxa = arrowEndx - arrowStartx;

delya = arrowEndy - arrowStarty;

delza = arrowEndz - arrowStartz;

arrowLen = (delxa^2 + delya^2 + delza^2)^0.5;

if (arrowLen > 0)

h = mArrow3([arrowStartx arrowStarty arrowStartz],...

[arrowEndx arrowEndy arrowEndz],...

'color',myBlue2,'stemWidth',0.07,'tipWidth',0.1,...

'facealpha',(abs(Efield(jj,ii))/ampl)^0.35);

end

end

end

end

% Oscillating electron

surf(xx*r,yy*r,zz*r+posz,'FaceColor',myBlue,'EdgeColor','none');

light('Position',lp,'Style','infinite');

frame = getframe(gcf);

writeVideo(vid,frame);

hold off

end

% Output the movie as an mpg file

close(vid);

% Cartoon movie of electric-field vectors induced by a moving charge

% This version moves the electron in the plane of the field grid

clear; close all;

vid = VideoWriter('electricField2.mp4','MPEG-4');

vid.Quality = 100;

frmRate = 30;

vid.FrameRate = frmRate;

open(vid);

figure('units','pixels','position',[0 0 3840 2160],'ToolBar','none');

set(0,'defaultfigurecolor',[1 1 1]); % white background = [1 1 1]

set(gca,'linewidth',7);

lp = [2 1 1];

myBlue = [0.5 0.55 0.88];

myBlue2 = [0.61 0.67 0.92];

pos1 = [-0.1 -0.2 1.2 1.5];

[xx,yy,zz] = sphere(70);

r = 0.5; % Radius of electron

ampl = 1.25;

lambda = 16; % Wavelength in terms of grid dimensions

% Want c to assume a value so that waves move one wavelength/second

c = lambda/frmRate; % c = f lambda; f = 1s = frmRate frames

xMx = 28;

yMx = 28;

x = linspace(-xMx,xMx,2*xMx+1);

y = linspace(-yMx,yMx,2*yMx+1);

[X,Y] = meshgrid(x,y);

Z = 0.0*X;

subplot('position',pos1);

for frm = 0:29 % Time in units of 1/frmRate

newplot

hold on

plot3(X,Y,Z,'.y')

axis equal

axis off

set(gca, 'Projection','perspective');

set(gca,'View',[44,40]);

set(gcf,'Color','k');

campos([43 41 25]);

xlim([-xMx-0.1 xMx+0.1]);

ylim([-yMx-0.1 yMx+0.1]);

zlim([-4*ampl 4*ampl]);

accy = sin(2*pi*c*frm/lambda); % Acceleration of electron in y-direction

posy = -sin(2*pi*c*frm/lambda); % Position of electron in y-direction

R = (X.^2 + (Y-posy).^2).^0.5; % Matrix of distances of each element in the meshgrid from present position of electron

for ii = 1:2*xMx+1

for jj = 1:2*yMx+1

if (X(jj,ii) ~= 0) || (Y(jj,ii) ~= 0)

% Value of position of electron as detected by field point

% after field propagates out from centre

posyHere = -sin(2*pi*c*(frm - abs(R(jj,ii))/c)/lambda);

alpha = atan2((Y(jj,ii)-posyHere),X(jj,ii)); % Angle of grid elements relative to electron

accperp = -ampl*posyHere*cos(alpha); % Perpendicular component of acceleration

Efield = accperp/R(jj,ii);

arrowStartx = X(jj,ii);

arrowStarty = Y(jj,ii);

arrowStartz = Z(jj,ii);

arrowEndx = arrowStartx - accperp*sin(alpha);

arrowEndy = arrowStarty + accperp*cos(alpha);

arrowEndz = 0;

% Determine whether arrow has nonzero length because

% mArrow3 totally craps out if it is zero. Took me forever

% to debug!!

delxa = arrowEndx - arrowStartx;

delya = arrowEndy - arrowStarty;

delza = arrowEndz - arrowStartz;

arrowLen = (delxa^2 + delya^2 + delza^2)^0.5;

if (arrowLen > 0)

h = mArrow3([arrowStartx arrowStarty arrowStartz],...

[arrowEndx arrowEndy arrowEndz],...

'color',myBlue2,'stemWidth',0.07,'tipWidth',0.1,...

'facealpha',(abs(Efield)/ampl)^0.35);

end

end

end

end

% Oscillating electron

surf(xx*r,yy*r+posy,zz*r,'FaceColor',myBlue,'EdgeColor','none');

light('Position',lp,'Style','infinite');

frame = getframe(gcf);

writeVideo(vid,frame);

hold off

end

% Output the movie as an mpg file

close(vid);

% Cartoon movie of electric-field vectors induced by a moving charge

% This version moves the electron in a circular path, inducing circular

% polarization

clear; close all;

vid = VideoWriter('electricField3.mp4','MPEG-4');

vid.Quality = 100;

frmRate = 30;

vid.FrameRate = frmRate;

open(vid);

figure('units','pixels','position',[0 0 3840 2160],'ToolBar','none');

set(0,'defaultfigurecolor',[1 1 1]); % white background = [1 1 1]

set(gca,'linewidth',7);

% Read in image files for white x, y, RCP, and LCP labels

lp = [2 1 1];

myBlue = [0.5 0.55 0.88];

myBlue2 = [0.61 0.67 0.92];

pos1 = [-0.4 -0.4 1.91 1.9];

xMx = 32;

yMx = 32;

[xx,yy,zz] = sphere(70);

r = 0.5; % Radius of electron

ampl = 1.25; % Radius of circular path

Eampl = 4; % Maximum amplitude of E-field

% Vector of alpha values for fading in and out of the RCP and LCP labels

alpRCPLCP = [zeros(1,150) 1/75:1/75:1 ones(1,150) 1:-1/75:1/75 zeros(1,150)];

[xa,ya,za] = cylinder([0.2 0]); % Used to generate the axis arrow heads

lambda = 20; % Wavelength in terms of grid dimensions

x = -xMx:0.5:xMx;

subplot('position',pos1);

for frm = 0:599 % Time in units of 1/frmRate

newplot

hold on

axis equal

axis off

set(gca, 'Projection','perspective');

set(gcf,'Color','k');

% Varying camera position

campos([69*cos(2*pi*frm/4800+pi/6) 67*sin(2*pi*frm/4800+pi/6) 29]);

xlim([-xMx-2 xMx+2.1]);

ylim([-yMx-2 yMx+2]);

zlim([-7 7]);

axisArrowx = surf(xa,ya,za+xMx+0.25,'FaceColor','w','LineStyle','none',...

'FaceLighting','gouraud','DiffuseStrength',1);

axisArrowy = surf(xa,ya,za+xMx,'FaceColor','w','LineStyle','none',...

'FaceLighting','gouraud','DiffuseStrength',1);

% Draw x- and y-axes

plot3([-xMx xMx+0.25],[0 0],[0 0],...

'color','w', 'LineWidth', 1);

tickLimx = xMx - mod(xMx,5);

for ii = -tickLimx:5:tickLimx

plot3([ii ii],[-0.25 0.25],[0 0],...

'color','w', 'LineWidth', 1);

end

rotate(axisArrowx,[0 1 0],90,[0,0,0]);

surf([xMx+1.4 xMx+2.1; xMx+1.4 xMx+2.1],[0 0; 0 0],[-0.35 -0.35; 0.35 0.35],...

whitex,'FaceColor','texturemap','FaceAlpha','texturemap',...

'none','FaceLighting','none');

plot3([0 0],[-yMx yMx],[0 0],...

'color','w', 'LineWidth', 1);

tickLimy = yMx - mod(yMx,5);

for ii = -tickLimy:5:tickLimy

plot3([-0.25 0.25],[ii ii],[0 0],...

'color','w', 'LineWidth', 1);

end

rotate(axisArrowy,[1 0 0],-90,[0,0,0]);

surf([0 0; 0 0],[yMx+1.2 yMx+1.9; yMx+1.2 yMx+1.9],[0.35 0.35; -0.41 -0.41],...

whitey,'FaceColor','texturemap','FaceAlpha','texturemap',...

'none','FaceLighting','none');

% Oscillating electron and acceleration arrow

surf(xx*r,yy*r + ampl*sin(2*pi*frm/60),zz*r - ampl*cos(2*pi*frm/60),...

'FaceColor',myBlue,'EdgeColor','none');

elAccArrow = mArrow3([0 0 -ampl],...

[0 0 3*ampl],'color','r','stemWidth',0.125,'tipWidth',0.25);

rotate(elAccArrow,[1 0 0],360*frm/60,[0,0,0]);

% R, the distance of electric-field position along x-axis from present

% position of the electron

R = (1 + x.^2).^0.5;

% Angle of R relative to x-axis

theta = atan2(1,x);

accperp = cos(theta); % Acceleration of electron perpendicular to R

% Draw E-field arrows

for ii = 1:4*xMx+1

if (accperp(ii) ~= 0)

arrowStartx = x(ii);

arrowStarty = 0;

arrowStartz = 0;

arrowEndx = x(ii);

arrowEndy = 0;

arrowEndz = -Eampl*accperp(ii);

h = mArrow3([arrowStartx arrowStarty arrowStartz],...

[arrowEndx arrowEndy arrowEndz],...

'color',myBlue2,'stemWidth',0.07,'tipWidth',0.125);

% Rotate around y to get perpendicular angle

rotate(h,[0 1 0],-(180/pi)*theta(ii),[x(ii),0,0]);

% Rotate around x to generate circular polarization

rotate(h,[1 0 0],360*(frm/60 - R(ii)/lambda),[x(ii),0,0]);

end

end

alphaMap3a = im2double(alphaMap3)*alpRCPLCP(1,frm+1);

RCPlabel = surf([xMx/2+4 xMx/2; xMx/2+4 xMx/2],[0 0; 0 0],[6.5 6.5; 5 5],...

RCP,'FaceColor','texturemap','FaceAlpha','texturemap',...

'none','FaceLighting','none');

alphaMap4a = im2double(alphaMap4)*alpRCPLCP(1,frm+1);

LCPlabel = surf([-xMx/2 -xMx/2-4; -xMx/2 -xMx/2-4],[0 0; 0 0],[6.5 6.5; 5 5],...

LCP,'FaceColor','texturemap','FaceAlpha','texturemap',...

'none','FaceLighting','none');

light('Position',lp,'Style','infinite');

frame = getframe(gcf);

writeVideo(vid,frame);

hold off

end

% Output the movie as an mpg file

close(vid);