Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I would like to display an electromagnetic (EM) wave. I have written code that works, but it does not "shade" the area between the graph and the axes. Both the Filling and EdgeForm commands are ignored.

strength = 2; frequency = 3;

wave1 = ParametricPlot3D[{t (x/6.28), -strength Sin[frequency t (x/6.28)], 0}, 
  {t, 0, 2 Pi}, 
  PlotStyle->Directive[Thickness[.007], Lighter[Red, .5], Filling -> Axis]];
wave2 = ParametricPlot3D[{t (x/6.28), 0, strength Sin[frequency t(x/6.28)]}, 
  {t, 0, 2 Pi}, 
  PlotStyle -> Directive[Thickness[.007], Lighter[Blue, .5], Filling -> Axis]];

Show[wave1, wave2, Graphics3D[EdgeForm[Pink], wave1],
  Graphics3D[EdgeForm[LightBlue], wave2], 
  Axes->False, Boxed->False, PlotRange->All, ImageSize->{500, 400}]

I would like to accomplish filling the portion between the two sinusoidal waves and the direction of propagation of the wave with color.

share|improve this question

5 Answers 5

up vote 12 down vote accepted

Here's a variation of the plane wave rendering done in rm -rf's answer. Here, I use arrows instead of lines to indicate the wave's displacement from the axis:

waveDiagram[xm_, col_, k_] := Flatten[First[
    Normal[Plot[Sin[x], {x, 0, xm}, Mesh -> Full, 
                PlotStyle -> Directive[col, Arrowheads[Small]]]] /. 
           Point[{x_, y_}] :> 
             If[Chop[Abs[y]] < 0.1, Point[{x, 0}], Arrow[{{x, 0}, {x, y}}]]]] /. 
          v_?VectorQ /; Length[v] == 2 :> Insert[v, 0, k]

Graphics3D[(* axes *)
           {{Gray, {Arrowheads[.02], 
            Arrow[{{0, 0, 0}, {9 π/2, 0, 0}}]}, {Arrowheads[.01 {-1, 1}], 
            Arrow[{{0, 1, 0}, {0, -1, 0}}], Arrow[{{0, 0, 1}, {0, 0, -1}}]}}, 
           waveDiagram[4 π, Darker[Blue], 2], 
           waveDiagram[4 π, Darker[Green], 3]},
           Boxed -> False, BoxRatios -> {2, 1, 1}]

plane wave diagram

As a variation, here's a depiction of the circular polarization of a plane wave:

Show[
     (* circularly polarized wave *)
     Normal[ParametricPlot3D[{t, -Sin[t], Cos[t]}, {t, 0, 4 π}, Mesh -> Full, 
            PlotStyle -> Directive[Darker[Blue], Arrowheads[Small]]]] /. 
     Point[{x_, y_, z_}] :> 
           If[Chop[Norm[{y, z}]] < 0.1, Point[{x, 0, 0}], 
              Arrow[{{x, 0, 0}, {x, y, z}}]],
     (* axes *)
     Graphics3D[{{Gray, {Arrowheads[.02], Arrow[{{0, 0, 0}, {9 π/2, 0, 0}}]},
                 {Arrowheads[.01 {-1, 1}], Arrow[{{0, 1, 0}, {0, -1, 0}}], 
                  Arrow[{{0, 0, 1}, {0, 0, -1}}]}}}],
                Axes -> None, Boxed -> False, BoxRatios -> {2, 1, 1}, PlotRange -> All]

circular polarization


The common theme in both diagrams is the use of the Mesh option of the plotting functions, which generates Point[]s on the curve(s) at preset locations. From here, we replace each Point[] object generated with an Arrow[] whose head has the coordinates of the original Point[]; how the position of the tail is determined depends on the plot being done.

share|improve this answer

If you use a full period for x you can get by with this cheap hack:

x = 2 Pi;

wave1 = ParametricPlot3D[{t (x/6.28), -strength Sin[
     frequency t (x/6.28)], 0}, {t, 0, 2 Pi}, 
  PlotStyle -> 
   Directive[Thickness[.007], Lighter[Red, .5], Filling -> Axis]];
wave2 = ParametricPlot3D[{t (x/6.28), 0, 
   strength Sin[frequency t (x/6.28)]}, {t, 0, 2 Pi}, 
  PlotStyle -> 
   Directive[Thickness[.007], Lighter[Blue, .5], Filling -> Axis]];

Adding /. Line -> Polygon

Show[wave1, wave2, Axes -> False, Boxed -> False, PlotRange -> All, 
  ImageSize -> {500, 400}] /. Line -> Polygon

Mathematica graphics


My take on the hatched shading version:

strength = 1; frequency = 3; x = 5;

pts1 =
 Table[
   {t (x/6.28), -strength Sin[frequency t (x/6.28)], 0},
   {t, 0, 2 Pi, 0.03}
 ];

