Created
January 20, 2021 19:15
-
-
Save bencbartlett/744c581d4022a2a72459fa213e3c66b1 to your computer and use it in GitHub Desktop.
Code to make the animation for https://twitter.com/bencbartlett/status/1351967463609491458
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| SetDirectory[NotebookDirectory[]]; | |
| \[Theta]0 = -.1 \[Pi]; \[Phi]0 = .35*\[Pi]; | |
| \[Psi]0 = {Cos[\[Theta]0] Cos[\[Phi]0], Sin[\[Theta]0] Cos[\[Phi]0], | |
| Sin[\[Phi]0]}; | |
| Clear[BlochSphereVector]; | |
| BlochSphereVector[\[Psi]_, imSize_ : 1000, color_ : Gray, | |
| opacity_ : 1, \[Phi]view_ : \[Pi]/4, viewdist_ : 100] := Module[{ | |
| tubeball, pointline, | |
| blochSphereEmpty, | |
| lineLen = 1, | |
| mag = 4 | |
| }, | |
| tubeball[pt_, r_] := | |
| Sequence[Sphere[pt, 3 r],(*Opacity[.5],*)Tube[{{0, 0, 0}, pt}, r]]; | |
| pointline[pt_, r_] := | |
| Sequence[Point[pt],(*Opacity[.5],*)Line[{{0, 0, 0}, pt}]]; | |
| Show[ | |
| Graphics3D[{Blue, [email protected], | |
| Specularity[Blue, 10], | |
| Sphere[{0, 0, 0}, 1], | |
| Lighting -> "Neutral", | |
| [email protected], Arrowheads[.03], | |
| Opacity[.2], Gray, | |
| Line[lineLen*{{0, 0, 0}, {0, 0, 1}}], | |
| Line[lineLen*{{0, 0, 0}, {1, 0, 0}}], | |
| Line[lineLen*{{0, 0, 0}, {0, 1, 0}}], | |
| Opacity[.03], Gray, EdgeForm[{Transparent}], | |
| Polygon[ | |
| Table[{Cos[\[Theta]\[Prime]], Sin[\[Theta]\[Prime]], | |
| 0}, {\[Theta]\[Prime], 0, 2 \[Pi], .01}]] | |
| }, | |
| Boxed -> False, PlotRange -> ConstantArray[1*{-1, 1}, 3]], | |
| Graphics3D[{Opacity[1], GrayLevel[.9], [email protected], | |
| Point[{1, 0, 0}], | |
| Point[{0, 1, 0}], | |
| Point[{0, 0, 1}] | |
| }], | |
| Graphics3D[{ | |
| Lighting -> "Neutral", | |
| Thickness[0.005], | |
| Arrowheads[0.025], | |
| PointSize[0.02], | |
| Opacity[opacity], color, tubeball[\[Psi], 0.01], | |
| PointSize[0.02], | |
| Opacity@1, Black, Sphere[{0, 0, 0}, 0.025] | |
| }], | |
| ImageSize -> imSize, | |
| ImagePadding -> 0, | |
| ViewVertical -> {0, 0, 1}, | |
| ViewPoint -> | |
| viewdist*{1 Cos[\[Phi]view], 1 Cos[\[Phi]view], 1 Sin[\[Phi]view]} | |
| ] | |
| ]; | |
| BlochSphereVectorOnly[\[Psi]_, imSize_ : 1000, color_ : Gray, | |
| opacity_ : 1] := Module[{tubeball}, | |
| tubeball[pt_, r_] := | |
| Sequence[Sphere[pt, 3 r],(*Opacity[.5],*)Tube[{{0, 0, 0}, pt}, r]]; | |
| Graphics3D[{Opacity[opacity], color, tubeball[\[Psi], 0.01]}] | |
| ]; | |
| BlochSphereVectorFromAngles[\[Theta]_, \[Phi]_, imSize_ : 1000, | |
| color_ : Gray, \[Phi]view_ : \[Pi]/4, viewdist_ : 100] := | |
| BlochSphereVector[{Cos[\[Theta]] Cos[\[Phi]], | |
| Sin[\[Theta]] Cos[\[Phi]], Sin[\[Phi]]}, imSize, | |
| color, \[Phi]view, viewdist]; | |
| Clear[BlochSphereRotation]; | |
| BlochSphereRotation[\[Psi]0_, \[Theta]_, ax_, tmax_ : 1, | |
| imSize_ : 1000, color_ : Gray, opacityScale_ : 1, | |
| tubeOpacity_ : 1] := Module[{ | |
| \[Psi]1, | |
| arc, arcpts, | |
| thickness = 0.006}, | |
| If[tmax == 0, Return[BlochSphereVector[\[Psi]0, imSize]]]; | |
| \[Psi]1 = RotationMatrix[tmax*\[Theta], ax] . \[Psi]0; | |
| arc = ParametricPlot3D[ | |
| RotationMatrix[t \[Theta], ax] . \[Psi]0, {t, 0, tmax}, | |
| PlotStyle -> Directive[Gray, Thickness[thickness]], | |
| ColorFunction -> (Opacity[opacityScale*(#4 + .1), color] &)]; | |
| arcpts = | |
| Table[RotationMatrix[t \[Theta], ax] . \[Psi]0, {t, 0, tmax, | |
| 0.01}]; | |
| Show[ | |
| BlochSphereVector[\[Psi]1, imSize, Gray, tubeOpacity], | |
| arc, | |
| Graphics3D[{ | |
| Opacity[0.1*opacityScale], color, | |
| Thickness[0.003], | |
| Arrowheads[0.02], | |
| EdgeForm[{Transparent, Thickness[0.001], Dotted, color}], | |
| Polygon[Join[ | |
| arcpts, {Normalize[ax]*Dot[Last[arcpts], Normalize[ax]]}]] | |
| }] | |
| ] | |
| ]; | |
| BlochSphereRotationSequence[\[Psi]0_, \[Theta]List_, axList_, | |
| animTime_ : 1, imSize_ : 1000, colorList\[Prime]_ : Null, | |
| opacityList\[Prime]_ : Null] := Module[{ | |
| \[Psi] = \[Psi]0, | |
| i = 0, | |
| colorList = colorList\[Prime], | |
| opacityList = opacityList\[Prime], | |
| \[Theta], ax, tmax, opacity, color, | |
| displayList = {}, | |
| arc, arcpts, | |
| thickness = 0.006}, | |
| If[colorList == Null, | |
| colorList = ConstantArray[Gray, Length[\[Theta]List]]]; | |
| If[opacityList == Null, | |
| opacityList = ConstantArray[0.1, Length[\[Theta]List]]]; | |
| If[animTime == 0, Return[BlochSphereVector[\[Psi]0, imSize]]]; | |
| While[i < Length[\[Theta]List]*animTime , | |
| \[Theta] = \[Theta]List[[i + 1]]; (*1-indexed*) | |
| ax = axList[[i + 1]]; | |
| color = colorList[[i + 1]]; | |
| opacity = opacityList[[i + 1]]; | |
| tmax = Clip[Length[\[Theta]List]*animTime - i, {0, 1}]; | |
| arc = | |
| ParametricPlot3D[ | |
| RotationMatrix[t \[Theta], ax] . \[Psi], {t, 0, tmax}, | |
| PlotStyle -> Directive[Gray, Thickness[thickness]], | |
| ColorFunction -> (Opacity[#4 + .1, color] &)]; | |
| arcpts = | |
| Table[RotationMatrix[t \[Theta], ax] . \[Psi], {t, 0, tmax, | |
| 0.01}]; | |
| \[Psi] = RotationMatrix[tmax*\[Theta], ax] . \[Psi]; | |
| AppendTo[displayList, arc]; | |
| AppendTo[displayList, | |
| Graphics3D[{ | |
| Opacity[opacity], color, | |
| Thickness[0.003], | |
| Arrowheads[0.02], | |
| EdgeForm[{Transparent, Thickness[0.001], Dotted, color}], | |
| Polygon[ | |
| Join[arcpts, {Normalize[ax]*Dot[Last[arcpts], Normalize[ax]]}]] | |
| }] | |
| ]; | |
| ++i; | |
| ]; | |
| Show[BlochSphereVector[\[Psi], imSize], displayList] | |
| ]; | |
| baseSwitchClosed = | |
| Import["/Users/ben/Dropbox/Research/qpgav2/animation/switches_\ | |
| closed_2.png"]; | |
| baseSwitchOpen = | |
| Import["/Users/ben/Dropbox/Research/qpgav2/animation/switches_open_\ | |
| 2.png"]; | |
| base = baseSwitchClosed; | |
| (*these coordinates were chosen by clicking points on the images to \ | |
| trace the photon path*) | |
| coordsRingToBeamsplitterTop = \ | |
| {{3213.8305999348113`, 1059.3037483813007`}, {3166.0119817800314`, | |
| 1106.6882343267484`}, {3125.583593903153`, | |
| 1147.1165061254958`}, {3086.4594599043658`, | |
| 1186.67535272427`}, {3043.4227964275683`, | |
| 1229.27718752295`}, {2987.779583629292`, | |
| 1271.009597121657`}, {2905.619018309969`, | |
| 1274.9220105215356`}, {2810.8516715129053`, | |
| 1275.7914357215086`}, {2726.5174271155183`, | |
| 1276.6608609214818`}, {2650.008009517889`, | |
| 1275.7914357215086`}, {2563.934914720556`, | |
| 1275.7914357215086`}, {2471.3400862202475`, | |
| 1288.398101121118`}, {2384.3975662229414`, | |
| 1321.870971320081`}, {2303.1298738860205`, | |
| 1367.5585691098804`}, {2225.3164345665623`, | |
| 1424.505919708116`}, {2153.588739490654`, | |
| 1485.36568370623`}, {2088.3818494926745`, | |
| 1550.137861104223`}, {2029.260935894506`, | |
| 1610.5629125023506`}, {1969.2705970963648`, | |
| 1681.8557789001418`}, {1903.4672057829514`, | |
| 1751.2574705894`}, {1783.5966424593155`, | |
| 1804.267902358066`}}; coordsRingToBeamsplitterBottom = \ | |
| {{3213.8027411834105`, 1058.23640996825`}, {3182.50343398438`, | |
| 1028.2412405691794`}, {3149.8998729072596`, | |
| 998.2460711701087`}, {3115.5574614301927`, | |
| 963.4690631711865`}, {3079.911260387559`, | |
| 928.2573425722774`}, {3040.78689423251`, | |
| 888.2637833735166`}, {2990.360232634072`, | |
| 847.8355115747693`}, {2923.414724392408`, | |
| 845.2272359748501`}, {2853.8607083945635`, | |
| 844.7925233748635`}, {2786.4801393185203`, | |
| 844.7925233748635`}, {2716.9261233206753`, | |
| 843.9230981748906`}, {2651.7190011664343`, | |
| 845.2272359748501`}, {2583.903835568535`, | |
| 844.7925233748635`}, {2514.3498195706907`, | |
| 842.1842477749444`}, {2434.7975298512865`, | |
| 828.2734445753754`}, {2355.6796044974762`, | |
| 806.537814576049`}, {2280.909037299793`, | |
| 774.3690821770456`}, {2214.397893423723`, | |
| 734.8102355782714`}, {2152.668704225636`, | |
| 689.1654125796856`}, {2102.2420426271983`, | |
| 640.9123139811809`}, {2060.944229550347`, | |
| 591.789790182703`}, {2013.9952687518016`, | |
| 538.7547369062154`}, {1951.3966543537413`, | |
| 490.50163830771044`}, {1901.8394179552768`, | |
| 433.11957510948855`}, {1850.1085024787487`, | |
| 372.6945237113607`}, {1784.032303358927`, 309.66119671331376`}}; | |
| coordsBeamsplitterToMirrorTop = {{4397.265782207965`, | |
| 1275.59}, {4341.867493152422`, 1275.59}, {4277.8731729089595`, | |
| 1275.59}, {4212.9234547059095`, 1275.59}, {4147.9737365028595`, | |
| 1275.59}, {4089.2323197232695`, 1275.59}, {4027.148030264472`, | |
| 1275.59}, {3963.63089891113`, 1275.59}, {3892.472879284618`, | |
| 1274.770400099958`}, {3819.4043187837683`, | |
| 1275.59}, {3746.8129471730385`, 1275.59}, {3683.295815819696`, | |
| 1275.59}, {3611.182653278434`, 1275.59}, {3531.428092374329`, | |
| 1275.7255430147088`}, {3443.55417908275`, | |
| 1272.382542813081`}, {3382.425032538703`, | |
| 1228.92290257983`}, {3326.0716005684094`, | |
| 1172.0918991521612`}, {3269.718168598116`, | |
| 1113.8281813523663`}, {3214.3198795425733`, 1058.907463754199`}}; | |
| coordsBeamsplitterToAtomBottom = {{4222.067322203811`, | |
| 842.69}, {4206.785035567799`, 842.69}, {4193.89098878592`, | |
| 842.69}, {4173.355288596361`, 842.69}, {4155.68527219589`, | |
| 842.69}, {4134.672128071375`, 842.69}, {4115.091315751729`, | |
| 842.69}, {4091.606022021691`, | |
| 846.1683803338327`}, {4068.6825920676724`, | |
| 842.69}, {4047.6694479431567`, 842.69}, {4006.5983026088747`, | |
| 842.69}, {3955.498284192129`, 842.69}, {3892.4588518185806`, | |
| 842.69}, {3827.5091336155306`, 842.69}, {3767.812573921191`, | |
| 842.69}, {3701.90771280339`, 842.69}, {3639.3459794096357`, | |
| 842.69}, {3575.828848056293`, 842.69}, {3511.8342727679938`, | |
| 842.69}, {3437.810059262719`, | |
| 848.5562376207095`}, {3385.7548979312223`, | |
| 887.2395256681143`}, {3348.5043242559436`, | |
| 925.9228137155192`}, {3303.134908282865`, | |
| 969.859387794053`}, {3259.1983342043313`, | |
| 1014.7511047873376`}, {3214.784316190841`, 1059.1652503232467`}}; | |
| ringXY = {1125, 1060}; (* approx center of ring in pixels *) | |
| ringRadius = 995; | |
| (*Manipulate[Show[base,Graphics[{Magenta,Circle[{x,y}, r]}],ImageSize\ | |
| \[Rule]1500],{x,1100,1200},{y,1000,1200},{r,950,1100}]*) | |
| \ | |
| (*Show[base,Graphics[{Magenta,Circle[ringXY, ringRadius]}],ImageSize\ | |
| \[Rule]1500]*) | |
| coordsRing = | |
| Table[ringXY - ringRadius*{Cos[2 \[Pi] t], Sin[2 \[Pi] t]}, {t, 0, | |
| 1, 0.01}]; | |
| (*pathRingCCW[t_]:= ringXY-ringRadius*{Cos[2\[Pi] t], Sin[2\[Pi] t]}; | |
| pathRingCW[t_] := ringXY-ringRadius*{Cos[-2\[Pi] t], Sin[-2\[Pi] \ | |
| t]}; | |
| (*Manipulate[Show[base,Graphics[{PointSize[0.05],Red,Point[pathRingCW[\ | |
| t]], Blue,Point[ pathRingCCW[t]]}],ImageSize\[Rule]1500],{t,0,1}]*)*) | |
| ymax = 1.2* | |
| ImageAspectRatio[ | |
| base]; (*stretch the image vertically a little to make it look \ | |
| less distorted when viewed from an angle*) | |
| p = {{0, 0}, {1, 0}, {1, ymax}, {0, ymax}}; | |
| plane = Graphics3D[{ | |
| EdgeForm[Opacity[0.2]], | |
| Texture[base], | |
| Polygon[(Join[#1, {0.002}] &) /@ p, | |
| VertexTextureCoordinates -> {{0, 0}, {1, 0}, {1, 1}, {0, 1}}] | |
| }]; | |
| (*Show[ | |
| plane, | |
| PlotRange\[Rule]{{0,1},{0,ymax},{-.1,.1}}, | |
| ViewPoint\[Rule] 1*{0,-1.5,2}, ViewVertical\[Rule]{0,0,1}, | |
| ImageSize\[Rule]1500,ImagePadding\[Rule]5,Boxed\[Rule]False,Lighting\ | |
| \[Rule]"Neutral"]*) | |
| coordsRingNormalized = | |
| Map[((#/ ImageDimensions[base])*{1, ymax}) &, coordsRing]; | |
| coordsRingToBeamsplitterTopNormalized = | |
| Map[((#/ ImageDimensions[base])*{1, ymax}) &, | |
| coordsRingToBeamsplitterTop]; | |
| coordsRingToBeamsplitterBottomNormalized = | |
| Map[((#/ ImageDimensions[base])*{1, ymax}) &, | |
| coordsRingToBeamsplitterBottom]; | |
| coordsBeamsplitterToMirrorTopNormalized = | |
| Map[((#/ ImageDimensions[base])*{1, ymax}) &, | |
| coordsBeamsplitterToMirrorTop]; | |
| coordsBeamsplitterToAtomBottomNormalized = | |
| Map[((#/ ImageDimensions[base])*{1, ymax}) &, | |
| coordsBeamsplitterToAtomBottom]; | |
| tspecTop1 = | |
| Rescale[Prepend[ | |
| Accumulate[ | |
| Map[Norm, Differences[coordsRingToBeamsplitterTopNormalized]]], | |
| 0]]; | |
| tspecTop2 = | |
| Rescale[Prepend[ | |
| Accumulate[ | |
| Map[Norm, Differences[coordsBeamsplitterToMirrorTopNormalized]]], | |
| 0]]; | |
| tspecBot1 = | |
| Rescale[Prepend[ | |
| Accumulate[ | |
| Map[Norm, | |
| Differences[coordsRingToBeamsplitterBottomNormalized]]], 0]]; | |
| (*no tspecBot2 because we want photon to seem like it's moving slower \ | |
| in chamber*) | |
| zValueForPath = 0.0; | |
| pathRingCCW = | |
| Interpolation[ | |
| TimeSeries[ | |
| Join[#1, {zValueForPath}] & /@ coordsRingNormalized, {0, 1}]]; | |
| pathRingCW = | |
| Interpolation[ | |
| TimeSeries[ | |
| Reverse[Join[#1, {zValueForPath}] & /@ coordsRingNormalized], {0, | |
| 1}]]; | |
| pathTop1 = | |
| Interpolation[ | |
| TimeSeries[ | |
| Reverse[Join[#1, {zValueForPath}] & /@ | |
| coordsRingToBeamsplitterTopNormalized], {tspecTop1}]]; | |
| pathTop2 = | |
| Interpolation[ | |
| TimeSeries[ | |
| Reverse[Join[#1, {zValueForPath}] & /@ | |
| coordsBeamsplitterToMirrorTopNormalized], {tspecTop2}]]; | |
| pathBot1 = | |
| Interpolation[ | |
| TimeSeries[ | |
| Reverse[Join[#1, {zValueForPath}] & /@ | |
| coordsRingToBeamsplitterBottomNormalized], {tspecBot1}]]; | |
| pathBot2 = | |
| Interpolation[ | |
| TimeSeries[ | |
| Reverse[Join[#1, {zValueForPath}] & /@ | |
| coordsBeamsplitterToAtomBottomNormalized], {0, 1}]]; | |
| (*define functions to show the pulses*) | |
| dt = 0.001;(*0.0005;*) | |
| rfunc = | |
| Function[{x, y, z}, Abs[z] > 0.001]; | |
| opac = 0.3; | |
| A0 = 0.05; | |
| vg = 1.3; | |
| \[Omega] = 70; | |
| \[Delta]\[Omega] = 250; | |
| Clear[pulse, ringPulse, reflectedPulse]; | |
| pulse[path_, A_, \[Tau]_, color_, op_ : opac] := ListPointPlot3D[ | |
| Table[path[t] + {0, 0, | |
| A*A0 Cos[\[Omega] (\[Tau]/vg - | |
| t)] Exp[-\[Delta]\[Omega] (\[Tau] - t)^2]}, {t, 0, 1, | |
| dt}], | |
| PlotStyle -> {color, PointSize[Small]}, Filling -> 0, | |
| FillingStyle -> {color, Opacity[op]}, RegionFunction -> rfunc, | |
| RegionBoundaryStyle -> None]; | |
| ringPulse[path_, A_, \[Tau]_, color_, pointOp_ : 1, op_ : opac, | |
| numRotations_ : 1] := ListPointPlot3D[ | |
| Table[path[Mod[t/4, 1]] + {0, 0, | |
| A*A0 Cos[\[Omega] (\[Tau]/vg - | |
| t)] Exp[-\[Delta]\[Omega] ((\[Tau] - t)^2)]}, {t, 0, | |
| 4*numRotations, dt}], | |
| PlotStyle -> {color, Opacity[pointOp], PointSize[Small]}, | |
| Filling -> 0, FillingStyle -> {color, Opacity[op]}, | |
| RegionFunction -> rfunc, RegionBoundaryStyle -> None]; | |
| reflectedPulse[path_, A_, \[Tau]_, color_, \[Phi]_ : -1] := | |
| ListPointPlot3D[ | |
| Table[path[t] + {0, 0, | |
| A*A0 Cos[\[Omega] (\[Tau]/vg - | |
| t)] Exp[-\[Delta]\[Omega] (\[Tau] - t)^2] + \[Phi]*A* | |
| A0 Cos[\[Omega] ((\[Tau] - 1)/ | |
| vg + (t - 1))] Exp[-\[Delta]\[Omega] ((\[Tau] - | |
| 1) + (t - 1))^2] | |
| }, {t, 0, 1, dt}], | |
| PlotStyle -> {color, PointSize[Small]}, Filling -> 0, | |
| FillingStyle -> {color, Opacity[opac]}, RegionFunction -> rfunc, | |
| RegionBoundaryStyle -> None]; | |
| BS = 1/Sqrt[2] ({ | |
| {1, I}, | |
| {I, 1} | |
| }); | |
| \[Phi]ringDelay = 1.465(*1.462*); | |
| createPulses[\[Alpha]_, \[Beta]_, t_] := | |
| Module[{A, B, \[Alpha]\[Prime], \[Beta]\[Prime]}, | |
| {A, B} = Abs[BS . {\[Alpha], \[Beta]}]; | |
| {\[Alpha]\[Prime], \[Beta]\[Prime]} = Abs[BS . {A, -B}]; | |
| Show[ | |
| pulse[pathTop1, \[Alpha], t, Red], | |
| pulse[pathBot1, \[Beta], t, Blue], | |
| reflectedPulse[pathTop2, A, t - 1, Purple, 1], | |
| reflectedPulse[pathBot2, B, t - 1, Magenta, -1], | |
| pulse[pathTop1, \[Alpha], 3 - (t - 1), Blue], | |
| pulse[pathBot1, \[Beta], 3 - (t - 1), Red] | |
| ] | |
| ]; | |
| createRingPulses[\[Alpha]_, \[Beta]_, t_] := | |
| Module[{CWpath, CCWpath}, | |
| CWpath[\[Tau]_] := pathRingCW[Mod[\[Tau] + \[Phi]ringDelay/4, 1]]; | |
| CCWpath[\[Tau]_] := pathRingCCW[Mod[\[Tau] + \[Phi]ringDelay/4, 1]]; | |
| Show[ | |
| ringPulse[CWpath, \[Alpha], t, Red], | |
| ringPulse[CCWpath, \[Beta], t, Blue] | |
| ] | |
| ]; | |
| createRingPulsesReturn[\[Alpha]_, \[Beta]_, t_] := | |
| Module[{CWpath, CCWpath}, | |
| CWpath[\[Tau]_] := pathRingCW[Mod[\[Tau] - \[Phi]ringDelay/4, 1]]; | |
| CCWpath[\[Tau]_] := pathRingCCW[Mod[\[Tau] - \[Phi]ringDelay/4, 1]]; | |
| Show[ | |
| ringPulse[CWpath, \[Alpha], t, Red, 1, opac, 2], | |
| ringPulse[CCWpath, \[Beta], t, Blue, 1, opac, 2] | |
| ] | |
| ]; | |
| createOtherRingPulses[t_, nPulses_ : 4 - 1] := | |
| Module[{t\[Prime] = t + \[Phi]ringDelay, pointOp = .1, op = .07}, | |
| Show[ | |
| ringPulse[pathRingCW, 1, Mod[t\[Prime] - 1*4/6, 4], Red, pointOp, | |
| op], | |
| ringPulse[pathRingCW, 1, Mod[t\[Prime] - 2*4/6, 4], Red, pointOp, | |
| op], | |
| ringPulse[pathRingCW, 1, Mod[t\[Prime] - 3*4/6, 4], Red, pointOp, | |
| op], | |
| ringPulse[pathRingCW, 1, Mod[t\[Prime] - 4*4/6, 4], Red, pointOp, | |
| op], | |
| ringPulse[pathRingCW, 1, Mod[t\[Prime] - 5*4/6, 4], Red, pointOp, | |
| op], | |
| ringPulse[pathRingCCW, 1, Mod[t\[Prime] - 1*4/6, 4], Blue, pointOp, | |
| op], | |
| ringPulse[pathRingCCW, 1, Mod[t\[Prime] - 2*4/6, 4], Blue, pointOp, | |
| op], | |
| ringPulse[pathRingCCW, 1, Mod[t\[Prime] - 3*4/6, 4], Blue, pointOp, | |
| op], | |
| ringPulse[pathRingCCW, 1, Mod[t\[Prime] - 4*4/6, 4], Blue, pointOp, | |
| op], | |
| ringPulse[pathRingCCW, 1, Mod[t\[Prime] - 5*4/6, 4], Blue, pointOp, | |
| op] | |
| ] | |
| ] | |
| ringSpeed = 1 + 2*(1/2 - \[Phi]ringDelay/4); | |
| (*"retroactive" Bloch sphere rotation to show teleportation action*) | |
| customBlochSphereRotationSequence[\[Psi]0_, \[Theta]List_, axList_, | |
| animTime_ : 1, imSize_ : 1000, colorList\[Prime]_ : Null, | |
| opacityList\[Prime]_ : Null, auxTime_ : 1] := Module[{ | |
| \[Psi] = \[Psi]0, | |
| i = 0, | |
| colorList = colorList\[Prime], | |
| opacityList = opacityList\[Prime], | |
| \[Theta], ax, tmax, opacity, color, | |
| displayList = {}, | |
| arc, arcpts, | |
| thickness = 0.006, | |
| aux\[Theta] = 0.7 \[Pi], auxAx = {0, 1, 0}, auxInsertionPos = 1, | |
| auxColor = Magenta, auxOp = 0.1 | |
| }, | |
| If[colorList == Null, | |
| colorList = ConstantArray[Gray, Length[\[Theta]List]]]; | |
| If[opacityList == Null, | |
| opacityList = ConstantArray[0.1, Length[\[Theta]List]]]; | |
| If[animTime == 0.0, Return[BlochSphereVector[\[Psi]0, imSize]]]; | |
| While[i < Length[\[Theta]List]*animTime , | |
| (*retroactively insert a rotation here*) | |
| If[i == auxInsertionPos && auxTime > 0.0, | |
| arc = | |
| ParametricPlot3D[ | |
| RotationMatrix[t aux\[Theta], auxAx] . \[Psi], {t, 0, | |
| auxTime}, | |
| PlotStyle -> Directive[auxColor, Thickness[thickness]], | |
| ColorFunction -> (Opacity[#4 + .1, auxColor] &)]; | |
| arcpts = | |
| Table[ | |
| RotationMatrix[t aux\[Theta], auxAx] . \[Psi], {t, 0, auxTime, | |
| 0.01}]; | |
| \[Psi] = RotationMatrix[auxTime*aux\[Theta], auxAx] . \[Psi]; | |
| AppendTo[displayList, arc]; | |
| AppendTo[displayList, | |
| Graphics3D[{ | |
| Opacity[auxOp], auxColor, | |
| Thickness[0.003], | |
| Arrowheads[0.02], | |
| EdgeForm[{Transparent, Thickness[0.001], Dotted, auxColor}], | |
| Polygon[Join[ | |
| arcpts, {Normalize[auxAx]* | |
| Dot[Last[arcpts], Normalize[auxAx]]}]] | |
| }] | |
| ]; | |
| ]; | |
| \[Theta] = \[Theta]List[[i + 1]]; (*1-indexed*) | |
| ax = axList[[i + 1]]; | |
| color = colorList[[i + 1]]; | |
| opacity = opacityList[[i + 1]]; | |
| tmax = Clip[Length[\[Theta]List]*animTime - i, {0, 1}]; | |
| arc = | |
| ParametricPlot3D[ | |
| RotationMatrix[t \[Theta], ax] . \[Psi], {t, 0, tmax}, | |
| PlotStyle -> Directive[Gray, Thickness[thickness]], | |
| ColorFunction -> (Opacity[#4 + .1, color] &)]; | |
| arcpts = | |
| Table[RotationMatrix[t \[Theta], ax] . \[Psi], {t, 0, tmax, | |
| 0.01}]; | |
| \[Psi] = RotationMatrix[tmax*\[Theta], ax] . \[Psi]; | |
| AppendTo[displayList, arc]; | |
| AppendTo[displayList, | |
| Graphics3D[{ | |
| Opacity[opacity], color, | |
| Thickness[0.003], | |
| Arrowheads[0.02], | |
| EdgeForm[{Transparent, Thickness[0.001], Dotted, color}], | |
| Polygon[Join[ | |
| arcpts, {Normalize[ax]*Dot[Last[arcpts], Normalize[ax]]}]] | |
| }] | |
| ]; | |
| ++i; | |
| ]; | |
| Show[BlochSphereVector[\[Psi], imSize], displayList] | |
| ]; | |
| (* | |
| Timings: | |
| t~0-0.1:red photon enters scattering unit | |
| t~0.1-0.2:blue photon enters scattering unit | |
| t~0.4-0.6 photon passes phase shifter | |
| t=1:photon passes beamsplitter | |
| t=2:photon hits atom/mirror | |
| t=3:photon passes beamsplitter (return) | |
| t~3.4:photon passes phase shifter | |
| t=4:photon re-injected into ring | |
| t=4-4.75:atom state rotated | |
| t=5.25-5.75:atom measured,teleportation animation shown | |
| *) | |
| \[Theta]0atom = \[Pi]/2; \[Phi]0atom = 0; | |
| \[Psi]0atom = {Cos[\[Theta]0atom] Cos[\[Phi]0atom], | |
| Sin[\[Theta]0atom] Cos[\[Phi]0atom], Sin[\[Phi]0atom]}; | |
| \[Psi]1atom = {0, 0, -1}; | |
| scaleTime01[t_, min_, | |
| max_] := (Clip[t, {min, max}] - min)/(max - | |
| min); (*scales a time range between min and max to run from 0 to \ | |
| 1*) | |
| laserImg = | |
| Import["/Users/ben/Dropbox/Research/qpgav2/animation/laser_pulse.\ | |
| png"]; | |
| baseSwitchClosedLaserOn = | |
| Import["/Users/ben/Dropbox/Research/qpgav2/animation/switches_\ | |
| closed_laser_on.png"]; | |
| baseSwitchClosedMeterOn = | |
| Import["/Users/ben/Dropbox/Research/qpgav2/animation/switches_\ | |
| closed_meter_on_laser_on_labeled.png"]; | |
| laserPlane = Graphics3D[{ | |
| EdgeForm[Opacity[0.0]], Texture[laserImg], | |
| Polygon[(Join[#1, {0.003}] &) /@ p, | |
| VertexTextureCoordinates -> {{0, 0}, {1, 0}, {1, 1}, {0, 1}}] | |
| }]; | |
| Clear[showBase]; | |
| showBase[t_, imSize_ : 1500, debug_ : False] := | |
| Module[{texture, blochPhoton, blochAtom, tAtomRotate, tPhotonZ, | |
| tMeas, ballSize, imScale, meterAngle, meterPivot, meterEnd, meter}, | |
| ballSize = imSize/5; | |
| imScale = imSize/1500; | |
| (* set up progress of different events of animation *) | |
| tPhotonZ = 0; | |
| tPhotonZ += 1/2*scaleTime01[t, 0.4, 0.6]; | |
| tPhotonZ += 1/2*2/3*scaleTime01[t, 1.9, 2.1]; | |
| tPhotonZ += 1/2*1/3*scaleTime01[t, 3.4, 3.6]; | |
| tAtomRotate = scaleTime01[t, 4, 4.75]; | |
| tMeas = scaleTime01[t, 5.25, 5.65]; | |
| If[debug, | |
| Print[tPhotonZ]; | |
| Print[tAtomRotate]; | |
| Print[tMeas]; | |
| ]; | |
| meterAngle = 80 Degree *(Sin[\[Pi] tMeas] - .5); | |
| meterPivot = {0.9235, ymax*.5, 0}; | |
| meterEnd = | |
| meterPivot + | |
| RotationMatrix[meterAngle, {0, 0, -1}] . {0, .03, 0}; | |
| meter = Line[{meterPivot, meterEnd}]; | |
| blochPhoton = | |
| customBlochSphereRotationSequence[\[Psi]0, {\[Pi]/ | |
| 4, \[Pi]/2 + \[Pi]/4}, {{0, 0, 1}, {0, 0, 1}}, tPhotonZ, | |
| ballSize, {Gray, Gray}, Null, tMeas]; | |
| blochAtom = Show[ | |
| BlochSphereRotation[\[Psi]0atom, 0.7 \[Pi], {1, 0, 0}, | |
| tAtomRotate, ballSize, Magenta, 1 - tMeas, 1 - tMeas], | |
| BlochSphereVectorOnly[\[Psi]1atom, ballSize, Magenta, tMeas] | |
| ]; | |
| texture = If[0 <= t <= 0.2 || 3.8 <= t <= 4.0, baseSwitchOpen, | |
| If[0 < tAtomRotate < 1, baseSwitchClosedLaserOn, | |
| If[0 < tMeas < 1, baseSwitchClosedMeterOn, | |
| baseSwitchClosed] | |
| ] | |
| ]; | |
| Show[ | |
| Graphics3D[{ | |
| Inset[blochPhoton, {.58, 1.07*ymax, -.12}], | |
| Inset[blochAtom, {.88, 1.07*ymax, -.12}], | |
| EdgeForm[Opacity[0.0]], | |
| Texture[texture], | |
| Polygon[(Join[#1, {0.002}] &) /@ p, | |
| VertexTextureCoordinates -> {{0, 0}, {1, 0}, {1, 1}, {0, 1}}], | |
| Text[ | |
| Style["|photon\[RightAngleBracket]", 25*imScale, | |
| Gray], {0.58 - .12, 1.07*ymax + .02, -.00}], | |
| Text[ | |
| Style["|atom\[RightAngleBracket]", 25*imScale, | |
| Gray], {0.88 - .12, 1.07*ymax + .02, -.00}], | |
| If[tAtomRotate > 0, Text[Style["Subscript[R, x](\[Theta])", 18*imScale, Magenta, | |
| Opacity[tAtomRotate - tMeas]], {0.89, .90*ymax, -.00}]], | |
| If[tMeas > 0, Text[Style["Subscript[R, y](-\[Theta])", 18*imScale, Magenta, Opacity[tMeas]], {0.55, .86*ymax, -.00}]], | |
| Thick, Black, meter, | |
| If[debug, | |
| Text[Style["t=" <> ToString[N[t, 3]], 25*imScale, Gray], {0.1, | |
| 1.07*ymax + .02, -.00}]] | |
| }], | |
| PlotRange -> {{0, 1}, {0, ymax}, {-.1, .1}}, | |
| ViewPoint -> 1*{0, -1.5, 2}, ViewVertical -> {0, 0, 1}, | |
| ImageSize -> imSize, ImagePadding -> 5, Boxed -> False, | |
| Lighting -> "Neutral"] | |
| ]; | |
| Clear[renderFrame]; | |
| renderFrame[t_, imSize_ : 1000, debug_ : False] := Quiet@Show[ | |
| showBase[t, imSize, debug], | |
| createRingPulses[1, 1 , ringSpeed (t) + 4], | |
| createRingPulsesReturn[-1, -1, ringSpeed (t - 4)], | |
| createOtherRingPulses[t ringSpeed], | |
| createPulses[-1, -1, t], | |
| PlotRange -> {{0, 1}, {0, ymax}, {-.1, .1}}, | |
| ViewPoint -> 1*{0, -1.5, 2}, ViewVertical -> {0, 0, 1}, | |
| ImageSize -> imSize, ImagePadding -> 5, Boxed -> False, | |
| Lighting -> "Neutral"] | |
| saveFrame[t_] := Module[{frame, title}, | |
| frame = Quiet[renderFrame[t, 2000]]; | |
| title = IntegerString[Floor[10^4 * (t + 2)], 10, 6] <> ".png"; | |
| Export["frames/" <> title, frame]; | |
| Print["rendered frame: " <> title] | |
| ] | |
| start = -1; stop = 8.5; | |
| simTimescale = (stop - start); | |
| animationTime = 15; | |
| framesPerSec = 60; | |
| frameStep = simTimescale /(animationTime*framesPerSec); | |
| ParallelDo[saveFrame[t], {t, start, stop, frameStep}] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment