Physics Beyond Our Senses
The following function will generate the animation in
Matlab. If you are interested, feel free to use it. Please
cut and paste, looking at the HTML source is a waste of
time, because of the syntax highlighting directives.
The highlighting is done using
highlight.m (© 2003 Guillaume Flandin)
clear ;
close ;
h = subplot(1,1,1) ;
set(h,'xtick',[]) ;
set(h,'ytick',[]) ;
title('Superluminal motion and our perception of it') ;
fprintf('Hit <enter> if ready to go: ') ;
pause ;
nStep = 50 ;
nY = 25 ;
nZm = 4 ;
nMovie = 8 ;
nMarg = 5 ;
xMarg = nMarg*nZm ;
beta = 10 ;
[x,y] = cylinder(1,32) ;
xG = x(1,:)' ;
yG = y(1,:)' ;
lObj = 3 ;
xObj = xG * lObj ;
yObj = yG * lObj ;
maxG = ceil(nStep+nMarg*2) ;
nG = 0 ;
hGs = zeros(maxG,1) ;
hRays = zeros(maxG,1) ;
for iG=1:maxG
hRays(iG) = line([0 -lObj],[0 -lObj]);
set(hRays(iG),'color','r') ;
hGs(iG) = patch(xG-lObj,yG-lObj,'r') ;
end
xStart = 0 ;
xEnd = nStep*nZm ;
yStart = nY*nZm ;
hTrace = line([xStart, xStart],[yStart yStart]) ;
hObj = patch(xObj+xStart,yObj+yStart,'w') ;
set(hTrace,'color','k') ;
hPhantom1 = patch(xObj-lObj,yObj-lObj,'g') ;
hPhantom2 = patch(xObj-lObj,yObj-lObj,'y') ;
axis([0 xEnd 0 1.5*yStart]) ;
xO = (xStart+xEnd)/2 ;
yO = 0 ;
dx = zeros(maxG,1) ;
dy = zeros(maxG,1) ;
xEmit = zeros(maxG,1) ;
yEmit = zeros(maxG,1) ;
iFrame = 0 ;
FirstCross = true ;
for iStep=-xMarg:xEnd*(1+beta)
xNow = xStart+iStep ;
yNow = yStart ;
set(hObj,'xdata',xObj+xNow) ;
set(hTrace,'xdata',[xStart xNow]) ;
if (mod(iStep,nZm) == 0 && nG<maxG)
nG = nG + 1;
set(hGs(nG),'xdata',xG+xNow,'ydata',yG+yNow) ;
ddx = (xO-xNow) ;
ddy = (yO-yNow) ;
r = sqrt(ddx*ddx+ddy*ddy)*beta ;
dx(nG) = ddx/r ;
dy(nG) = ddy/r ;
xEmit(nG) = xNow ;
yEmit(nG) = yNow ;
end
xMin = xEnd ;
xMax = xStart ;
nAbove = 0 ;
for iG=1:nG
xpos = get(hGs(iG),'xdata')+dx(iG) ;
ypos = get(hGs(iG),'ydata')+dy(iG) ;
set(hGs(iG),'xdata',xpos,'ydata',ypos) ;
xcent = mean(xpos) ;
ycent = mean(ypos) ;
xpos = [xEmit(iG) ; xcent] ;
ypos = [yEmit(iG) ; ycent] ;
set(hRays(iG),'XData',xpos,'YData',ypos) ;
if (ycent<yO)
if (FirstCross)
FirstCross = false ;
patch(xG+xEmit(iG),yG+yEmit(iG),'k')
end
if (xEmit(iG) < xO-yEmit(iG)/beta)
if (xEmit(iG) < xMin)
xMin = xEmit(iG) ;
end
else
if (xEmit(iG) > xMax)
xMax = xEmit(iG) ;
end
end
cF = (xMax-xMin)/(xEnd-xStart) ;
col = [cF 0 1-cF] ;
if (xMin ~= xEnd)
set(hPhantom1,'xdata',xObj+xMin,'ydata',yObj+yEmit(iG)) ;
end
if (xMax ~= xStart)
set(hPhantom2,'xdata',xObj+xMax,'ydata',yObj+yEmit(iG)) ;
end
if (cF>0 && cF<1)
col(2) = min(col(1), col(3)) ;
col = col/max(col) ;
set(hPhantom1,'facecolor',col) ;
set(hPhantom2,'facecolor',col) ;
end
else
nAbove = nAbove + 1 ;
end
end
drawnow ;
if (mod(iStep,nMovie) == 0)
F = getframe(gca);
iFrame = iFrame+1 ;
M(iFrame) = F ;
end
if (xMax > xEnd+xMarg)
break ;
end
if (iStep > xEnd && nAbove < 1)
break ;
end
end
return ;
|