pts2 = {#, 0, -#2} & @@@ pts1;

Graphics3D[{
  Thickness[0.007],
  {Lighter@Red, Line[pts1]},
  {Lighter@Blue, Line[pts2]},
  Thickness[0.002],
  Pink,
  Line[ {#, # {1, 0, 1}}& /@ pts1[[;; ;; 3]] ],
  RGBColor[0.7, 0.7, 1],
  Line[ {#, # {1, 1, 0}}& /@ pts2[[;; ;; 3]] ]
}]

Mathematica graphics


My take on arrows a la J. M.'s answer:

Table[{t/3, -Sin[t], Cos[t]}, {t, 0, 4 Pi, 0.05}] //
  Graphics3D[{
    {Orange, Lighting -> "Neutral", Tube@#},
    {RGBColor[0, .8, 1], Arrow@Tube[{{0, 0, 0}, 1.5 #}, 0.01] & /@
      {{3, 0, 0}, {0, 1, 0}, {0, -1, 0}, {0, 0, 1}, {0, 0, -1}}},
    Arrowheads[1/40, Appearance -> "Projected"],
    Opacity[0.3],
    Arrow[{# {1, 0, 0}, #}] & /@ #[[;; ;; 3]]
  }, Boxed -> False] &

Mathematica graphics

share|improve this answer

You could do something like

strength = 2; frequency = 3; x = 5;

wave1 = ParametricPlot3D[{t (x/6.28), -s strength Sin[
      frequency t (x/6.28)], 0}, {t, 0, 2 Pi}, {s, 0, 1}, 
   Mesh -> None, PlotStyle -> Lighter[Red, .5]];
wave2 = ParametricPlot3D[{t (x/6.28), 0, 
    s strength Sin[frequency t (x/6.28)]}, {t, 0, 2 Pi}, {s, 0, 1}, 
   Mesh -> None, PlotStyle -> Lighter[Blue, .5]];

Show[wave1, wave2, Axes -> False, Boxed -> False, PlotRange -> All, 
 ImageSize -> {500, 400}, Lighting -> "Neutral"]

Mathematica graphics

Note that you can also combine the two waves in one ParametricPlot3D:

waves = ParametricPlot3D[
  {{t (x/6.28), -s strength Sin[frequency t (x/6.28)], 0},
   {t (x/6.28), 0, s strength Sin[frequency t (x/6.28)]}},
  {t, 0, 2 Pi}, {s, 0, 1},
  Mesh -> None,
  PlotStyle -> {Lighter[Red, .5], Lighter[Blue, .5]},
  PlotPoints -> {50, 2},
  Boxed -> False, Axes -> False, PlotRange -> All, 
  Lighting -> "Neutral"
  ]
share|improve this answer

To get a cleaner output I would recommend taking control of the polygons in your plot more explicitly. If you rely on ParametricPlot3D, that control is harder to achieve.

Here is a function that plots an integer number of wavelengths with an arrow indicating the propagation direction, and blue face color for the electric field (red for magnetic field).

plotWave[λ_, nλ_, aspect_: 1/5] := 
  Module[{nStep = 40, amplitudes},
   amplitudes =
    Table[
     {aspect λ nλ Sin[2 Pi z/λ], 0, z},
     {z, 0, λ nλ, λ/nStep/2}
     ];
   Graphics3D[
    {
     {Black, Thick, 
      Arrow[{{0, 0, 0}, {0, 0, λ nλ*1.08}}]},
     {FaceForm[Red],
      Polygon[Partition[amplitudes, nStep + 1, nStep]]}, {FaceForm[
       Blue], Polygon[
       Partition[amplitudes.RotationMatrix[Pi/2, {0, 0, 1}], 
        nStep + 1, nStep]]
      }}]];
plotWave[1, 5]

Mathematica graphics

The first argument is the wavelength, the second argument the number of full wavelength to plot. An optional third argument can be given to specify what ratio of the longitudinal plot length should be assigned to the transverse amplitude.

The output looks pretty much the same as in the other answers, but I generate the wave from a discrete list of points at which the amplitude is calculated. It's important to do this symmetrically so that each half wave has a start and end point on the axis.

The trick then is to make a Polygon out of each half wave. To get the end points to lie on the axis, I partition the amplitude list (amplitudes) with the appropriate sub-list size (nStep +1). Since consecutive half waves share a point on the axis, I have to add an offset as the third argument in Partition.

Finally, I use the fact that Polygon can accept a list of lists, to make the first wave. The second wave is done the same way, except that a rotation matrix is first applied to the list amplitudes.

Edit

If you want other ideas for how to represent waves, you may want to take a look at my web page and the CDF called "PlaneWaveField.cdf" linked near the bottom of the section on 3D arrows.

share|improve this answer
    
You can consider using this palette for effortless image uploading. I added an image to the post. –  Szabolcs Feb 19 '12 at 15:28
    
Thanks - but in this case I didn't think the image adds much info. –  Jens Feb 19 '12 at 16:34

You've gotten answers to the specific problem you had, but here's another way of visualizing the EM wave. This is how I've always seen it depicted in my textbooks, and the advantage is that it prints neatly in black & white.

Module[{w1, w2, colors, plot, lines},
    w1[x_] := {x, 0, Sin[x]};
    w2[x_] := {x, Sin[x], 0};
    colors = Darker /@ {Blue, Green};

    {plot, lines} = ParametricPlot3D[{w1[x], w2[x]}, {x, 0, 4 \[Pi]},   
        Boxed -> False, AxesOrigin -> {0, 0, 0}, MaxRecursion -> 0, 
        PlotStyle -> {{Thick, Thick}, colors}\[Transpose], 
        EvaluationMonitor :> Sow[{Line[{w1[x], {x, 0, 0}}], Line[{w2[x], {x, 0, 0}}]}]
        ] // Reap;

    Show[plot, 
        Graphics3D[Insert[Flatten[lines, 1], colors, 1]\[Transpose]], 
        ViewPoint -> {3.009, -1.348, 0.759}, ViewVertical -> {0.406, -0.398, 5.732}, Ticks -> None, 
        AspectRatio -> 0.75
    ]
 ]

Mathematica graphics

share|improve this answer
1  
Please see if my edit is okay (hope no visible colour fringing is present) –  Szabolcs Feb 19 '12 at 15:08
3  
Oh that's sexy. +1 –  Mr.Wizard Feb 19 '12 at 15:45

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.