@classytic/stage 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +5 -1
- package/dist/_virtual/_rolldown/runtime.mjs +18 -0
- package/dist/assets/index.mjs +0 -1
- package/dist/atomic/aufbau.d.mts +144 -0
- package/dist/atomic/aufbau.mjs +384 -0
- package/dist/atomic/elements.d.mts +67 -0
- package/dist/atomic/elements.mjs +785 -0
- package/dist/atomic/emission.d.mts +112 -0
- package/dist/atomic/emission.mjs +179 -0
- package/dist/atomic/index.d.mts +8 -0
- package/dist/atomic/index.mjs +9 -0
- package/dist/atomic/periodic.d.mts +82 -0
- package/dist/atomic/periodic.mjs +231 -0
- package/dist/atomic/properties.d.mts +100 -0
- package/dist/atomic/properties.mjs +574 -0
- package/dist/atomic/shells.d.mts +137 -0
- package/dist/atomic/shells.mjs +170 -0
- package/dist/atomic/trends.d.mts +148 -0
- package/dist/atomic/trends.mjs +225 -0
- package/dist/builder/Palette.mjs +50 -89
- package/dist/builder/SceneBuilder.mjs +15 -73
- package/dist/chem/chromatography.d.mts +66 -0
- package/dist/chem/chromatography.mjs +63 -0
- package/dist/chem/complex.d.mts +114 -0
- package/dist/chem/complex.mjs +234 -0
- package/dist/chem/cycle.d.mts +75 -0
- package/dist/chem/cycle.mjs +145 -0
- package/dist/chem/equation.d.mts +86 -0
- package/dist/chem/equation.mjs +168 -0
- package/dist/chem/formula.d.mts +90 -0
- package/dist/chem/formula.mjs +201 -0
- package/dist/chem/functional-groups.d.mts +31 -0
- package/dist/chem/functional-groups.mjs +187 -0
- package/dist/chem/hazard.d.mts +94 -0
- package/dist/chem/hazard.mjs +329 -0
- package/dist/chem/index.d.mts +34 -33
- package/dist/chem/index.mjs +34 -28
- package/dist/chem/ionic.d.mts +98 -0
- package/dist/chem/ionic.mjs +156 -0
- package/dist/chem/layout.d.mts +46 -0
- package/dist/chem/layout.mjs +342 -0
- package/dist/chem/lewis.d.mts +79 -0
- package/dist/chem/lewis.mjs +163 -0
- package/dist/chem/molecular-orbital.d.mts +114 -0
- package/dist/chem/molecular-orbital.mjs +201 -0
- package/dist/chem/molecule.d.mts +154 -0
- package/dist/chem/molecule.mjs +282 -0
- package/dist/chem/nmr.d.mts +153 -0
- package/dist/chem/nmr.mjs +165 -0
- package/dist/chem/polymer.d.mts +65 -0
- package/dist/chem/polymer.mjs +179 -0
- package/dist/chem/redox.d.mts +138 -0
- package/dist/chem/redox.mjs +328 -0
- package/dist/chem/relations.d.mts +183 -0
- package/dist/chem/relations.mjs +299 -0
- package/dist/chem/skeleton.d.mts +51 -0
- package/dist/chem/skeleton.mjs +186 -0
- package/dist/chem/solution.d.mts +116 -0
- package/dist/chem/solution.mjs +186 -0
- package/dist/chem/species.d.mts +47 -0
- package/dist/chem/species.mjs +128 -0
- package/dist/chem/stereo.d.mts +108 -0
- package/dist/chem/stereo.mjs +286 -0
- package/dist/chem/stoichiometry.d.mts +95 -0
- package/dist/chem/stoichiometry.mjs +145 -0
- package/dist/chem/synthesis.d.mts +113 -0
- package/dist/chem/synthesis.mjs +281 -0
- package/dist/chem/vsepr.d.mts +80 -0
- package/dist/chem/vsepr.mjs +247 -0
- package/dist/circuit/ac.d.mts +163 -0
- package/dist/circuit/ac.mjs +452 -0
- package/dist/circuit/dc.d.mts +92 -0
- package/dist/circuit/dc.mjs +333 -0
- package/dist/circuit/index.d.mts +5 -92
- package/dist/circuit/index.mjs +5 -332
- package/dist/circuit/network.d.mts +99 -0
- package/dist/circuit/network.mjs +440 -0
- package/dist/circuit/topology.d.mts +102 -0
- package/dist/circuit/topology.mjs +143 -0
- package/dist/colour/absorption.d.mts +79 -0
- package/dist/colour/absorption.mjs +137 -0
- package/dist/colour/index.d.mts +6 -0
- package/dist/colour/index.mjs +7 -0
- package/dist/colour/name.d.mts +14 -0
- package/dist/colour/name.mjs +76 -0
- package/dist/colour/observer.d.mts +31 -0
- package/dist/colour/observer.mjs +46 -0
- package/dist/colour/spectrum.d.mts +61 -0
- package/dist/colour/spectrum.mjs +108 -0
- package/dist/colour/srgb.d.mts +49 -0
- package/dist/colour/srgb.mjs +108 -0
- package/dist/core/constants.d.mts +138 -0
- package/dist/core/constants.mjs +139 -0
- package/dist/core/index.d.mts +4 -1
- package/dist/core/index.mjs +4 -1
- package/dist/core/math.d.mts +26 -0
- package/dist/core/math.mjs +37 -0
- package/dist/core/vec3.d.mts +94 -0
- package/dist/core/vec3.mjs +123 -0
- package/dist/core/worked.d.mts +35 -0
- package/dist/core/worked.mjs +44 -0
- package/dist/electro/cell.d.mts +102 -0
- package/dist/electro/cell.mjs +170 -0
- package/dist/electro/conductivity.d.mts +157 -0
- package/dist/electro/conductivity.mjs +156 -0
- package/dist/electro/couples.d.mts +114 -0
- package/dist/electro/couples.mjs +334 -0
- package/dist/electro/electrolysis.d.mts +96 -0
- package/dist/electro/electrolysis.mjs +274 -0
- package/dist/electro/faraday.d.mts +150 -0
- package/dist/electro/faraday.mjs +118 -0
- package/dist/electro/index.d.mts +6 -0
- package/dist/electro/index.mjs +7 -0
- package/dist/finance/accounting/adjustments.d.mts +17 -0
- package/dist/finance/accounting/adjustments.mjs +202 -0
- package/dist/finance/accounting/analysis.d.mts +8 -0
- package/dist/finance/accounting/analysis.mjs +205 -0
- package/dist/finance/accounting/clubs.d.mts +21 -0
- package/dist/finance/accounting/clubs.mjs +217 -0
- package/dist/finance/accounting/company-statements.d.mts +7 -0
- package/dist/finance/accounting/company-statements.mjs +150 -0
- package/dist/finance/accounting/harness.d.mts +7 -0
- package/dist/finance/accounting/harness.mjs +45 -0
- package/dist/finance/accounting/index.d.mts +18 -0
- package/dist/finance/accounting/index.mjs +18 -0
- package/dist/finance/accounting/journalize.d.mts +16 -0
- package/dist/finance/accounting/journalize.mjs +128 -0
- package/dist/finance/accounting/manufacturing.d.mts +8 -0
- package/dist/finance/accounting/manufacturing.mjs +236 -0
- package/dist/finance/accounting/partnership.d.mts +7 -0
- package/dist/finance/accounting/partnership.mjs +152 -0
- package/dist/finance/accounting/period-case.d.mts +6 -0
- package/dist/finance/accounting/period-case.mjs +71 -0
- package/dist/finance/accounting/post.d.mts +9 -0
- package/dist/finance/accounting/post.mjs +84 -0
- package/dist/finance/accounting/precision.d.mts +9 -0
- package/dist/finance/accounting/precision.mjs +15 -0
- package/dist/finance/accounting/rules.d.mts +21 -0
- package/dist/finance/accounting/rules.mjs +37 -0
- package/dist/finance/accounting/solve.d.mts +28 -0
- package/dist/finance/accounting/solve.mjs +92 -0
- package/dist/finance/accounting/statements.d.mts +7 -0
- package/dist/finance/accounting/statements.mjs +142 -0
- package/dist/finance/accounting/types.d.mts +649 -0
- package/dist/finance/accounting/validate.d.mts +7 -0
- package/dist/finance/accounting/validate.mjs +67 -0
- package/dist/finance/accounting/verification.d.mts +24 -0
- package/dist/finance/accounting/verification.mjs +386 -0
- package/dist/finance/bizsim.d.mts +75 -0
- package/dist/finance/bizsim.mjs +296 -0
- package/dist/finance/index.d.mts +95 -0
- package/dist/finance/index.mjs +145 -0
- package/dist/finance/investment-math.d.mts +7 -0
- package/dist/finance/investment-math.mjs +18 -0
- package/dist/finance/management-accounting/budgeting.d.mts +7 -0
- package/dist/finance/management-accounting/budgeting.mjs +189 -0
- package/dist/finance/management-accounting/cash-budget.d.mts +7 -0
- package/dist/finance/management-accounting/cash-budget.mjs +154 -0
- package/dist/finance/management-accounting/costing.d.mts +8 -0
- package/dist/finance/management-accounting/costing.mjs +175 -0
- package/dist/finance/management-accounting/decisions.d.mts +8 -0
- package/dist/finance/management-accounting/decisions.mjs +164 -0
- package/dist/finance/management-accounting/index.d.mts +13 -0
- package/dist/finance/management-accounting/index.mjs +13 -0
- package/dist/finance/management-accounting/integrated-budget.d.mts +8 -0
- package/dist/finance/management-accounting/integrated-budget.mjs +67 -0
- package/dist/finance/management-accounting/inventory-costing.d.mts +7 -0
- package/dist/finance/management-accounting/inventory-costing.mjs +173 -0
- package/dist/finance/management-accounting/investment-appraisal.d.mts +7 -0
- package/dist/finance/management-accounting/investment-appraisal.mjs +148 -0
- package/dist/finance/management-accounting/management-case.d.mts +8 -0
- package/dist/finance/management-accounting/management-case.mjs +91 -0
- package/dist/finance/management-accounting/master-budget.d.mts +7 -0
- package/dist/finance/management-accounting/master-budget.mjs +137 -0
- package/dist/finance/management-accounting/production-costing.d.mts +8 -0
- package/dist/finance/management-accounting/production-costing.mjs +214 -0
- package/dist/finance/management-accounting/types.d.mts +644 -0
- package/dist/finance/management-accounting/variances.d.mts +7 -0
- package/dist/finance/management-accounting/variances.mjs +150 -0
- package/dist/index.d.mts +9 -8
- package/dist/index.mjs +5 -5
- package/dist/interaction/MovableDot.mjs +19 -0
- package/dist/interaction/useDraggable.mjs +24 -4
- package/dist/math/analysis.d.mts +61 -0
- package/dist/math/analysis.mjs +187 -0
- package/dist/math/answer-check.d.mts +50 -0
- package/dist/math/answer-check.mjs +106 -0
- package/dist/math/calculus.d.mts +17 -1
- package/dist/math/calculus.mjs +365 -2
- package/dist/math/complex.d.mts +93 -0
- package/dist/math/complex.mjs +239 -0
- package/dist/math/expr.d.mts +23 -0
- package/dist/math/expr.mjs +36 -0
- package/dist/math/index.d.mts +9 -23
- package/dist/math/index.mjs +9 -38
- package/dist/math/latex.mjs +10 -1
- package/dist/math/parse.mjs +1 -1
- package/dist/math/poly.d.mts +55 -0
- package/dist/math/poly.mjs +273 -0
- package/dist/math/rearrange.d.mts +14 -0
- package/dist/math/rearrange.mjs +125 -0
- package/dist/math/solve.d.mts +21 -0
- package/dist/math/solve.mjs +75 -0
- package/dist/networking/addressing.d.mts +26 -0
- package/dist/networking/addressing.mjs +33 -0
- package/dist/networking/cloud/access.d.mts +36 -0
- package/dist/networking/cloud/access.mjs +95 -0
- package/dist/networking/cloud/containers.d.mts +43 -0
- package/dist/networking/cloud/containers.mjs +54 -0
- package/dist/networking/cloud/edge.d.mts +17 -0
- package/dist/networking/cloud/edge.mjs +31 -0
- package/dist/networking/cloud/failure-domains.d.mts +19 -0
- package/dist/networking/cloud/failure-domains.mjs +22 -0
- package/dist/networking/cloud/geo-routing.d.mts +22 -0
- package/dist/networking/cloud/geo-routing.mjs +64 -0
- package/dist/networking/cloud/index.d.mts +18 -0
- package/dist/networking/cloud/index.mjs +19 -0
- package/dist/networking/cloud/inference-reliability.d.mts +30 -0
- package/dist/networking/cloud/inference-reliability.mjs +76 -0
- package/dist/networking/cloud/inference.d.mts +118 -0
- package/dist/networking/cloud/inference.mjs +179 -0
- package/dist/networking/cloud/infrastructure.d.mts +45 -0
- package/dist/networking/cloud/infrastructure.mjs +96 -0
- package/dist/networking/cloud/observability.d.mts +24 -0
- package/dist/networking/cloud/observability.mjs +34 -0
- package/dist/networking/cloud/orchestration.d.mts +32 -0
- package/dist/networking/cloud/orchestration.mjs +38 -0
- package/dist/networking/cloud/recovery.d.mts +21 -0
- package/dist/networking/cloud/recovery.mjs +27 -0
- package/dist/networking/cloud/releases.d.mts +42 -0
- package/dist/networking/cloud/releases.mjs +135 -0
- package/dist/networking/cloud/scaling.d.mts +25 -0
- package/dist/networking/cloud/scaling.mjs +65 -0
- package/dist/networking/cloud/secrets.d.mts +39 -0
- package/dist/networking/cloud/secrets.mjs +68 -0
- package/dist/networking/cloud/server-deployment.d.mts +29 -0
- package/dist/networking/cloud/server-deployment.mjs +72 -0
- package/dist/networking/cloud/storage.d.mts +16 -0
- package/dist/networking/cloud/storage.mjs +58 -0
- package/dist/networking/cloud/vpc.d.mts +18 -0
- package/dist/networking/cloud/vpc.mjs +100 -0
- package/dist/networking/delivery.d.mts +34 -0
- package/dist/networking/delivery.mjs +52 -0
- package/dist/networking/index.d.mts +47 -0
- package/dist/networking/index.mjs +47 -0
- package/dist/networking/ipv6.d.mts +28 -0
- package/dist/networking/ipv6.mjs +17 -0
- package/dist/networking/journeys.d.mts +83 -0
- package/dist/networking/journeys.mjs +161 -0
- package/dist/networking/models/airtime.d.mts +87 -0
- package/dist/networking/models/airtime.mjs +130 -0
- package/dist/networking/models/cellular.d.mts +157 -0
- package/dist/networking/models/cellular.mjs +252 -0
- package/dist/networking/models/encapsulation.d.mts +98 -0
- package/dist/networking/models/encapsulation.mjs +132 -0
- package/dist/networking/models/handover.d.mts +116 -0
- package/dist/networking/models/handover.mjs +209 -0
- package/dist/networking/models/handshake.d.mts +90 -0
- package/dist/networking/models/handshake.mjs +122 -0
- package/dist/networking/models/index.d.mts +14 -0
- package/dist/networking/models/index.mjs +15 -0
- package/dist/networking/models/media.d.mts +82 -0
- package/dist/networking/models/media.mjs +188 -0
- package/dist/networking/models/satellite.d.mts +86 -0
- package/dist/networking/models/satellite.mjs +121 -0
- package/dist/networking/models/spectrum.d.mts +83 -0
- package/dist/networking/models/spectrum.mjs +235 -0
- package/dist/networking/models/switch.d.mts +80 -0
- package/dist/networking/models/switch.mjs +155 -0
- package/dist/networking/models/vlan.d.mts +62 -0
- package/dist/networking/models/vlan.mjs +100 -0
- package/dist/networking/models/vpn.d.mts +66 -0
- package/dist/networking/models/vpn.mjs +125 -0
- package/dist/networking/models/wifi-privacy.d.mts +82 -0
- package/dist/networking/models/wifi-privacy.mjs +130 -0
- package/dist/networking/models/wifi.d.mts +240 -0
- package/dist/networking/models/wifi.mjs +562 -0
- package/dist/networking/nat-traversal.d.mts +24 -0
- package/dist/networking/nat-traversal.mjs +38 -0
- package/dist/networking/protocols.d.mts +17 -0
- package/dist/networking/protocols.mjs +57 -0
- package/dist/networking/queue.d.mts +12 -0
- package/dist/networking/queue.mjs +18 -0
- package/dist/networking/route-learning.d.mts +23 -0
- package/dist/networking/route-learning.mjs +43 -0
- package/dist/networking/routing.d.mts +11 -0
- package/dist/networking/routing.mjs +25 -0
- package/dist/networking/signals.d.mts +26 -0
- package/dist/networking/signals.mjs +35 -0
- package/dist/networking/subnet.d.mts +49 -0
- package/dist/networking/subnet.mjs +89 -0
- package/dist/networking/tcp-reliability.d.mts +24 -0
- package/dist/networking/tcp-reliability.mjs +38 -0
- package/dist/networking/topology/contract.d.mts +123 -0
- package/dist/networking/topology/index.d.mts +4 -0
- package/dist/networking/topology/index.mjs +4 -0
- package/dist/networking/topology/presets.d.mts +7 -0
- package/dist/networking/topology/presets.mjs +302 -0
- package/dist/networking/topology/simulation.d.mts +8 -0
- package/dist/networking/topology/simulation.mjs +179 -0
- package/dist/networking/wireless.d.mts +11 -0
- package/dist/networking/wireless.mjs +17 -0
- package/dist/optics/imaging.d.mts +218 -0
- package/dist/optics/imaging.mjs +276 -0
- package/dist/optics/index.d.mts +7 -0
- package/dist/optics/index.mjs +8 -0
- package/dist/optics/laws.d.mts +70 -0
- package/dist/optics/laws.mjs +195 -0
- package/dist/optics/prism.d.mts +148 -0
- package/dist/optics/prism.mjs +197 -0
- package/dist/optics/refraction.d.mts +201 -0
- package/dist/optics/refraction.mjs +270 -0
- package/dist/optics/wave-optics.d.mts +171 -0
- package/dist/optics/wave-optics.mjs +259 -0
- package/dist/physics/ac/index.d.mts +183 -0
- package/dist/physics/ac/index.mjs +203 -0
- package/dist/physics/dynamics/forces.d.mts +98 -0
- package/dist/physics/dynamics/forces.mjs +153 -0
- package/dist/physics/dynamics/friction.d.mts +76 -0
- package/dist/physics/dynamics/friction.mjs +119 -0
- package/dist/physics/dynamics/system.d.mts +68 -0
- package/dist/physics/dynamics/system.mjs +125 -0
- package/dist/physics/electrostatics/index.d.mts +169 -0
- package/dist/physics/electrostatics/index.mjs +249 -0
- package/dist/physics/energy/centre-of-mass.d.mts +115 -0
- package/dist/physics/energy/centre-of-mass.mjs +180 -0
- package/dist/physics/energy/conservation.d.mts +81 -0
- package/dist/physics/energy/conservation.mjs +129 -0
- package/dist/physics/energy/power.d.mts +90 -0
- package/dist/physics/energy/power.mjs +167 -0
- package/dist/physics/energy/spring.d.mts +73 -0
- package/dist/physics/energy/spring.mjs +129 -0
- package/dist/physics/energy/store.d.mts +63 -0
- package/dist/physics/energy/store.mjs +108 -0
- package/dist/physics/energy/theorem.d.mts +65 -0
- package/dist/physics/energy/theorem.mjs +113 -0
- package/dist/physics/energy/work.d.mts +114 -0
- package/dist/physics/energy/work.mjs +219 -0
- package/dist/physics/gravitation/body.d.mts +85 -0
- package/dist/physics/gravitation/body.mjs +168 -0
- package/dist/physics/gravitation/kepler.d.mts +127 -0
- package/dist/physics/gravitation/kepler.mjs +216 -0
- package/dist/physics/gravitation/law.d.mts +117 -0
- package/dist/physics/gravitation/law.mjs +175 -0
- package/dist/physics/gravitation/orbit.d.mts +119 -0
- package/dist/physics/gravitation/orbit.mjs +202 -0
- package/dist/physics/gravitation/potential.d.mts +114 -0
- package/dist/physics/gravitation/potential.mjs +202 -0
- package/dist/physics/gravitation/variation.d.mts +97 -0
- package/dist/physics/gravitation/variation.mjs +175 -0
- package/dist/physics/index.d.mts +35 -0
- package/dist/physics/index.mjs +36 -0
- package/dist/physics/integral-sweep.d.mts +63 -0
- package/dist/physics/integral-sweep.mjs +126 -0
- package/dist/physics/kinematics/equations.d.mts +47 -0
- package/dist/physics/kinematics/equations.mjs +126 -0
- package/dist/physics/kinematics/free-fall.d.mts +53 -0
- package/dist/physics/kinematics/free-fall.mjs +71 -0
- package/dist/physics/kinematics/given.d.mts +16 -0
- package/dist/physics/kinematics/given.mjs +55 -0
- package/dist/physics/kinematics/roots.d.mts +41 -0
- package/dist/physics/kinematics/roots.mjs +72 -0
- package/dist/physics/kinematics/solve.d.mts +52 -0
- package/dist/physics/kinematics/solve.mjs +172 -0
- package/dist/physics/magnetism/biot-savart.d.mts +161 -0
- package/dist/physics/magnetism/biot-savart.mjs +353 -0
- package/dist/physics/magnetism/flux.d.mts +94 -0
- package/dist/physics/magnetism/flux.mjs +313 -0
- package/dist/physics/magnetism/geomagnetism.d.mts +151 -0
- package/dist/physics/magnetism/geomagnetism.mjs +184 -0
- package/dist/physics/magnetism/index.d.mts +12 -0
- package/dist/physics/magnetism/index.mjs +74 -0
- package/dist/physics/magnetism/lorentz.d.mts +28 -0
- package/dist/physics/magnetism/lorentz.mjs +88 -0
- package/dist/physics/magnetism/magnetic-force.d.mts +102 -0
- package/dist/physics/magnetism/magnetic-force.mjs +169 -0
- package/dist/physics/momentum/collide.d.mts +77 -0
- package/dist/physics/momentum/collide.mjs +115 -0
- package/dist/physics/momentum/impulse.d.mts +89 -0
- package/dist/physics/momentum/impulse.mjs +159 -0
- package/dist/physics/momentum/planar.d.mts +60 -0
- package/dist/physics/momentum/planar.mjs +110 -0
- package/dist/physics/projectile.d.mts +107 -0
- package/dist/physics/projectile.mjs +185 -0
- package/dist/physics/rotation/angular.d.mts +85 -0
- package/dist/physics/rotation/angular.mjs +130 -0
- package/dist/physics/rotation/circular.d.mts +79 -0
- package/dist/physics/rotation/circular.mjs +131 -0
- package/dist/physics/rotation/inertia.d.mts +164 -0
- package/dist/physics/rotation/inertia.mjs +332 -0
- package/dist/physics/rotation/torque.d.mts +65 -0
- package/dist/physics/rotation/torque.mjs +134 -0
- package/dist/physics/vectors.d.mts +64 -0
- package/dist/physics/vectors.mjs +114 -0
- package/dist/primitives/Dot.d.mts +2 -15
- package/dist/primitives/Dot.mjs +6 -4
- package/dist/primitives/Grid.d.mts +33 -17
- package/dist/primitives/Grid.mjs +89 -17
- package/dist/primitives/Label.d.mts +1 -14
- package/dist/primitives/Label.mjs +3 -2
- package/dist/primitives/Lines.d.mts +4 -32
- package/dist/primitives/Lines.mjs +10 -8
- package/dist/primitives/Shapes.d.mts +5 -43
- package/dist/primitives/Shapes.mjs +12 -10
- package/dist/primitives/index.d.mts +2 -2
- package/dist/primitives/index.mjs +2 -2
- package/dist/primitives/props.mjs +31 -0
- package/dist/quantity/index.d.mts +119 -0
- package/dist/quantity/index.mjs +417 -0
- package/dist/relation/derive.d.mts +74 -0
- package/dist/relation/derive.mjs +73 -0
- package/dist/relation/index.d.mts +56 -0
- package/dist/relation/index.mjs +234 -0
- package/dist/scene/Scene.d.mts +6 -1
- package/dist/scene/Scene.mjs +15 -40
- package/dist/scene/evaluators.mjs +1 -1
- package/dist/sim/thermal.mjs +45 -20
- package/dist/thermo/calorimetry.d.mts +207 -0
- package/dist/thermo/calorimetry.mjs +345 -0
- package/dist/thermo/cycles.d.mts +142 -0
- package/dist/thermo/cycles.mjs +256 -0
- package/dist/thermo/entropy.d.mts +87 -0
- package/dist/thermo/entropy.mjs +140 -0
- package/dist/thermo/expansion.d.mts +130 -0
- package/dist/thermo/expansion.mjs +178 -0
- package/dist/thermo/gas.d.mts +197 -0
- package/dist/thermo/gas.mjs +279 -0
- package/dist/thermo/heat-transfer.d.mts +164 -0
- package/dist/thermo/heat-transfer.mjs +217 -0
- package/dist/thermo/index.d.mts +9 -82
- package/dist/thermo/index.mjs +9 -132
- package/dist/thermo/processes.d.mts +95 -0
- package/dist/thermo/processes.mjs +154 -0
- package/dist/thermo/temperature.d.mts +174 -0
- package/dist/thermo/temperature.mjs +236 -0
- package/dist/view/Stage.mjs +4 -11
- package/dist/waves/damping.d.mts +224 -0
- package/dist/waves/damping.mjs +317 -0
- package/dist/waves/doppler.d.mts +72 -0
- package/dist/waves/doppler.mjs +125 -0
- package/dist/waves/index.d.mts +10 -0
- package/dist/waves/index.mjs +10 -0
- package/dist/waves/pendulum.d.mts +130 -0
- package/dist/waves/pendulum.mjs +211 -0
- package/dist/waves/pitch.d.mts +125 -0
- package/dist/waves/pitch.mjs +158 -0
- package/dist/waves/shm.d.mts +170 -0
- package/dist/waves/shm.mjs +279 -0
- package/dist/waves/springs.d.mts +103 -0
- package/dist/waves/springs.mjs +176 -0
- package/dist/waves/superposition.d.mts +124 -0
- package/dist/waves/superposition.mjs +196 -0
- package/dist/waves/wave.d.mts +154 -0
- package/dist/waves/wave.mjs +178 -0
- package/package.json +103 -23
- package/styles.css +125 -8
- package/dist/assets/kit/index.mjs +0 -4
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { Worked } from "../../core/worked.mjs";
|
|
2
|
+
import { Sweep } from "../integral-sweep.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/physics/energy/spring.d.ts
|
|
5
|
+
interface SpringWork {
|
|
6
|
+
/** Work done BY the spring: negative when the spring is being stretched further from natural length. */
|
|
7
|
+
readonly bySpring: number;
|
|
8
|
+
/** Work done by whatever is pulling or pushing: the same size, opposite sign. */
|
|
9
|
+
readonly byAgent: number;
|
|
10
|
+
/** Energy stored at the start and at the end, both measured from the natural length. */
|
|
11
|
+
readonly storedBefore: number;
|
|
12
|
+
readonly storedAfter: number;
|
|
13
|
+
/** The integral, ready to animate: strips under the force-extension graph. */
|
|
14
|
+
readonly sweep: Sweep;
|
|
15
|
+
readonly worked: Worked;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* The work a spring does as its extension goes from `from` to `to`.
|
|
19
|
+
*
|
|
20
|
+
* Both extensions are measured from the NATURAL length and are signed, so a compression is negative.
|
|
21
|
+
* The squares mean the answer only ever depends on the two magnitudes, which is why `−3 cm to 0` and
|
|
22
|
+
* `+3 cm to 0` give the same release.
|
|
23
|
+
*
|
|
24
|
+
* Their Type-04 strategy sheet says to integrate rather than to reach for the formula, and to place
|
|
25
|
+
* the limits carefully with their signs. That is exactly what happens below.
|
|
26
|
+
*/
|
|
27
|
+
declare function springWork(stiffness: number, from: number, to: number, sf?: number): SpringWork;
|
|
28
|
+
/**
|
|
29
|
+
* The stiffness a second spring needs so that a stated stretch stores a stated multiple of the
|
|
30
|
+
* energy of the first.
|
|
31
|
+
*
|
|
32
|
+
* Their Example-14, and a genuinely good question, because it cannot be answered by substituting
|
|
33
|
+
* into `½kx²` once. It has to be answered by the RATIO, where everything shared cancels and what is
|
|
34
|
+
* left is `k ∝ W/x²`. Returning the ratio as well as the stiffness is deliberate: the ratio is the
|
|
35
|
+
* transferable part.
|
|
36
|
+
*/
|
|
37
|
+
declare function stiffnessForEnergyRatio(stiffness: number, energyRatio: number, extensionRatio: number, sf?: number): {
|
|
38
|
+
readonly stiffness: number;
|
|
39
|
+
readonly ratio: number;
|
|
40
|
+
readonly worked: Worked;
|
|
41
|
+
};
|
|
42
|
+
interface SpringLaunch {
|
|
43
|
+
/** Speed of the body once the spring reaches its natural length. */
|
|
44
|
+
readonly speed: number;
|
|
45
|
+
readonly storedEnergy: number;
|
|
46
|
+
/** Energy lost to friction over the release, zero on a smooth surface. */
|
|
47
|
+
readonly lostToFriction: number;
|
|
48
|
+
readonly kineticEnergy: number;
|
|
49
|
+
readonly worked: Worked;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* A compressed spring released against a block: how fast the block leaves.
|
|
53
|
+
*
|
|
54
|
+
* Optional friction, because the pair of questions "smooth" then "now with friction" is the standard
|
|
55
|
+
* way this is examined, and the second one is only harder in that one term joins the ledger. The
|
|
56
|
+
* ledger is the lesson: what the spring stored either ends up as motion or ends up as heat, and
|
|
57
|
+
* there is nowhere else for it to go.
|
|
58
|
+
*/
|
|
59
|
+
declare function springLaunch(stiffness: number, compression: number, mass: number, frictionForce?: number, sf?: number): SpringLaunch;
|
|
60
|
+
/**
|
|
61
|
+
* How far a moving block compresses a spring before it stops.
|
|
62
|
+
*
|
|
63
|
+
* The launch run backwards, and the standard way a work-energy question is dressed up. The answer
|
|
64
|
+
* comes out as a magnitude and is then given a negative sign, because the spring was compressed:
|
|
65
|
+
* that last move is the one worth watching, since the square root cannot know which way the block
|
|
66
|
+
* came from.
|
|
67
|
+
*/
|
|
68
|
+
declare function springCompressionToStop(stiffness: number, mass: number, speed: number, sf?: number): {
|
|
69
|
+
readonly compression: number;
|
|
70
|
+
readonly worked: Worked;
|
|
71
|
+
};
|
|
72
|
+
//#endregion
|
|
73
|
+
export { SpringLaunch, SpringWork, springCompressionToStop, springLaunch, springWork, stiffnessForEnergyRatio };
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { calc, texSigFigs } from "../../core/worked.mjs";
|
|
2
|
+
import { sweep } from "../integral-sweep.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/physics/energy/spring.ts
|
|
5
|
+
/**
|
|
6
|
+
* The spring: the first force a student meets that is not constant, and the reason work became an
|
|
7
|
+
* integral.
|
|
8
|
+
*
|
|
9
|
+
* `W = Fd` is useless here, because there is no single `F`. The force grows as you stretch, so the
|
|
10
|
+
* honest answer is to add up `F dx` over strips, and that is `∫kx dx = ½kx²`. This module performs
|
|
11
|
+
* that integral SYMBOLICALLY through the shared integrator rather than quoting `½kx²` as a fact, so
|
|
12
|
+
* the derivation a lab prints is the mathematics the engine actually did. The same `sweep` that
|
|
13
|
+
* animates a moment of inertia animates this one, because the picture (strips accumulating under a
|
|
14
|
+
* graph) is identical.
|
|
15
|
+
*
|
|
16
|
+
* THE SIGN IS THE WHOLE TOPIC, and it is where every mark is lost. Two different forces act during
|
|
17
|
+
* the same stretch:
|
|
18
|
+
*
|
|
19
|
+
* - the SPRING pulls back towards the natural length: `F_spring = −kx`;
|
|
20
|
+
* - the AGENT doing the stretching pulls outwards: `F_agent = +kx`.
|
|
21
|
+
*
|
|
22
|
+
* They are equal and opposite, so their works are equal and opposite. Stretching a spring from rest
|
|
23
|
+
* to `x`, the agent does `+½kx²` and the spring does `−½kx²`. Releasing it, the two swap. A question
|
|
24
|
+
* asking for "the work done by the spring" and one asking for "the work done in stretching the
|
|
25
|
+
* spring" therefore differ by a minus sign and by nothing else, and `springWork` returns both rather
|
|
26
|
+
* than making the caller guess which one it meant.
|
|
27
|
+
*
|
|
28
|
+
* Pure: no React, no pixels.
|
|
29
|
+
*/
|
|
30
|
+
/**
|
|
31
|
+
* The work a spring does as its extension goes from `from` to `to`.
|
|
32
|
+
*
|
|
33
|
+
* Both extensions are measured from the NATURAL length and are signed, so a compression is negative.
|
|
34
|
+
* The squares mean the answer only ever depends on the two magnitudes, which is why `−3 cm to 0` and
|
|
35
|
+
* `+3 cm to 0` give the same release.
|
|
36
|
+
*
|
|
37
|
+
* Their Type-04 strategy sheet says to integrate rather than to reach for the formula, and to place
|
|
38
|
+
* the limits carefully with their signs. That is exactly what happens below.
|
|
39
|
+
*/
|
|
40
|
+
function springWork(stiffness, from, to, sf = 3) {
|
|
41
|
+
const s = sweep({
|
|
42
|
+
element: "-k*x",
|
|
43
|
+
variable: "x",
|
|
44
|
+
from: "xi",
|
|
45
|
+
to: "xf"
|
|
46
|
+
}, {
|
|
47
|
+
k: stiffness,
|
|
48
|
+
xi: from,
|
|
49
|
+
xf: to
|
|
50
|
+
});
|
|
51
|
+
const storedBefore = .5 * stiffness * from * from;
|
|
52
|
+
const storedAfter = .5 * stiffness * to * to;
|
|
53
|
+
const bySpring = s.total;
|
|
54
|
+
const worked = calc().step("F_{\\text{spring}} = -kx", "the force is not constant, so W = Fd does not apply. It grows in proportion to how far the spring is from its natural length").step("W = \\int_{x_i}^{x_f} F\\,dx = \\int_{x_i}^{x_f} -kx\\,dx = -\\tfrac{1}{2}k\\left[x^2\\right]_{x_i}^{x_f}", "add up F dx over strips. The area under the force-extension graph IS the work").step(`W_{\\text{spring}} = \\tfrac{1}{2}k\\left(x_i^2 - x_f^2\\right) = \\tfrac{1}{2} \\times ${texSigFigs(stiffness, sf)} \\times \\left(${texSigFigs(from, sf)}^2 - ${texSigFigs(to, sf)}^2\\right)`).step(`W_{\\text{spring}} = ${texSigFigs(bySpring, sf)}\\ \\mathrm{J}`, bySpring >= 0 ? "positive: the spring is returning towards its natural length, so it is giving energy back" : "negative: the spring is being taken further from its natural length, so it is absorbing energy").step(`W_{\\text{agent}} = -W_{\\text{spring}} = ${texSigFigs(-bySpring, sf)}\\ \\mathrm{J}`, "the puller and the spring exert equal and opposite forces over the same displacement, so their works differ only in sign").step(`E_{\\text{stored}}: ${texSigFigs(storedBefore, sf)} \\rightarrow ${texSigFigs(storedAfter, sf)}\\ \\mathrm{J}`, "and the change in the store is exactly minus the work the spring did").done(bySpring);
|
|
55
|
+
return {
|
|
56
|
+
bySpring,
|
|
57
|
+
byAgent: -bySpring,
|
|
58
|
+
storedBefore,
|
|
59
|
+
storedAfter,
|
|
60
|
+
sweep: s,
|
|
61
|
+
worked
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* The stiffness a second spring needs so that a stated stretch stores a stated multiple of the
|
|
66
|
+
* energy of the first.
|
|
67
|
+
*
|
|
68
|
+
* Their Example-14, and a genuinely good question, because it cannot be answered by substituting
|
|
69
|
+
* into `½kx²` once. It has to be answered by the RATIO, where everything shared cancels and what is
|
|
70
|
+
* left is `k ∝ W/x²`. Returning the ratio as well as the stiffness is deliberate: the ratio is the
|
|
71
|
+
* transferable part.
|
|
72
|
+
*/
|
|
73
|
+
function stiffnessForEnergyRatio(stiffness, energyRatio, extensionRatio, sf = 3) {
|
|
74
|
+
if (extensionRatio === 0) throw new Error("A second spring stretched by nothing stores nothing, so no stiffness satisfies the ratio.");
|
|
75
|
+
const ratio = energyRatio / (extensionRatio * extensionRatio);
|
|
76
|
+
const value = stiffness * ratio;
|
|
77
|
+
return {
|
|
78
|
+
stiffness: value,
|
|
79
|
+
ratio,
|
|
80
|
+
worked: calc().step("W = \\tfrac{1}{2}kx^2", "write it for both springs rather than evaluating either").step("\\frac{W_2}{W_1} = \\frac{k_2}{k_1}\\left(\\frac{x_2}{x_1}\\right)^2", "dividing kills the half and any shared quantity. What survives is the only thing the question is about").step(`\\frac{k_2}{k_1} = \\frac{W_2}{W_1} \\div \\left(\\frac{x_2}{x_1}\\right)^2 = ${texSigFigs(energyRatio, sf)} \\div ${texSigFigs(extensionRatio * extensionRatio, sf)} = ${texSigFigs(ratio, sf)}`).step(`k_2 = ${texSigFigs(ratio, sf)}k_1 = ${texSigFigs(value, sf)}\\ \\mathrm{N\\,m^{-1}}`, "halving the stretch while doubling the energy needs eight times the stiffness, because the extension enters squared").done(value)
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* A compressed spring released against a block: how fast the block leaves.
|
|
85
|
+
*
|
|
86
|
+
* Optional friction, because the pair of questions "smooth" then "now with friction" is the standard
|
|
87
|
+
* way this is examined, and the second one is only harder in that one term joins the ledger. The
|
|
88
|
+
* ledger is the lesson: what the spring stored either ends up as motion or ends up as heat, and
|
|
89
|
+
* there is nowhere else for it to go.
|
|
90
|
+
*/
|
|
91
|
+
function springLaunch(stiffness, compression, mass, frictionForce = 0, sf = 3) {
|
|
92
|
+
const storedEnergy = .5 * stiffness * compression * compression;
|
|
93
|
+
const lostToFriction = frictionForce * Math.abs(compression);
|
|
94
|
+
const kineticEnergy = storedEnergy - lostToFriction;
|
|
95
|
+
if (kineticEnergy < 0) throw new Error(`Friction would absorb ${lostToFriction.toPrecision(3)} J over that distance but the spring only stored ${storedEnergy.toPrecision(3)} J, so the block never reaches the natural length. It stops inside the spring.`);
|
|
96
|
+
const speed = Math.sqrt(2 * kineticEnergy / mass);
|
|
97
|
+
const w = calc().step("E_{\\text{stored}} = E_k + E_{\\text{lost}}", "the ledger. Everything the spring stored goes to motion or to heat, and nowhere else");
|
|
98
|
+
w.step(`E_{\\text{stored}} = \\tfrac{1}{2}kx^2 = \\tfrac{1}{2} \\times ${texSigFigs(stiffness, sf)} \\times ${texSigFigs(compression, sf)}^2 = ${texSigFigs(storedEnergy, sf)}\\ \\mathrm{J}`);
|
|
99
|
+
if (frictionForce !== 0) w.step(`E_{\\text{lost}} = fx = ${texSigFigs(frictionForce, sf)} \\times ${texSigFigs(Math.abs(compression), sf)} = ${texSigFigs(lostToFriction, sf)}\\ \\mathrm{J}`, "friction acts over the SAME distance the spring pushes through, which is the compression");
|
|
100
|
+
w.step(`E_k = ${texSigFigs(kineticEnergy, sf)}\\ \\mathrm{J}`, frictionForce === 0 ? "nothing is lost on a smooth surface" : "what is left over becomes motion");
|
|
101
|
+
w.step(`v = \\sqrt{\\frac{2E_k}{m}} = ${texSigFigs(speed, sf)}\\ \\mathrm{m\\,s^{-1}}`, "measured at the natural length, where the spring stops pushing");
|
|
102
|
+
return {
|
|
103
|
+
speed,
|
|
104
|
+
storedEnergy,
|
|
105
|
+
lostToFriction,
|
|
106
|
+
kineticEnergy,
|
|
107
|
+
worked: w.done(speed)
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* How far a moving block compresses a spring before it stops.
|
|
112
|
+
*
|
|
113
|
+
* The launch run backwards, and the standard way a work-energy question is dressed up. The answer
|
|
114
|
+
* comes out as a magnitude and is then given a negative sign, because the spring was compressed:
|
|
115
|
+
* that last move is the one worth watching, since the square root cannot know which way the block
|
|
116
|
+
* came from.
|
|
117
|
+
*/
|
|
118
|
+
function springCompressionToStop(stiffness, mass, speed, sf = 3) {
|
|
119
|
+
const kinetic = .5 * mass * speed * speed;
|
|
120
|
+
const magnitude = Math.sqrt(2 * kinetic / stiffness);
|
|
121
|
+
const worked = calc().step("\\Delta E_k = W_{\\text{spring}}", "the work-energy theorem. The spring is the only thing doing work, so it must absorb all the motion").step(`0 - \\tfrac{1}{2}mv^2 = -\\tfrac{1}{2}kx^2 \\Rightarrow x^2 = \\frac{mv^2}{k} = \\frac{${texSigFigs(mass, sf)} \\times ${texSigFigs(speed, sf)}^2}{${texSigFigs(stiffness, sf)}}`).step(`x = ${texSigFigs(-magnitude, sf)}\\ \\mathrm{m}`, "the square root gives a size only. The negative sign is put back by hand, because the spring was COMPRESSED and extensions are measured as positive").done(-magnitude);
|
|
122
|
+
return {
|
|
123
|
+
compression: -magnitude,
|
|
124
|
+
worked
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
//#endregion
|
|
129
|
+
export { springCompressionToStop, springLaunch, springWork, stiffnessForEnergyRatio };
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { Worked } from "../../core/worked.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/physics/energy/store.d.ts
|
|
4
|
+
/** `Ek = ½mv²`. Always positive: the speed is squared, so the direction of travel cannot enter. */
|
|
5
|
+
declare function kineticEnergy(mass: number, speed: number, sf?: number): Worked;
|
|
6
|
+
/**
|
|
7
|
+
* `Ek = p²/2m`, kinetic energy straight from momentum.
|
|
8
|
+
*
|
|
9
|
+
* Derived rather than asserted, because the derivation is two lines and the alternative is a fourth
|
|
10
|
+
* formula to remember. It matters beyond exam convenience: it is the form that says a heavy slow
|
|
11
|
+
* body and a light fast one can carry the same momentum while carrying wildly different energies,
|
|
12
|
+
* which is the whole reason a bullet and a truck are dangerous in different ways.
|
|
13
|
+
*/
|
|
14
|
+
declare function kineticFromMomentum(momentum: number, mass: number, sf?: number): Worked;
|
|
15
|
+
/** The momentum a body of known kinetic energy carries: `p = √(2mEk)`. */
|
|
16
|
+
declare function momentumFromKinetic(kinetic: number, mass: number, sf?: number): Worked;
|
|
17
|
+
/** The speed a stated kinetic energy corresponds to: `v = √(2Ek/m)`. */
|
|
18
|
+
declare function speedFromKinetic(kinetic: number, mass: number, sf?: number): Worked;
|
|
19
|
+
/**
|
|
20
|
+
* Kinetic energy from a velocity given as components, in any number of dimensions.
|
|
21
|
+
*
|
|
22
|
+
* The useful lesson is in the middle step: you square the MAGNITUDE, which means squaring each
|
|
23
|
+
* component and adding, never squaring the components separately and calling each one an energy.
|
|
24
|
+
* Energy has no components to be resolved into.
|
|
25
|
+
*/
|
|
26
|
+
declare function kineticFromVelocity(mass: number, velocity: readonly number[], sf?: number): Worked;
|
|
27
|
+
interface PotentialResult {
|
|
28
|
+
readonly value: number;
|
|
29
|
+
/** Height above the chosen reference, which is what actually went into the formula. */
|
|
30
|
+
readonly heightAboveReference: number;
|
|
31
|
+
readonly worked: Worked;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* `Ep = mgh`, with the reference level stated out loud.
|
|
35
|
+
*
|
|
36
|
+
* Both heights are measured from the same arbitrary origin, and `h` in the formula is their
|
|
37
|
+
* DIFFERENCE. Making the caller name the reference is the point: a body on the floor has zero
|
|
38
|
+
* potential energy relative to the floor, `+mgh` relative to the basement, and `−mgh` relative to
|
|
39
|
+
* the table, and all three are correct at once. Only the change between two levels is ever measured
|
|
40
|
+
* by an experiment, which is why the arbitrariness never causes trouble.
|
|
41
|
+
*/
|
|
42
|
+
declare function gravitationalPE(mass: number, height: number, referenceLevel?: number, g?: number, sf?: number): PotentialResult;
|
|
43
|
+
/**
|
|
44
|
+
* Work done against gravity between two radii of a spherical body: `W = GMm(1/r_a − 1/r_b)`.
|
|
45
|
+
*
|
|
46
|
+
* The far-field version, for when `mgh` will not do because `g` itself has changed over the journey.
|
|
47
|
+
* The final step shows the two collapsing into one another for a small rise, which is the connection
|
|
48
|
+
* a syllabus asserts and rarely demonstrates: `mgh` is not a different law, it is this law with the
|
|
49
|
+
* denominator barely moving.
|
|
50
|
+
*/
|
|
51
|
+
declare function gravitationalWork(centralMass: number, mass: number, fromRadius: number, toRadius: number, G?: number, sf?: number): Worked;
|
|
52
|
+
/**
|
|
53
|
+
* `Ep = ½kx²`, the energy stored in a spring stretched or compressed by `x` from its natural length.
|
|
54
|
+
*
|
|
55
|
+
* `x` is squared, so stretching and compressing by the same amount store the same energy. That is
|
|
56
|
+
* worth stating because a compression is usually written as a negative extension and a learner who
|
|
57
|
+
* carries the minus sign into an energy gets a negative store, which is impossible.
|
|
58
|
+
*
|
|
59
|
+
* The derivation lives in `spring.ts`, where the integral is actually performed rather than quoted.
|
|
60
|
+
*/
|
|
61
|
+
declare function elasticPE(stiffness: number, extension: number, sf?: number): Worked;
|
|
62
|
+
//#endregion
|
|
63
|
+
export { PotentialResult, elasticPE, gravitationalPE, gravitationalWork, kineticEnergy, kineticFromMomentum, kineticFromVelocity, momentumFromKinetic, speedFromKinetic };
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { GRAVITATIONAL_CONSTANT } from "../../core/constants.mjs";
|
|
2
|
+
import { calc, texSigFigs } from "../../core/worked.mjs";
|
|
3
|
+
import { G_EARTH } from "../kinematics/free-fall.mjs";
|
|
4
|
+
|
|
5
|
+
//#region src/physics/energy/store.ts
|
|
6
|
+
/**
|
|
7
|
+
* The energy stores, and the conversions between the ways of naming the same one.
|
|
8
|
+
*
|
|
9
|
+
* A body in motion has one kinetic energy. It can be written from the speed, from the momentum, or
|
|
10
|
+
* from the components of a velocity vector, and a question will hand you whichever of those is least
|
|
11
|
+
* convenient. These are not three quantities; they are three doors into one room, and a learner who
|
|
12
|
+
* has only memorised `½mv²` will stall on a momentum-first question that is genuinely no harder.
|
|
13
|
+
*
|
|
14
|
+
* THE SUBTLETY THAT ACTUALLY COSTS MARKS is not here in the kinetic energy at all. It is that
|
|
15
|
+
* gravitational potential energy has NO ABSOLUTE VALUE. It is always measured from a level you
|
|
16
|
+
* chose, and a body below that level has a NEGATIVE potential energy, which is not a mistake and not
|
|
17
|
+
* a sign error. `gravitationalPE` therefore takes the reference level explicitly instead of quietly
|
|
18
|
+
* assuming the ground, because the assumption is exactly the thing being taught.
|
|
19
|
+
*
|
|
20
|
+
* Pure: no React, no pixels.
|
|
21
|
+
*/
|
|
22
|
+
/** `Ek = ½mv²`. Always positive: the speed is squared, so the direction of travel cannot enter. */
|
|
23
|
+
function kineticEnergy(mass, speed, sf = 3) {
|
|
24
|
+
const value = .5 * mass * speed * speed;
|
|
25
|
+
return calc().step("E_k = \\tfrac{1}{2}mv^2").step(`E_k = \\tfrac{1}{2} \\times ${texSigFigs(mass, sf)} \\times ${texSigFigs(speed, sf)}^2 = ${texSigFigs(value, sf)}\\ \\mathrm{J}`, "v is squared, so a body moving backwards has the same kinetic energy as one moving forwards. Kinetic energy is never negative").done(value);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* `Ek = p²/2m`, kinetic energy straight from momentum.
|
|
29
|
+
*
|
|
30
|
+
* Derived rather than asserted, because the derivation is two lines and the alternative is a fourth
|
|
31
|
+
* formula to remember. It matters beyond exam convenience: it is the form that says a heavy slow
|
|
32
|
+
* body and a light fast one can carry the same momentum while carrying wildly different energies,
|
|
33
|
+
* which is the whole reason a bullet and a truck are dangerous in different ways.
|
|
34
|
+
*/
|
|
35
|
+
function kineticFromMomentum(momentum, mass, sf = 3) {
|
|
36
|
+
const value = momentum * momentum / (2 * mass);
|
|
37
|
+
return calc().step("p = mv \\Rightarrow v = \\frac{p}{m}", "start from the definition of momentum and make v the subject").step("E_k = \\tfrac{1}{2}mv^2 = \\tfrac{1}{2}m\\left(\\frac{p}{m}\\right)^2 = \\frac{p^2}{2m}", "substitute and let one factor of m cancel. This is not a new formula, it is the old one in different clothes").step(`E_k = \\frac{${texSigFigs(momentum, sf)}^2}{2 \\times ${texSigFigs(mass, sf)}} = ${texSigFigs(value, sf)}\\ \\mathrm{J}`).done(value);
|
|
38
|
+
}
|
|
39
|
+
/** The momentum a body of known kinetic energy carries: `p = √(2mEk)`. */
|
|
40
|
+
function momentumFromKinetic(kinetic, mass, sf = 3) {
|
|
41
|
+
const value = Math.sqrt(2 * mass * kinetic);
|
|
42
|
+
return calc().step("E_k = \\frac{p^2}{2m} \\Rightarrow p = \\sqrt{2mE_k}").step(`p = \\sqrt{2 \\times ${texSigFigs(mass, sf)} \\times ${texSigFigs(kinetic, sf)}} = ${texSigFigs(value, sf)}\\ \\mathrm{kg\\,m\\,s^{-1}}`).done(value);
|
|
43
|
+
}
|
|
44
|
+
/** The speed a stated kinetic energy corresponds to: `v = √(2Ek/m)`. */
|
|
45
|
+
function speedFromKinetic(kinetic, mass, sf = 3) {
|
|
46
|
+
if (kinetic < 0) throw new Error("Kinetic energy cannot be negative, so no speed corresponds to it.");
|
|
47
|
+
const value = Math.sqrt(2 * kinetic / mass);
|
|
48
|
+
return calc().step("E_k = \\tfrac{1}{2}mv^2 \\Rightarrow v = \\sqrt{\\frac{2E_k}{m}}").step(`v = \\sqrt{\\frac{2 \\times ${texSigFigs(kinetic, sf)}}{${texSigFigs(mass, sf)}}} = ${texSigFigs(value, sf)}\\ \\mathrm{m\\,s^{-1}}`, "the speed only. Kinetic energy is a scalar and cannot tell you which way the body is going").done(value);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Kinetic energy from a velocity given as components, in any number of dimensions.
|
|
52
|
+
*
|
|
53
|
+
* The useful lesson is in the middle step: you square the MAGNITUDE, which means squaring each
|
|
54
|
+
* component and adding, never squaring the components separately and calling each one an energy.
|
|
55
|
+
* Energy has no components to be resolved into.
|
|
56
|
+
*/
|
|
57
|
+
function kineticFromVelocity(mass, velocity, sf = 3) {
|
|
58
|
+
const squared = velocity.reduce((sum, c) => sum + c * c, 0);
|
|
59
|
+
const value = .5 * mass * squared;
|
|
60
|
+
return calc().step("v^2 = v_x^2 + v_y^2 + v_z^2", "square each component and add. This gives the square of the SPEED, which is the scalar the energy needs").step(`v^2 = ${velocity.map((c) => `${texSigFigs(c, sf)}^2`).join(" + ")} = ${texSigFigs(squared, sf)}`).step(`E_k = \\tfrac{1}{2} \\times ${texSigFigs(mass, sf)} \\times ${texSigFigs(squared, sf)} = ${texSigFigs(value, sf)}\\ \\mathrm{J}`, "one number, with no direction. There is no such thing as the x-component of an energy").done(value);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* `Ep = mgh`, with the reference level stated out loud.
|
|
64
|
+
*
|
|
65
|
+
* Both heights are measured from the same arbitrary origin, and `h` in the formula is their
|
|
66
|
+
* DIFFERENCE. Making the caller name the reference is the point: a body on the floor has zero
|
|
67
|
+
* potential energy relative to the floor, `+mgh` relative to the basement, and `−mgh` relative to
|
|
68
|
+
* the table, and all three are correct at once. Only the change between two levels is ever measured
|
|
69
|
+
* by an experiment, which is why the arbitrariness never causes trouble.
|
|
70
|
+
*/
|
|
71
|
+
function gravitationalPE(mass, height, referenceLevel = 0, g = G_EARTH, sf = 3) {
|
|
72
|
+
const h = height - referenceLevel;
|
|
73
|
+
const value = mass * g * h;
|
|
74
|
+
return {
|
|
75
|
+
value,
|
|
76
|
+
heightAboveReference: h,
|
|
77
|
+
worked: calc().step("E_p = mgh", "h is measured from a level YOU choose. The choice is free, and different choices give different values that are all correct").step(`h = ${texSigFigs(height, sf)} - ${texSigFigs(referenceLevel, sf)} = ${texSigFigs(h, sf)}\\ \\mathrm{m}`, "height above the chosen reference").step(`E_p = ${texSigFigs(mass, sf)} \\times ${texSigFigs(g, sf)} \\times ${texSigFigs(h, sf)} = ${texSigFigs(value, sf)}\\ \\mathrm{J}`, h < 0 ? "negative, because the body sits BELOW the reference. This is a correct answer, not a sign slip" : "positive: the body is above the reference level").step("\\Delta E_p = mg\\,\\Delta h", "the reference cancels out of any CHANGE, which is why the arbitrary choice never affects a physical answer").done(value)
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Work done against gravity between two radii of a spherical body: `W = GMm(1/r_a − 1/r_b)`.
|
|
82
|
+
*
|
|
83
|
+
* The far-field version, for when `mgh` will not do because `g` itself has changed over the journey.
|
|
84
|
+
* The final step shows the two collapsing into one another for a small rise, which is the connection
|
|
85
|
+
* a syllabus asserts and rarely demonstrates: `mgh` is not a different law, it is this law with the
|
|
86
|
+
* denominator barely moving.
|
|
87
|
+
*/
|
|
88
|
+
function gravitationalWork(centralMass, mass, fromRadius, toRadius, G = GRAVITATIONAL_CONSTANT, sf = 4) {
|
|
89
|
+
if (fromRadius <= 0 || toRadius <= 0) throw new Error("Radii are measured from the centre of the attracting body and must be positive.");
|
|
90
|
+
const value = G * centralMass * mass * (1 / fromRadius - 1 / toRadius);
|
|
91
|
+
return calc().step("F = \\frac{GMm}{r^2}", "the force weakens with distance, so a single \"mg\" is no longer good enough over the journey").step("W = \\int_{r_a}^{r_b} \\frac{GMm}{r^2}\\,dr = GMm\\left(\\frac{1}{r_a} - \\frac{1}{r_b}\\right)", "integrate, because the force is not constant. The 1/r squared integrates to minus 1/r").step(`W = ${texSigFigs(G, 4)} \\times ${texSigFigs(centralMass, sf)} \\times ${texSigFigs(mass, sf)} \\left(\\frac{1}{${texSigFigs(fromRadius, sf)}} - \\frac{1}{${texSigFigs(toRadius, sf)}}\\right)`).step(`W = ${texSigFigs(value, sf)}\\ \\mathrm{J}`, "work done BY an outside agent moving the mass outwards. Gravity did the same amount with the opposite sign").step("r_b = r_a + h,\\ h \\ll r_a \\Rightarrow W \\approx \\frac{GMm}{r_a^2}h = mgh", "for a small rise the two radii barely differ, and this collapses into mgh. That is where mgh comes from").done(value);
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* `Ep = ½kx²`, the energy stored in a spring stretched or compressed by `x` from its natural length.
|
|
95
|
+
*
|
|
96
|
+
* `x` is squared, so stretching and compressing by the same amount store the same energy. That is
|
|
97
|
+
* worth stating because a compression is usually written as a negative extension and a learner who
|
|
98
|
+
* carries the minus sign into an energy gets a negative store, which is impossible.
|
|
99
|
+
*
|
|
100
|
+
* The derivation lives in `spring.ts`, where the integral is actually performed rather than quoted.
|
|
101
|
+
*/
|
|
102
|
+
function elasticPE(stiffness, extension, sf = 3) {
|
|
103
|
+
const value = .5 * stiffness * extension * extension;
|
|
104
|
+
return calc().step("E_p = \\tfrac{1}{2}kx^2", "x is measured from the NATURAL length, not from wherever the spring happens to be sitting").step(`E_p = \\tfrac{1}{2} \\times ${texSigFigs(stiffness, sf)} \\times ${texSigFigs(extension, sf)}^2 = ${texSigFigs(value, sf)}\\ \\mathrm{J}`, "x is squared, so a compression of 3 cm stores exactly what a stretch of 3 cm stores. The store is never negative").done(value);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
//#endregion
|
|
108
|
+
export { elasticPE, gravitationalPE, gravitationalWork, kineticEnergy, kineticFromMomentum, kineticFromVelocity, momentumFromKinetic, speedFromKinetic };
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { Worked } from "../../core/worked.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/physics/energy/theorem.d.ts
|
|
4
|
+
interface WorkEnergyResult {
|
|
5
|
+
readonly initialKinetic: number;
|
|
6
|
+
readonly finalKinetic: number;
|
|
7
|
+
/** `ΔEk`, which IS the net work done. Negative when the body slowed. */
|
|
8
|
+
readonly netWork: number;
|
|
9
|
+
readonly worked: Worked;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* The theorem itself: the net work done on a body equals its change in kinetic energy.
|
|
13
|
+
*
|
|
14
|
+
* Deliberately blunt and general, taking only the two speeds. A body brought to rest from 30 m/s has
|
|
15
|
+
* had a definite amount of work done against it and it does not matter in the slightest whether that
|
|
16
|
+
* was a brake, a wall, a parachute, or a hill.
|
|
17
|
+
*/
|
|
18
|
+
declare function workEnergy(mass: number, initialSpeed: number, finalSpeed: number, sf?: number): WorkEnergyResult;
|
|
19
|
+
/** The work that must be done against resistance to stop a moving body: `½mu²`. */
|
|
20
|
+
declare const workToStop: (mass: number, speed: number, sf?: number) => Worked;
|
|
21
|
+
interface PenetrationResult {
|
|
22
|
+
/** The average force resisting the penetration, newtons. */
|
|
23
|
+
readonly resistance: number;
|
|
24
|
+
/** Energy arriving at the surface, joules. */
|
|
25
|
+
readonly arriving: number;
|
|
26
|
+
/** The extra work gravity did during the penetration itself. Zero for a horizontal strike. */
|
|
27
|
+
readonly gravityDuringPenetration: number;
|
|
28
|
+
readonly worked: Worked;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* A mass DROPPED onto a nail or a stake: the average resistance of the material.
|
|
32
|
+
*
|
|
33
|
+
* `mg(h + x) = Fx`. The `+ x` is the term this function exists to make unmissable: gravity does not
|
|
34
|
+
* switch off when the hammer touches the nail, and it keeps pulling for the whole penetration too.
|
|
35
|
+
* For a 5 m drop into 10 cm the correction is 2 per cent, which is small enough to look like a
|
|
36
|
+
* rounding difference and large enough to fail a mark scheme.
|
|
37
|
+
*
|
|
38
|
+
* `dropHeight` is the fall BEFORE contact. `penetration` is how far in it went.
|
|
39
|
+
*/
|
|
40
|
+
declare function resistanceFromDrop(mass: number, dropHeight: number, penetration: number, g?: number, sf?: number): PenetrationResult;
|
|
41
|
+
/**
|
|
42
|
+
* A mass driven horizontally into a material at a known speed: resistance from kinetic energy alone.
|
|
43
|
+
*
|
|
44
|
+
* The simpler cousin, and simpler for a reason worth saying: struck sideways, gravity is
|
|
45
|
+
* perpendicular to the motion, so it does no work and the `+ x` term is genuinely absent. Not
|
|
46
|
+
* because the problem is easier, but because `cos 90° = 0`.
|
|
47
|
+
*/
|
|
48
|
+
declare function resistanceFromStrike(mass: number, speed: number, penetration: number, sf?: number): PenetrationResult;
|
|
49
|
+
/**
|
|
50
|
+
* The speed needed to drive a known distance into a material of known resistance.
|
|
51
|
+
*
|
|
52
|
+
* `resistanceFromStrike` rearranged, and the form a question takes when it wants the hammer's speed
|
|
53
|
+
* rather than the wood's toughness.
|
|
54
|
+
*/
|
|
55
|
+
declare function speedToPenetrate(mass: number, resistance: number, penetration: number, sf?: number): Worked;
|
|
56
|
+
/**
|
|
57
|
+
* How far a body travels before a constant resisting force stops it.
|
|
58
|
+
*
|
|
59
|
+
* The braking-distance question, and the place to notice that the distance goes as `v²`: doubling
|
|
60
|
+
* the speed quadruples the stopping distance. That single fact is the entire physics content of
|
|
61
|
+
* every road safety campaign.
|
|
62
|
+
*/
|
|
63
|
+
declare function stoppingDistance(mass: number, speed: number, resistance: number, sf?: number): Worked;
|
|
64
|
+
//#endregion
|
|
65
|
+
export { PenetrationResult, WorkEnergyResult, resistanceFromDrop, resistanceFromStrike, speedToPenetrate, stoppingDistance, workEnergy, workToStop };
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { calc, texSigFigs } from "../../core/worked.mjs";
|
|
2
|
+
import { G_EARTH } from "../kinematics/free-fall.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/physics/energy/theorem.ts
|
|
5
|
+
/**
|
|
6
|
+
* The work-energy theorem, and the questions that are only tractable through it.
|
|
7
|
+
*
|
|
8
|
+
* `W_net = ΔEk`. Four symbols, and it replaces a whole class of problems that are painful through
|
|
9
|
+
* forces and accelerations. A nail driven into wood decelerates enormously over a few millimetres
|
|
10
|
+
* and nobody wants to find that acceleration; what they want is that the kinetic energy arriving had
|
|
11
|
+
* to go somewhere, and the only place available was work done against the resisting force.
|
|
12
|
+
*
|
|
13
|
+
* TWO THINGS DECIDE WHETHER A SOLUTION IS RIGHT HERE, and neither is the arithmetic.
|
|
14
|
+
*
|
|
15
|
+
* 1. It is the NET work. Every force doing work goes in the ledger, with its sign. A solution that
|
|
16
|
+
* counts the resistance and forgets that gravity kept pulling during the penetration is out by
|
|
17
|
+
* a term, and for a hammer falling 5 m into 10 cm of wood that term is small but for a short
|
|
18
|
+
* drop it is not.
|
|
19
|
+
* 2. The DISTANCE for each force is the distance THAT force acted over, and they are not always
|
|
20
|
+
* the same distance. Gravity acts over the drop AND the penetration; the resistance acts only
|
|
21
|
+
* over the penetration. `mg(h + x) = Fx` is that observation written down, and the `+ x` is the
|
|
22
|
+
* single most commonly dropped term in this topic.
|
|
23
|
+
*
|
|
24
|
+
* Pure: no React, no pixels.
|
|
25
|
+
*/
|
|
26
|
+
/**
|
|
27
|
+
* The theorem itself: the net work done on a body equals its change in kinetic energy.
|
|
28
|
+
*
|
|
29
|
+
* Deliberately blunt and general, taking only the two speeds. A body brought to rest from 30 m/s has
|
|
30
|
+
* had a definite amount of work done against it and it does not matter in the slightest whether that
|
|
31
|
+
* was a brake, a wall, a parachute, or a hill.
|
|
32
|
+
*/
|
|
33
|
+
function workEnergy(mass, initialSpeed, finalSpeed, sf = 3) {
|
|
34
|
+
const initialKinetic = .5 * mass * initialSpeed * initialSpeed;
|
|
35
|
+
const finalKinetic = .5 * mass * finalSpeed * finalSpeed;
|
|
36
|
+
const netWork = finalKinetic - initialKinetic;
|
|
37
|
+
return {
|
|
38
|
+
initialKinetic,
|
|
39
|
+
finalKinetic,
|
|
40
|
+
netWork,
|
|
41
|
+
worked: calc().step("W_{\\text{net}} = \\Delta E_k = \\tfrac{1}{2}mv^2 - \\tfrac{1}{2}mu^2", "the net work done on a body is its gain in kinetic energy. What did the work is irrelevant").step(`E_k \\text{ initial} = \\tfrac{1}{2} \\times ${texSigFigs(mass, sf)} \\times ${texSigFigs(initialSpeed, sf)}^2 = ${texSigFigs(initialKinetic, sf)}\\ \\mathrm{J}`).step(`E_k \\text{ final} = \\tfrac{1}{2} \\times ${texSigFigs(mass, sf)} \\times ${texSigFigs(finalSpeed, sf)}^2 = ${texSigFigs(finalKinetic, sf)}\\ \\mathrm{J}`).step(`W_{\\text{net}} = ${texSigFigs(netWork, sf)}\\ \\mathrm{J}`, netWork < 0 ? "negative, because the body slowed. The work done AGAINST the resisting force is the same size, positive" : netWork > 0 ? "positive: energy was fed in and the body sped up" : "zero: the speed is unchanged, so however much force acted, the net work was nothing").done(netWork)
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
/** The work that must be done against resistance to stop a moving body: `½mu²`. */
|
|
45
|
+
const workToStop = (mass, speed, sf = 3) => {
|
|
46
|
+
const value = .5 * mass * speed * speed;
|
|
47
|
+
return calc().step("W = \\Delta E_k = 0 - \\tfrac{1}{2}mu^2", "the body ends at rest, so all of its kinetic energy must be removed").step(`W_{\\text{against}} = \\tfrac{1}{2} \\times ${texSigFigs(mass, sf)} \\times ${texSigFigs(speed, sf)}^2 = ${texSigFigs(value, sf)}\\ \\mathrm{J}`, "quoted positive: it is the work done against the resisting force, not the work done on the body").done(value);
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* A mass DROPPED onto a nail or a stake: the average resistance of the material.
|
|
51
|
+
*
|
|
52
|
+
* `mg(h + x) = Fx`. The `+ x` is the term this function exists to make unmissable: gravity does not
|
|
53
|
+
* switch off when the hammer touches the nail, and it keeps pulling for the whole penetration too.
|
|
54
|
+
* For a 5 m drop into 10 cm the correction is 2 per cent, which is small enough to look like a
|
|
55
|
+
* rounding difference and large enough to fail a mark scheme.
|
|
56
|
+
*
|
|
57
|
+
* `dropHeight` is the fall BEFORE contact. `penetration` is how far in it went.
|
|
58
|
+
*/
|
|
59
|
+
function resistanceFromDrop(mass, dropHeight, penetration, g = G_EARTH, sf = 3) {
|
|
60
|
+
if (penetration <= 0) throw new Error("Nothing penetrated, so the material absorbed the energy over no distance and the force is unbounded.");
|
|
61
|
+
const arriving = mass * g * dropHeight;
|
|
62
|
+
const gravityDuringPenetration = mass * g * penetration;
|
|
63
|
+
const resistance = (arriving + gravityDuringPenetration) / penetration;
|
|
64
|
+
return {
|
|
65
|
+
resistance,
|
|
66
|
+
arriving,
|
|
67
|
+
gravityDuringPenetration,
|
|
68
|
+
worked: calc().step("W_{\\text{gravity}} = W_{\\text{resistance}}", "the hammer starts at rest and finishes at rest, so the net work over the whole journey is zero").step("mg(h + x) = Fx", "gravity acts over the drop AND the penetration, so its distance is h + x. The resistance only acts over x").step(`F = \\frac{mg(h + x)}{x} = \\frac{${texSigFigs(mass, sf)} \\times ${texSigFigs(g, sf)} \\times (${texSigFigs(dropHeight, sf)} + ${texSigFigs(penetration, sf)})}{${texSigFigs(penetration, sf)}}`).step(`F = ${texSigFigs(resistance, sf)}\\ \\mathrm{N}`, "an average. The real force rises from nothing as the material compresses, and this is the flat force that would do the same total work").step(`\\text{dropping the } +x \\text{ term would give } ${texSigFigs(arriving / penetration, sf)}\\ \\mathrm{N}`, "close enough to look right and wrong enough to be marked wrong").done(resistance)
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* A mass driven horizontally into a material at a known speed: resistance from kinetic energy alone.
|
|
73
|
+
*
|
|
74
|
+
* The simpler cousin, and simpler for a reason worth saying: struck sideways, gravity is
|
|
75
|
+
* perpendicular to the motion, so it does no work and the `+ x` term is genuinely absent. Not
|
|
76
|
+
* because the problem is easier, but because `cos 90° = 0`.
|
|
77
|
+
*/
|
|
78
|
+
function resistanceFromStrike(mass, speed, penetration, sf = 3) {
|
|
79
|
+
if (penetration <= 0) throw new Error("Nothing penetrated, so the material absorbed the energy over no distance and the force is unbounded.");
|
|
80
|
+
const arriving = .5 * mass * speed * speed;
|
|
81
|
+
const resistance = arriving / penetration;
|
|
82
|
+
return {
|
|
83
|
+
resistance,
|
|
84
|
+
arriving,
|
|
85
|
+
gravityDuringPenetration: 0,
|
|
86
|
+
worked: calc().step("\\tfrac{1}{2}mv^2 = Fx", "struck horizontally, gravity is perpendicular to the motion and does no work. Only the kinetic energy has to be absorbed").step(`F = \\frac{\\tfrac{1}{2}mv^2}{x} = \\frac{\\tfrac{1}{2} \\times ${texSigFigs(mass, sf)} \\times ${texSigFigs(speed, sf)}^2}{${texSigFigs(penetration, sf)}}`).step(`F = ${texSigFigs(resistance, sf)}\\ \\mathrm{N}`).done(resistance)
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* The speed needed to drive a known distance into a material of known resistance.
|
|
91
|
+
*
|
|
92
|
+
* `resistanceFromStrike` rearranged, and the form a question takes when it wants the hammer's speed
|
|
93
|
+
* rather than the wood's toughness.
|
|
94
|
+
*/
|
|
95
|
+
function speedToPenetrate(mass, resistance, penetration, sf = 3) {
|
|
96
|
+
const value = Math.sqrt(2 * resistance * penetration / mass);
|
|
97
|
+
return calc().step("\\tfrac{1}{2}mv^2 = Fx \\Rightarrow v = \\sqrt{\\frac{2Fx}{m}}").step(`v = \\sqrt{\\frac{2 \\times ${texSigFigs(resistance, sf)} \\times ${texSigFigs(penetration, sf)}}{${texSigFigs(mass, sf)}}} = ${texSigFigs(value, sf)}\\ \\mathrm{m\\,s^{-1}}`).done(value);
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* How far a body travels before a constant resisting force stops it.
|
|
101
|
+
*
|
|
102
|
+
* The braking-distance question, and the place to notice that the distance goes as `v²`: doubling
|
|
103
|
+
* the speed quadruples the stopping distance. That single fact is the entire physics content of
|
|
104
|
+
* every road safety campaign.
|
|
105
|
+
*/
|
|
106
|
+
function stoppingDistance(mass, speed, resistance, sf = 3) {
|
|
107
|
+
if (resistance <= 0) throw new Error("With no resisting force the body never stops.");
|
|
108
|
+
const value = .5 * mass * speed * speed / resistance;
|
|
109
|
+
return calc().step("\\tfrac{1}{2}mv^2 = Fd \\Rightarrow d = \\frac{mv^2}{2F}").step(`d = \\frac{${texSigFigs(mass, sf)} \\times ${texSigFigs(speed, sf)}^2}{2 \\times ${texSigFigs(resistance, sf)}} = ${texSigFigs(value, sf)}\\ \\mathrm{m}`).step("d \\propto v^2", "twice the speed is four times the distance, because the energy to be removed went up fourfold while the force did not").done(value);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
//#endregion
|
|
113
|
+
export { resistanceFromDrop, resistanceFromStrike, speedToPenetrate, stoppingDistance, workEnergy, workToStop };
|