Annus Mirabilis · Interactive critical edition in preparation

The finite light complex

Follow a bounded patch of light into a moving frame and compare its energy and volume.

The finite light complex

The finite light complex

Static worked example

Model note
  • Frame speed (frameSpeed), Propagation angle (stationary system) (propagationAngleStationary), Propagation angle (moving system) (propagationAngleMoving), Light complex energy (stationary system) (lightComplexEnergyStationary), Light complex energy (moving system) (lightComplexEnergyMoving), Light complex volume (stationary system) (lightComplexVolumeStationary), Light complex volume (moving system) (lightComplexVolumeMoving), Light amplitude (stationary system) (lightAmplitudeStationary), Light amplitude (moving system) (lightAmplitudeMoving), Doppler factor (dopplerFactor), Lorentz factor (lorentzFactor), Energy density ratio u′/u (energyDensityFactor), Volume ratio V′/V (1/q) (volumeFactor) and Material volume factor 1/γ (materialVolumeFactor): Host calculation, by the site's own reference code. Computed in waves.
  • Computed from the settings last applied (settings revision 1, result 1).
  • Not modeled: media and dispersion; quantum photon structure; finite pulse dispersion in dielectric; gravitational redshift; boundary diffraction at packet edges.

Predict before the numbers

When a spherical light complex travels in the same direction as an observer moving at 0.6c (receding along x), what happens to its volume in the moving frame?

Three relations the model could have

The result appears when you choose, say you have one in mind, or skip.

Set observer speed and packet parameters

A bounded pulse of light does not transform like a solid rod. Its energy follows q = γ(1 − β cos φ) and its volume 1/q. The tempting mistake keeps light’s energy density, q², but gives the packet a rod’s volume, 1/γ, so its energy becomes q²/γ. Along the axis that is 0.2 against 0.5 at 0.6c, and for a ray transverse in the moving frame, cos φ = β, it is 0.512 against 0.8. At φ = 90° in K, q = γ and the two agree at 1.25, so that ray cannot tell them apart.

Experiment settings initial energy and volume, the material rod countermodel

Changes here apply with Apply settings.

Worked example: seen from the frame moving at 0.6c, a light complex of 1 J filling 1 m³ in the stationary frame carries 0.5 J in 2 m³, its ray still at 0°.

Stationary frame KStationary Frame KSpherical light complexE = 1.00 J · V = 1.00 m³xyφ = 0.0°Moving frame kMoving Frame k (β = 0.60c)Physical complexE′ = 0.50 J · V′ = 2.00 m³x′y′v = 0.60cRod: 1/γφ′ = 0.0°
Energy ratio E′/E (q)
0.5
γ(1 − β cos φ) = ν′/ν
Volume ratio V′/V (1/q)
2
1 / [γ(1 − β cos φ)]
Energy density ratio u′/u
0.25
q² = (A′/A)²
Lorentz factor γ
1.25
1 / √(1 − β²)
Countermodel Comparison: “Treat the packet like a rigid rod”

If the packet kept light’s energy density but had a rigid rod’s volume, its volume would scale by 1/γ = 0.8 and its energy by q²/γ = 0.2 (E′_wrong = 0.2 J). The true energy factor is q = 0.5 and the true volume factor is 1/q = 2. At cos φ = β they differ; at φ = 90° in K they agree, because there q = γ.

Values at these settings

Relativistic light complex transformation factors compared to the naive material contraction countermodel.
Energy in K (E)1 J
Physical energy in k (E′)0.5 J
Volume in K (V)1 m³
Physical volume in k (V′)2 m³
Energy ratio E′/E (q)0.5
Volume ratio V′/V (1/q)2
Material volume factor 1/γ0.8
Lorentz factor γ1.25
Transformed angle in k (φ′)0 °
Countermodel E′ (q²/γ)0.2 J (wrong model)
Countermodel V′ (1/γ)0.8 m³ (wrong model)

Remarkably, the energy factor E′/E equals the Doppler frequency ratio ν′/ν = q across all angles and speeds. This exact proportionality between light energy and wave frequency holds invariantly for any bounded light packet under Lorentz transformations.

A packet of light seen from a moving frame changes both its energy and the volume it fills, and its energy changes exactly as its frequency does. Neither change is the shortening of a moving rod.

