8 · Mirror worlds
Everything in Acts I and II floated in free space. Real antennas don’t: they hang over the earth, and the ground rewrites their impedance and their pattern. Act III adds it back, one layer of realism at a time. Start with the simplest possible ground — a perfect conductor — because it costs almost nothing and it already reproduces the effect every operator knows by feel.
The oldest trick
Section titled “The oldest trick”A perfect electric conductor forces the tangential electric field to vanish on
its surface. You could enforce that with a wall of unknowns across the whole
plane — or you could use the trick Lord Kelvin published in 1848. Replace the
ground with a mirror image of the antenna, the same distance below the
plane, carrying a current arranged so the two together satisfy E_tan = 0
automatically. For a horizontal wire, the image current runs backwards:
Above the plane, the field of {antenna + image} is identical to the field of
{antenna + real ground} — and now there’s no ground to mesh, just a second wire
that isn’t even an unknown. Its current is dictated, point for point, by the
real antenna’s. In the method of moments this is almost insultingly cheap: every
matrix entry gains one extra kernel term — the field of segment n’s image
evaluated at segment m — and nothing else changes. Same unknowns, same matrix
size. In momwire it’s a single constructor argument,
ground_z:
set the plane’s height and the solver reflects every segment for you.
Height is a knob
Section titled “Height is a knob”Once the image is in, the antenna feels its own reflection — and the feel depends entirely on how far above the ground it sits, because the round trip down to the image and back is a path length that slides in and out of phase:
Read it from the left. At very low height the image is right underneath,
its reversed current almost perfectly cancelling the real one — the radiation
resistance collapses toward zero. A horizontal dipole lying on a perfect
ground is a short circuit; it can’t radiate, because its mirror twin is fighting
it at point-blank range. Lift it to about 0.3 λ and the reflection comes
back in phase — R peaks near 94 Ω, well above free space. Keep going and the
impedance oscillates, each swing smaller than the last, converging on the
free-space 69.7 Ω as the ground recedes out of reach.
That oscillation is not a numerical artifact; it is the single most practical fact about antenna height. Every operator who has raised a dipole and watched the SWR change has measured this curve. It’s why “get it up at least a half-wavelength” is folklore, and why a low antenna feeds so strangely.
Run it yourself
Section titled “Run it yourself”import numpy as npfrom momwire import BSplineSolver
# horizontal half-wave dipole, 0.3 lambda up, over perfect ground at z = 0h = 0.3 * 22.0wire = np.array([[-5.291, 0.0, h], [5.291, 0.0, h]])solver = BSplineSolver(wires=[wire], nsegs=21, wavelength=22.0, wire_radius=0.0005, degree=2, ground_z=0.0, # <- the whole ground model feed_wire_index=0, feed_arclength=5.291)Z, _ = solver.compute_impedance()print(f"Z_in = {Z.real:.0f} {Z.imag:+.0f}j ohms") # ~93 +5j — up from 70 in free spaceOne argument, one extra kernel term, and the dipole knows there’s a floor.
The grounded end
Section titled “The grounded end”Everything above kept the antenna clear of the plane. But the oldest antenna over ground doesn’t hover — it touches: a quarter-wave vertical driven against the earth itself. And here the mirror pays out its famous dividend, because a vertical current images unreversed (flip the geometry across the plane and the arrow still points the same way). The image doesn’t fight the wire; it finishes it. Monopole + mirror twin = a half-wave dipole, of which you only had to build half.
That poses a boundary-condition question the free-space chapters never faced.
A free wire end pins its current to zero — charge has nowhere to go. But a
wire end in the plane is not an end at all: the current flows through into
the image. So the solver must treat a ground-touching end as a junction with
its own reflection — the end current stays a real unknown, and the image
supplies the return path. (momwire does exactly this whenever a wire end lies
in the ground_z plane; pinning it to zero instead would strangle the feed
and report a monopole as a few-picofarad capacitor.)
import numpy as npfrom momwire import BSplineSolver
# quarter-wave vertical, base ON the perfect ground at z = 0wire = np.array([[0.0, 0.0, 0.0], [0.0, 0.0, 5.236]])solver = BSplineSolver(wires=[wire], nsegs=21, wavelength=22.0, wire_radius=0.0005, degree=2, ground_z=0.0, feed_wire_index=0, feed_arclength=0.1) # drive the baseZ, _ = solver.compute_impedance()print(f"Z_in = {Z.real:.0f} {Z.imag:+.0f}j ohms") # ~34 -17jSolve the equivalent free-space dipole (double the wire, feed the middle) and
you get twice that — 67 -35j — to the last digit that matters. The plane did
half the work: half the antenna, half the impedance, which is why the
textbook monopole reads 36 Ω where the textbook dipole reads 73. The current
profile tells the same story — maximum at the base where the free-end rule
would have forced a zero, tapering to nothing at the tip, exactly the top half
of a dipole’s hump.
But the earth is not a perfect conductor — it’s dirt, imperfectly reflecting and quietly absorbing. The mirror is real but dim, and its dimness is complex and angle-dependent. Chapter 9 replaces the perfect image with the next honest approximation: the Fresnel reflection coefficient.