aboutsummaryrefslogtreecommitdiff
path: root/src/physics/test4.ts
blob: a4d4be5d6655fcba9973788dd475c22a767c7982 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import { COULOMB_CONSTANT, type Charge } from './electricField';

export function uniformWork(q: number, field: number, distance: number, angle: number): number {
  return q * field * distance * Math.cos(angle);
}

export function centralWork(q: number, q0: number, ra: number, rb: number): number {
  if (!Number.isFinite(ra) || ra <= 0 || rb <= 0 || Number.isNaN(rb)) throw new RangeError('Distances must be positive; only the final distance may be infinity.');
  return COULOMB_CONSTANT * q * q0 * (1 / ra - 1 / rb);
}

export function energyTransfer(initialPotential: number, potential: number, initialKinetic: number, mass: number) {
  const kinetic = initialKinetic + initialPotential - potential;
  if (kinetic < -1e-20 || mass <= 0) throw new RangeError('This position is energetically inaccessible or the mass is invalid.');
  return { kinetic: Math.max(0, kinetic), total: initialKinetic + initialPotential, speed: Math.sqrt(2 * Math.max(0, kinetic) / mass) };
}

export function assembledEnergy(charges: readonly Charge[]): number {
  let energy = 0;
  for (let i = 0; i < charges.length; i++) for (let j = i + 1; j < charges.length; j++) {
    const a = charges[i], b = charges[j];
    const distance = Math.hypot(a.x - b.x, a.y - b.y, a.z - b.z);
    if (distance === 0) throw new RangeError('Point charges must have distinct positions.');
    energy += COULOMB_CONSTANT * a.coulombs * b.coulombs / distance;
  }
  return energy;
}

/** Dipole in the xy plane, E along +x; positive theta is counterclockwise. */
export function dipoleState(moment: number, field: number, theta: number, thetaA: number) {
  return {
    energy: -moment * field * Math.cos(theta),
    torqueZ: -moment * field * Math.sin(theta),
    work: moment * field * (Math.cos(theta) - Math.cos(thetaA)),
  };
}