§8 follows a bounded packet of plane light waves, a light complex. In K, a sphere whose surface moves with the light at speed V along the wave normal lets no energy through, so it always encloses the same light. Seen from k, that sphere is an ellipsoid, and §8 computes its volume as S′/S = √(1 − (v/V)²)/(1 − (v/V) cos φ), where φ is the angle between the wave normal and the motion. Since A²/8π is the energy per unit volume and the amplitude transforms as in §7, the enclosed energy is E′/E = (1 − (v/V) cos φ)/√(1 − (v/V)²), which for φ = 0 becomes √((1 − v/V)/(1 + v/V)). §8 remarks that the energy and the frequency of a light complex change with the observer's motion by the same law. At the lab's default, 0.6c with the light moving along the motion, the energy factor is 0.5: 1 J becomes 0.5 J and 1 m³ becomes 2 m³, and the energy per unit volume falls to a quarter. At φ = 180° the energy doubles and the volume halves. The lab also runs a wrong model, labelled as one and kept out of the numbers above: it keeps light's energy per unit volume but gives the packet a rigid body's volume, 1/γ = 0.8, so its energy scales by q²/γ. Along the motion it predicts 0.2 J against the packet's 0.5 J, and against the motion 3.2 J against 2 J. The decisive ray is one at right angles to the motion in k, cos φ = 0.6 in K: the wrong model gives 0.512 J and 0.8 m³, the packet 0.8 J and 1.25 m³. At φ = 90° in K the two agree on both counts, 1.25 J and 0.8 m³, so that ray cannot tell them apart.

Modern qualifications

§8 writes the energy per unit volume as A²/8π, the speed of light as V, the two volumes as S and S′, and φ for the angle of the wave normal, and then goes on to the pressure of light on a perfect mirror. The remark that energy and frequency transform alike is Einstein's. The paper does not connect it with the light quanta of his March paper, and the reading of a light complex's energy as hν in every frame came later. The rigid-body model is authored for this site as a test of the idea that light contracts like matter; it is not a model from the period.

Not modeled: media and dispersion; quantum photon structure; finite pulse dispersion in dielectric; gravitational redshift; boundary diffraction at packet edges.

Show the code

The site’s own reference code for this law, in TypeScript. It computes the numbers above when the page runs it, and it is what the page uses wherever a FrankenSim result is not available.

evaluateSr10 · src/physics/reference/waves.ts · this site’s source, as built · sha256:ad778c144088027bf765a7708142de80d198481e20d810dad7ba4d4e62bca5e2

This function computes the listed outputs when it runs.

In words

A light complex carries an energy, occupies a volume and has an amplitude, and all three change together under a boost. The function returns the transformed energy, volume and amplitude, and the three factors relating them, for a bundle travelling at a stated angle. The energy factor is the same Doppler factor the previous instrument returns, which is § 8's result: the energy of a light complex transforms exactly as its frequency does.

Implementation

export function evaluateSr10(input: Sr10Input): Sr10EvaluationResult {
  const beta = input.beta;
  const thetaDeg = input.propagationAngleDeg;
  const thetaRad = (thetaDeg * Math.PI) / 180;
  const initialEnergyJ = input.initialEnergyJ ?? 1.0;
  const initialVolumeM3 = input.initialVolumeM3 ?? 1.0;
  const initialAmplitude = input.initialAmplitude ?? 1.0;

  if (!Number.isFinite(beta) || Math.abs(beta) >= 1) {
    return Object.freeze({
      beta,
      gamma: Number.NaN,
      propagationAngleStationaryDeg: thetaDeg,
      propagationAngleStationaryRad: thetaRad,
      propagationAngleMovingDeg: Number.NaN,
      propagationAngleMovingRad: Number.NaN,
      cosThetaStationary: Number.NaN,
      sinThetaStationary: Number.NaN,
      cosThetaMoving: Number.NaN,
      sinThetaMoving: Number.NaN,
      initialEnergyJ,
      transformedEnergyJ: Number.NaN,
      initialVolumeM3,
      transformedVolumeM3: Number.NaN,
      initialAmplitude,
      transformedAmplitude: Number.NaN,
      energyFactor: Number.NaN,
      energyDensityFactor: Number.NaN,
      volumeFactor: Number.NaN,
      amplitudeFactor: Number.NaN,
      materialVolumeFactor: Number.NaN,
      countermodelEnergyJ: Number.NaN,
      countermodelVolumeM3: Number.NaN,
      countermodelEnergyFactor: Number.NaN,
      countermodelVolumeFactor: Number.NaN,
      numericVolumeM3: Number.NaN,
      results: [
        sr10Outside("frameSpeed", "c", "speed"),
        sr10Outside("propagationAngleStationary", "deg", "angle"),
        sr10Outside("propagationAngleMoving", "deg", "angle"),
        sr10Outside("lightComplexEnergyStationary", "J", "energy"),
        sr10Outside("lightComplexEnergyMoving", "J", "energy"),
        sr10Outside("lightComplexVolumeStationary", "m^3", "space-geometry"),
        sr10Outside("lightComplexVolumeMoving", "m^3", "space-geometry"),
        sr10Outside("lightAmplitudeStationary", "V/m", "field"),
        sr10Outside("lightAmplitudeMoving", "V/m", "field"),
        sr10Outside("dopplerFactor", "1", "ratio"),
        sr10Outside("lorentzFactor", "1", "lorentz-factor"),
        sr10Outside("energyDensityFactor", "1", "ratio"),
        sr10Outside("volumeFactor", "1", "ratio"),
        sr10Outside("materialVolumeFactor", "1", "ratio"),
      ],
      countermodelComparison: Object.freeze({
        modelId: "countermodel-material-contraction",
        results: Object.freeze([]),
      }),
      status: "outside-domain",
    });
  }

  const gResult = gamma(beta);
  const g = gResult.status === "value" ? gResult.value : Number.NaN;
  const cosThetaK = Math.cos(thetaRad);
  const sinThetaK = Math.sin(thetaRad);

  const factors = lightComplexFactors(beta, thetaRad);
  const q = factors.energyFactor;
  const q2 = factors.energyDensityFactor;
  const volFactor = factors.volumeFactor;

  const ab = aberration(beta, thetaRad);
  let theta_k_deg = (ab.thetaPrimeRad * 180) / Math.PI;
  if (theta_k_deg < 0) theta_k_deg += 360;

  const transformedEnergyJ = initialEnergyJ * q;
  const transformedVolumeM3 = initialVolumeM3 * volFactor;
  const transformedAmplitude = initialAmplitude * q;

  const countermodel = lightComplexMaterialContractionCountermodel(beta, thetaRad);
  const countermodelEnergyFactor = countermodel.factor;
  const countermodelVolumeFactor = countermodel.volumeFactor;
  const countermodelEnergyJ = initialEnergyJ * countermodelEnergyFactor;
  const countermodelVolumeM3 = initialVolumeM3 * countermodelVolumeFactor;
  const materialVolumeFactor = 1 / g;

  const numericVolRatio = lightComplexVolumeNumeric(beta, thetaRad);
  const numericVolumeM3 = initialVolumeM3 * numericVolRatio;

  const val = (
    quantityId: string,
    unit: string,
    semanticKind: string,
    v: number,
  ): ScientificResult =>
    Object.freeze({
      quantityId,
      unit,
      semanticKind,
      ownerId: OWNER_ID,
      status: "value" as const,
      value: v,
    });

  const results: readonly ScientificResult[] = [
    val("frameSpeed", "c", "speed", beta),
    val("propagationAngleStationary", "deg", "angle", thetaDeg),
    val("propagationAngleMoving", "deg", "angle", theta_k_deg),
    val("lightComplexEnergyStationary", "J", "energy", initialEnergyJ),
    val("lightComplexEnergyMoving", "J", "energy", transformedEnergyJ),
    val("lightComplexVolumeStationary", "m^3", "space-geometry", initialVolumeM3),
    val("lightComplexVolumeMoving", "m^3", "space-geometry", transformedVolumeM3),
    val("lightAmplitudeStationary", "V/m", "field", initialAmplitude),
    val("lightAmplitudeMoving", "V/m", "field", transformedAmplitude),
    val("dopplerFactor", "1", "ratio", q),
    val("lorentzFactor", "1", "lorentz-factor", g),
    val("energyDensityFactor", "1", "ratio", q2),
    val("volumeFactor", "1", "ratio", volFactor),
    val("materialVolumeFactor", "1", "ratio", materialVolumeFactor),
  ];
  // The countermodel is a named wrong model: a reader's numbers never come from it, so it is
  // returned beside the accepted outputs, under its model id, and never among them.
  const countermodelComparison = Object.freeze({
    modelId: countermodel.modelId,
    results: Object.freeze([
      val("countermodelEnergyMoving", "J", "energy", countermodelEnergyJ),
      val("countermodelVolumeMoving", "m^3", "space-geometry", countermodelVolumeM3),
      val("countermodelEnergyFactor", "1", "ratio", countermodelEnergyFactor),
      val("countermodelVolumeFactor", "1", "ratio", countermodelVolumeFactor),
    ]),
  });

  return Object.freeze({
    beta,
    gamma: g,
    propagationAngleStationaryDeg: thetaDeg,
    propagationAngleStationaryRad: thetaRad,
    propagationAngleMovingDeg: theta_k_deg,
    propagationAngleMovingRad: ab.thetaPrimeRad,
    cosThetaStationary: cosThetaK,
    sinThetaStationary: sinThetaK,
    cosThetaMoving: ab.cosThetaPrime,
    sinThetaMoving: ab.sinThetaPrime,
    initialEnergyJ,
    transformedEnergyJ,
    initialVolumeM3,
    transformedVolumeM3,
    initialAmplitude,
    transformedAmplitude,
    energyFactor: q,
    energyDensityFactor: q2,
    volumeFactor: volFactor,
    amplitudeFactor: q,
    materialVolumeFactor,
    countermodelEnergyJ,
    countermodelVolumeM3,
    countermodelEnergyFactor,
    countermodelVolumeFactor,
    numericVolumeM3,
    results,
    countermodelComparison,
    status: "value",
  });
}

The explanation

Full explanation

The energy and the volume of the light complex change by different factors, and so does the energy density. The lab sets a rigid-body model beside the paper's result and names the cases where the two agree.

Show every step of the investigation

Choose the direction of the light, set the speed, and read the energy and volume factors. Compare them with the rigid-body model, then check that the energy changes by the same law as the frequency, as §8 remarks.

An explanatory model, not an observation of nature. This embed starts from the laboratory’s worked defaults, not a saved run. Presentation options change the surrounding guide, never the numerical inputs.