@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,164 @@
|
|
|
1
|
+
import { Worked } from "../../core/worked.mjs";
|
|
2
|
+
import { Node } from "../../math/ast.mjs";
|
|
3
|
+
import { Sweep } from "../integral-sweep.mjs";
|
|
4
|
+
|
|
5
|
+
//#region src/physics/rotation/inertia.d.ts
|
|
6
|
+
/**
|
|
7
|
+
* How to DRAW the body and the element sweeping through it.
|
|
8
|
+
*
|
|
9
|
+
* This lives in the kernel rather than in each lab on purpose. The element's shape is not
|
|
10
|
+
* decoration, it IS the derivation: the disc is cut into rings because a ring is the set of points
|
|
11
|
+
* at one distance from the axis, and the sphere is cut into discs because a disc is a thing whose
|
|
12
|
+
* moment of inertia we already know. A renderer that invented its own picture could easily draw
|
|
13
|
+
* strips across a disc, which would look fine and would be a different integral.
|
|
14
|
+
*
|
|
15
|
+
* Kept as a small closed vocabulary rather than as drawing instructions, so the kernel stays free
|
|
16
|
+
* of pixels and a renderer can draw a band however suits its scene.
|
|
17
|
+
*/
|
|
18
|
+
interface ShapeGeometry {
|
|
19
|
+
/** The body's outline. */
|
|
20
|
+
readonly body: 'rod' | 'disc' | 'ring' | 'sphere' | 'shell' | 'plate';
|
|
21
|
+
/** The shape of one element of the integral. */
|
|
22
|
+
readonly element: 'strip' | 'annulus' | 'slice' | 'band' | 'whole-ring';
|
|
23
|
+
/** Which way the element travels as the variable runs from `from` to `to`. */
|
|
24
|
+
readonly sweep: 'along-length' | 'outward-from-axis' | 'along-axis' | 'by-mass';
|
|
25
|
+
/**
|
|
26
|
+
* Which symbol sets the body's overall size, so a renderer can scale the scene to fit without
|
|
27
|
+
* being told separately.
|
|
28
|
+
*/
|
|
29
|
+
readonly extent: string;
|
|
30
|
+
}
|
|
31
|
+
/** A rigid body declared by how its mass is spread, not by its answer. */
|
|
32
|
+
interface ShapeSpec {
|
|
33
|
+
readonly id: string;
|
|
34
|
+
/** "uniform rod", for a lesson heading. */
|
|
35
|
+
readonly name: string;
|
|
36
|
+
/** Which axis this is about. Half the exam marks in this topic are about the axis. */
|
|
37
|
+
readonly axis: string;
|
|
38
|
+
/** Each symbol and what it means, so a lab can label its controls. */
|
|
39
|
+
readonly symbols: Readonly<Record<string, string>>;
|
|
40
|
+
/** The variable integrated over. */
|
|
41
|
+
readonly variable: string;
|
|
42
|
+
/**
|
|
43
|
+
* `dI`, the contribution of one element, as an expression in `variable`. EXPANDED: see the note
|
|
44
|
+
* at the top of the file about what the integrator will and will not accept.
|
|
45
|
+
*/
|
|
46
|
+
readonly element: string;
|
|
47
|
+
/** Where the element expression came from, in words, for the derivation. */
|
|
48
|
+
readonly elementNote: string;
|
|
49
|
+
/** Integration limits, as expressions in the symbols. */
|
|
50
|
+
readonly from: string;
|
|
51
|
+
readonly to: string;
|
|
52
|
+
/** The standard result. Used to CHECK the integral, never to replace it. */
|
|
53
|
+
readonly closedForm: string;
|
|
54
|
+
/** How the standard result is usually written, in LaTeX. */
|
|
55
|
+
readonly closedFormTex: string;
|
|
56
|
+
/** What a lab draws, and how the element moves through it. */
|
|
57
|
+
readonly geometry: ShapeGeometry;
|
|
58
|
+
}
|
|
59
|
+
interface InertiaResult {
|
|
60
|
+
readonly shape: ShapeSpec;
|
|
61
|
+
/** kg m², from the integral. */
|
|
62
|
+
readonly value: number;
|
|
63
|
+
/** The same thing from the closed form. Equal to `value`; the tests are what enforce that. */
|
|
64
|
+
readonly checkValue: number;
|
|
65
|
+
/** The antiderivative, for a lesson that wants to show the middle of the working. */
|
|
66
|
+
readonly antiderivative: Node;
|
|
67
|
+
readonly worked: Worked;
|
|
68
|
+
}
|
|
69
|
+
declare const SHAPES: Readonly<Record<string, ShapeSpec>>;
|
|
70
|
+
declare const shapeIds: () => readonly string[];
|
|
71
|
+
/**
|
|
72
|
+
* `I = ∫ r² dm` for a declared shape, with the integral shown.
|
|
73
|
+
*
|
|
74
|
+
* `values` supplies the symbols: `{ M: 2, R: 0.5 }`. The integral is done symbolically once and
|
|
75
|
+
* then evaluated at the limits, so what a lesson displays and what a lab computes are the same
|
|
76
|
+
* object rather than two implementations that agree today.
|
|
77
|
+
*/
|
|
78
|
+
declare function momentOfInertia(shape: ShapeSpec, values: Readonly<Record<string, number>>, sf?: number): InertiaResult;
|
|
79
|
+
/**
|
|
80
|
+
* The shape's integral as a watchable sweep: the element travelling through the body with the
|
|
81
|
+
* running total behind it.
|
|
82
|
+
*
|
|
83
|
+
* This is where the `r²` stops being a symbol. For a uniform disc, half the moment of inertia comes
|
|
84
|
+
* from beyond 84% of the radius, and a learner who has watched the meter barely move across the
|
|
85
|
+
* inner half will not need to be told why a flywheel is heavy at the rim.
|
|
86
|
+
*/
|
|
87
|
+
declare const sweepOf: (shape: ShapeSpec, values: Readonly<Record<string, number>>, samples?: number) => Sweep;
|
|
88
|
+
/** Where a given fraction of the moment of inertia has accumulated by. */
|
|
89
|
+
declare const inertiaComesFrom: (shape: ShapeSpec, values: Readonly<Record<string, number>>, fraction?: number) => number;
|
|
90
|
+
/**
|
|
91
|
+
* `I = Σ m r²` for point masses, where `r` is the distance from the AXIS, not from the origin.
|
|
92
|
+
*
|
|
93
|
+
* That distinction is the whole difficulty. For a mass at (x, y, z) rotating about the z axis the
|
|
94
|
+
* distance that matters is `√(x² + y²)`: the z coordinate is along the axis and contributes
|
|
95
|
+
* nothing, however large it is. Students routinely use the full position vector and get an answer
|
|
96
|
+
* that is too big, and the error is invisible in the common textbook case where every mass happens
|
|
97
|
+
* to lie in a plane through the origin.
|
|
98
|
+
*
|
|
99
|
+
* This is also the definition the continuous shapes are integrals OF, so it belongs beside them: a
|
|
100
|
+
* disc is this sum with the masses made infinitesimal and the sum made an integral.
|
|
101
|
+
*/
|
|
102
|
+
declare function pointMasses(masses: readonly {
|
|
103
|
+
label?: string;
|
|
104
|
+
mass: number;
|
|
105
|
+
distance: number;
|
|
106
|
+
}[], sf?: number): {
|
|
107
|
+
value: number;
|
|
108
|
+
totalMass: number;
|
|
109
|
+
worked: Worked;
|
|
110
|
+
};
|
|
111
|
+
/** Distance from an axis through the origin along `axis`, for a mass at (x, y, z). */
|
|
112
|
+
declare function distanceFromAxis(position: {
|
|
113
|
+
x: number;
|
|
114
|
+
y: number;
|
|
115
|
+
z: number;
|
|
116
|
+
}, axis?: 'x' | 'y' | 'z'): number;
|
|
117
|
+
/**
|
|
118
|
+
* Move an axis sideways: `I = I_cm + Mh²`.
|
|
119
|
+
*
|
|
120
|
+
* An operation, not a formula to recall, so a lab can let a learner drag the pivot and watch the
|
|
121
|
+
* number rise. It only works from the CENTRE OF MASS axis, and the error message says so, because
|
|
122
|
+
* applying it from an arbitrary axis is the standard mistake.
|
|
123
|
+
*/
|
|
124
|
+
declare function parallelAxis(aboutCentreOfMass: number, mass: number, distance: number, sf?: number): {
|
|
125
|
+
value: number;
|
|
126
|
+
worked: Worked;
|
|
127
|
+
};
|
|
128
|
+
/**
|
|
129
|
+
* For a FLAT body only: `I_z = I_x + I_y`.
|
|
130
|
+
*
|
|
131
|
+
* The flatness is the whole condition and is where the marks go, so it is in the note rather than
|
|
132
|
+
* in a comment. This is how the disc's `¼MR²` about a diameter is obtained from its `½MR²` about
|
|
133
|
+
* the axis, which is exactly the move the textbook makes and never justifies.
|
|
134
|
+
*/
|
|
135
|
+
declare function perpendicularAxis(inPlaneX: number, inPlaneY: number, sf?: number): {
|
|
136
|
+
value: number;
|
|
137
|
+
worked: Worked;
|
|
138
|
+
};
|
|
139
|
+
/**
|
|
140
|
+
* Add rigid bodies that share an axis.
|
|
141
|
+
*
|
|
142
|
+
* Moment of inertia is a scalar once the axis is fixed, so assemblies just add. That is what makes
|
|
143
|
+
* a three-blade fan tractable: one disc plus three rods, each rod moved out by the parallel axis
|
|
144
|
+
* theorem. A lab that lets a learner build a body out of parts is this function.
|
|
145
|
+
*/
|
|
146
|
+
declare function combine(parts: readonly {
|
|
147
|
+
label: string;
|
|
148
|
+
value: number;
|
|
149
|
+
}[], sf?: number): {
|
|
150
|
+
value: number;
|
|
151
|
+
worked: Worked;
|
|
152
|
+
};
|
|
153
|
+
/**
|
|
154
|
+
* `K = √(I/M)`: where a single point mass would have to sit to have the same moment of inertia.
|
|
155
|
+
*
|
|
156
|
+
* Worth saying in those words. It is routinely confused with the distance to the centre of mass,
|
|
157
|
+
* which it is not, and the textbook flags that confusion without explaining it.
|
|
158
|
+
*/
|
|
159
|
+
declare function radiusOfGyration(inertia: number, mass: number, sf?: number): {
|
|
160
|
+
value: number;
|
|
161
|
+
worked: Worked;
|
|
162
|
+
};
|
|
163
|
+
//#endregion
|
|
164
|
+
export { InertiaResult, SHAPES, ShapeGeometry, ShapeSpec, combine, distanceFromAxis, inertiaComesFrom, momentOfInertia, parallelAxis, perpendicularAxis, pointMasses, radiusOfGyration, shapeIds, sweepOf };
|
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
import { evaluate } from "../../math/ast.mjs";
|
|
2
|
+
import { parse } from "../../math/parse.mjs";
|
|
3
|
+
import { integrate, simplify } from "../../math/calculus.mjs";
|
|
4
|
+
import { toLatex } from "../../math/latex.mjs";
|
|
5
|
+
import { calc, texSigFigs } from "../../core/worked.mjs";
|
|
6
|
+
import { positionAtFraction, sweep } from "../integral-sweep.mjs";
|
|
7
|
+
|
|
8
|
+
//#region src/physics/rotation/inertia.ts
|
|
9
|
+
/**
|
|
10
|
+
* Moment of inertia, DERIVED rather than looked up.
|
|
11
|
+
*
|
|
12
|
+
* Every textbook at this level prints a table of eight standard results to memorise, and derives
|
|
13
|
+
* one or two of them in passing. The table is the problem. A student who memorises `I = ⅖MR²` has
|
|
14
|
+
* no way to check it, no idea why the sphere differs from the disc, and nothing to fall back on
|
|
15
|
+
* when the question is about a shape that is not in the table.
|
|
16
|
+
*
|
|
17
|
+
* So no result here is a constant. A shape is declared as a MASS DISTRIBUTION, and `I` comes out of
|
|
18
|
+
* an integral performed symbolically by `math/calculus`, together with the integral itself so a
|
|
19
|
+
* lesson can show it. The standard table is then an OUTPUT of this module rather than an input to
|
|
20
|
+
* it, which is the whole point.
|
|
21
|
+
*
|
|
22
|
+
* ```
|
|
23
|
+
* I = ∫ r² dm
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* WHY EACH SHAPE ALSO DECLARES ITS CLOSED FORM. It is not a duplicated source of truth, it is a
|
|
27
|
+
* CHECK: the tests integrate the distribution and evaluate the closed form at randomised
|
|
28
|
+
* dimensions and require them to agree, so a mis-stated distribution cannot pass silently.
|
|
29
|
+
* Deriving without verifying would just be a more elaborate way to be wrong.
|
|
30
|
+
*
|
|
31
|
+
* The integrand is written the way a learner would write it, `(R² − x²)²` and not its expansion,
|
|
32
|
+
* because `math/calculus` multiplies out before integrating. An integrand with no closed form at
|
|
33
|
+
* all is still fine for the SWEEP, which falls back to quadrature and says that it did; it is only
|
|
34
|
+
* this function, which quotes a formula, that needs a symbolic answer.
|
|
35
|
+
*
|
|
36
|
+
* Pure: no React, no pixels.
|
|
37
|
+
*/
|
|
38
|
+
const SHAPE_LIST = [
|
|
39
|
+
{
|
|
40
|
+
id: "rod-centre",
|
|
41
|
+
name: "uniform rod",
|
|
42
|
+
axis: "through its centre, at right angles to its length",
|
|
43
|
+
symbols: {
|
|
44
|
+
M: "mass",
|
|
45
|
+
l: "length"
|
|
46
|
+
},
|
|
47
|
+
variable: "x",
|
|
48
|
+
element: "(M/l)*x^2",
|
|
49
|
+
elementNote: "a piece of length dx has mass (M/l)dx, and sits a distance x from the axis",
|
|
50
|
+
from: "-l/2",
|
|
51
|
+
to: "l/2",
|
|
52
|
+
closedForm: "M*l^2/12",
|
|
53
|
+
closedFormTex: "\\tfrac{1}{12}Ml^2",
|
|
54
|
+
geometry: {
|
|
55
|
+
body: "rod",
|
|
56
|
+
element: "strip",
|
|
57
|
+
sweep: "along-length",
|
|
58
|
+
extent: "l"
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
id: "rod-end",
|
|
63
|
+
name: "uniform rod",
|
|
64
|
+
axis: "through one end, at right angles to its length",
|
|
65
|
+
symbols: {
|
|
66
|
+
M: "mass",
|
|
67
|
+
l: "length"
|
|
68
|
+
},
|
|
69
|
+
variable: "x",
|
|
70
|
+
element: "(M/l)*x^2",
|
|
71
|
+
elementNote: "the same rod and the same elements; only the limits move, because the axis moved",
|
|
72
|
+
from: "0",
|
|
73
|
+
to: "l",
|
|
74
|
+
closedForm: "M*l^2/3",
|
|
75
|
+
closedFormTex: "\\tfrac{1}{3}Ml^2",
|
|
76
|
+
geometry: {
|
|
77
|
+
body: "rod",
|
|
78
|
+
element: "strip",
|
|
79
|
+
sweep: "along-length",
|
|
80
|
+
extent: "l"
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
id: "disc-axis",
|
|
85
|
+
name: "uniform disc",
|
|
86
|
+
axis: "through its centre, perpendicular to its face",
|
|
87
|
+
symbols: {
|
|
88
|
+
M: "mass",
|
|
89
|
+
R: "radius"
|
|
90
|
+
},
|
|
91
|
+
variable: "r",
|
|
92
|
+
element: "(2*M/R^2)*r^3",
|
|
93
|
+
elementNote: "a ring of radius r and width dr has area 2πr dr, so mass (M/πR²)·2πr dr, all of it a distance r from the axis",
|
|
94
|
+
from: "0",
|
|
95
|
+
to: "R",
|
|
96
|
+
closedForm: "M*R^2/2",
|
|
97
|
+
closedFormTex: "\\tfrac{1}{2}MR^2",
|
|
98
|
+
geometry: {
|
|
99
|
+
body: "disc",
|
|
100
|
+
element: "annulus",
|
|
101
|
+
sweep: "outward-from-axis",
|
|
102
|
+
extent: "R"
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
id: "ring-axis",
|
|
107
|
+
name: "thin ring",
|
|
108
|
+
axis: "through its centre, perpendicular to its plane",
|
|
109
|
+
symbols: {
|
|
110
|
+
M: "mass",
|
|
111
|
+
R: "radius"
|
|
112
|
+
},
|
|
113
|
+
variable: "m",
|
|
114
|
+
element: "R^2",
|
|
115
|
+
elementNote: "every part of the ring is the same distance R from the axis, so no shape is needed at all",
|
|
116
|
+
from: "0",
|
|
117
|
+
to: "M",
|
|
118
|
+
closedForm: "M*R^2",
|
|
119
|
+
closedFormTex: "MR^2",
|
|
120
|
+
geometry: {
|
|
121
|
+
body: "ring",
|
|
122
|
+
element: "whole-ring",
|
|
123
|
+
sweep: "by-mass",
|
|
124
|
+
extent: "R"
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
id: "solid-sphere",
|
|
129
|
+
name: "solid sphere",
|
|
130
|
+
axis: "through its centre",
|
|
131
|
+
symbols: {
|
|
132
|
+
M: "mass",
|
|
133
|
+
R: "radius"
|
|
134
|
+
},
|
|
135
|
+
variable: "x",
|
|
136
|
+
element: "(3*M/(8*R^3))*(R^2 - x^2)^2",
|
|
137
|
+
elementNote: "slice it into discs. The disc at x has radius √(R²−x²), and a disc contributes ½r²dm, which is where the square comes from",
|
|
138
|
+
from: "-R",
|
|
139
|
+
to: "R",
|
|
140
|
+
closedForm: "2*M*R^2/5",
|
|
141
|
+
closedFormTex: "\\tfrac{2}{5}MR^2",
|
|
142
|
+
geometry: {
|
|
143
|
+
body: "sphere",
|
|
144
|
+
element: "slice",
|
|
145
|
+
sweep: "along-axis",
|
|
146
|
+
extent: "R"
|
|
147
|
+
}
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
id: "hollow-sphere",
|
|
151
|
+
name: "thin spherical shell",
|
|
152
|
+
axis: "through its centre",
|
|
153
|
+
symbols: {
|
|
154
|
+
M: "mass",
|
|
155
|
+
R: "radius"
|
|
156
|
+
},
|
|
157
|
+
variable: "x",
|
|
158
|
+
element: "(M/(2*R))*(R^2 - x^2)",
|
|
159
|
+
elementNote: "a band of the shell between x and x+dx has mass (M/2R)dx, which is Archimedes’ result that equal slices of a sphere carry equal surface area, and it sits at radius √(R²−x²)",
|
|
160
|
+
from: "-R",
|
|
161
|
+
to: "R",
|
|
162
|
+
closedForm: "2*M*R^2/3",
|
|
163
|
+
closedFormTex: "\\tfrac{2}{3}MR^2",
|
|
164
|
+
geometry: {
|
|
165
|
+
body: "shell",
|
|
166
|
+
element: "band",
|
|
167
|
+
sweep: "along-axis",
|
|
168
|
+
extent: "R"
|
|
169
|
+
}
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
id: "plate-in-plane",
|
|
173
|
+
name: "rectangular plate",
|
|
174
|
+
axis: "in its plane, through the centre, parallel to the side of length b",
|
|
175
|
+
symbols: {
|
|
176
|
+
M: "mass",
|
|
177
|
+
l: "length",
|
|
178
|
+
b: "breadth"
|
|
179
|
+
},
|
|
180
|
+
variable: "x",
|
|
181
|
+
element: "(M/l)*x^2",
|
|
182
|
+
elementNote: "strips parallel to the axis. Each strip’s own width does not matter, so this is the rod integral again and b never appears",
|
|
183
|
+
from: "-l/2",
|
|
184
|
+
to: "l/2",
|
|
185
|
+
closedForm: "M*l^2/12",
|
|
186
|
+
closedFormTex: "\\tfrac{1}{12}Ml^2",
|
|
187
|
+
geometry: {
|
|
188
|
+
body: "plate",
|
|
189
|
+
element: "strip",
|
|
190
|
+
sweep: "along-length",
|
|
191
|
+
extent: "l"
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
];
|
|
195
|
+
const SHAPES = Object.fromEntries(SHAPE_LIST.map((s) => [s.id, s]));
|
|
196
|
+
const shapeIds = () => SHAPE_LIST.map((s) => s.id);
|
|
197
|
+
/**
|
|
198
|
+
* `I = ∫ r² dm` for a declared shape, with the integral shown.
|
|
199
|
+
*
|
|
200
|
+
* `values` supplies the symbols: `{ M: 2, R: 0.5 }`. The integral is done symbolically once and
|
|
201
|
+
* then evaluated at the limits, so what a lesson displays and what a lab computes are the same
|
|
202
|
+
* object rather than two implementations that agree today.
|
|
203
|
+
*/
|
|
204
|
+
function momentOfInertia(shape, values, sf = 3) {
|
|
205
|
+
for (const symbol of Object.keys(shape.symbols)) if (!(symbol in values)) throw new Error(`${shape.name} (${shape.axis}) needs ${symbol}: ${shape.symbols[symbol]}.`);
|
|
206
|
+
const element = parse(shape.element);
|
|
207
|
+
const antiderivative = integrate(element, shape.variable);
|
|
208
|
+
if (!antiderivative) throw new Error(`Could not integrate ${shape.element} with respect to ${shape.variable}. The integrand must be an expanded polynomial; see the note in inertia.ts.`);
|
|
209
|
+
const lower = evaluate(parse(shape.from), values);
|
|
210
|
+
const upper = evaluate(parse(shape.to), values);
|
|
211
|
+
const at = (point) => evaluate(antiderivative, {
|
|
212
|
+
...values,
|
|
213
|
+
[shape.variable]: point
|
|
214
|
+
});
|
|
215
|
+
const value = at(upper) - at(lower);
|
|
216
|
+
const checkValue = evaluate(parse(shape.closedForm), values);
|
|
217
|
+
const tidy = simplify(antiderivative);
|
|
218
|
+
return {
|
|
219
|
+
shape,
|
|
220
|
+
value,
|
|
221
|
+
checkValue,
|
|
222
|
+
antiderivative,
|
|
223
|
+
worked: calc().step("I = \\int r^2 \\, dm", `${shape.name}, ${shape.axis}`).step(`dI = ${toLatex(element)} \\, d${shape.variable}`, shape.elementNote).step(`I = \\int_{${toLatex(parse(shape.from))}}^{${toLatex(parse(shape.to))}} ${toLatex(element)} \\, d${shape.variable}`, "the same integral the textbook writes, over the whole body").step(`= \\left[ ${toLatex(tidy)} \\right]_{${toLatex(parse(shape.from))}}^{${toLatex(parse(shape.to))}}`).step(`I = ${shape.closedFormTex}`, "which is the standard result, and now it is a conclusion").step(`I = ${texSigFigs(value, sf)}\\ \\mathrm{kg\\,m^2}`, `with ${Object.entries(values).map(([k, v]) => `${k} = ${v}`).join(", ")}`).done(value)
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* The shape's integral as a watchable sweep: the element travelling through the body with the
|
|
228
|
+
* running total behind it.
|
|
229
|
+
*
|
|
230
|
+
* This is where the `r²` stops being a symbol. For a uniform disc, half the moment of inertia comes
|
|
231
|
+
* from beyond 84% of the radius, and a learner who has watched the meter barely move across the
|
|
232
|
+
* inner half will not need to be told why a flywheel is heavy at the rim.
|
|
233
|
+
*/
|
|
234
|
+
const sweepOf = (shape, values, samples = 64) => sweep({
|
|
235
|
+
element: shape.element,
|
|
236
|
+
variable: shape.variable,
|
|
237
|
+
from: shape.from,
|
|
238
|
+
to: shape.to
|
|
239
|
+
}, values, samples);
|
|
240
|
+
/** Where a given fraction of the moment of inertia has accumulated by. */
|
|
241
|
+
const inertiaComesFrom = (shape, values, fraction = .5) => positionAtFraction(sweepOf(shape, values), fraction);
|
|
242
|
+
/**
|
|
243
|
+
* `I = Σ m r²` for point masses, where `r` is the distance from the AXIS, not from the origin.
|
|
244
|
+
*
|
|
245
|
+
* That distinction is the whole difficulty. For a mass at (x, y, z) rotating about the z axis the
|
|
246
|
+
* distance that matters is `√(x² + y²)`: the z coordinate is along the axis and contributes
|
|
247
|
+
* nothing, however large it is. Students routinely use the full position vector and get an answer
|
|
248
|
+
* that is too big, and the error is invisible in the common textbook case where every mass happens
|
|
249
|
+
* to lie in a plane through the origin.
|
|
250
|
+
*
|
|
251
|
+
* This is also the definition the continuous shapes are integrals OF, so it belongs beside them: a
|
|
252
|
+
* disc is this sum with the masses made infinitesimal and the sum made an integral.
|
|
253
|
+
*/
|
|
254
|
+
function pointMasses(masses, sf = 3) {
|
|
255
|
+
const value = masses.reduce((sum, m) => sum + m.mass * m.distance * m.distance, 0);
|
|
256
|
+
const totalMass = masses.reduce((sum, m) => sum + m.mass, 0);
|
|
257
|
+
const w = calc().step("I = \\sum m r^2", "r is the distance from the AXIS, not from the origin: a coordinate along the axis contributes nothing");
|
|
258
|
+
for (const m of masses) w.step(`${m.label ? `${m.label}: ` : ""}${texSigFigs(m.mass, sf)} \\times ${texSigFigs(m.distance, sf)}^2 = ${texSigFigs(m.mass * m.distance * m.distance, sf)}`);
|
|
259
|
+
w.step(`I = ${texSigFigs(value, sf)}\\ \\mathrm{kg\\,m^2}`, "total");
|
|
260
|
+
return {
|
|
261
|
+
value,
|
|
262
|
+
totalMass,
|
|
263
|
+
worked: w.done(value)
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
/** Distance from an axis through the origin along `axis`, for a mass at (x, y, z). */
|
|
267
|
+
function distanceFromAxis(position, axis = "z") {
|
|
268
|
+
if (axis === "z") return Math.hypot(position.x, position.y);
|
|
269
|
+
if (axis === "y") return Math.hypot(position.x, position.z);
|
|
270
|
+
return Math.hypot(position.y, position.z);
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Move an axis sideways: `I = I_cm + Mh²`.
|
|
274
|
+
*
|
|
275
|
+
* An operation, not a formula to recall, so a lab can let a learner drag the pivot and watch the
|
|
276
|
+
* number rise. It only works from the CENTRE OF MASS axis, and the error message says so, because
|
|
277
|
+
* applying it from an arbitrary axis is the standard mistake.
|
|
278
|
+
*/
|
|
279
|
+
function parallelAxis(aboutCentreOfMass, mass, distance, sf = 3) {
|
|
280
|
+
const value = aboutCentreOfMass + mass * distance * distance;
|
|
281
|
+
return {
|
|
282
|
+
value,
|
|
283
|
+
worked: calc().step("I = I_{cm} + Mh^2", "and it must start from the centre-of-mass axis, or it is not true").step(`I = ${texSigFigs(aboutCentreOfMass, sf)} + ${texSigFigs(mass, sf)} \\times ${texSigFigs(distance, sf)}^2`).step(`I = ${texSigFigs(value, sf)}\\ \\mathrm{kg\\,m^2}`, "moving the axis away always increases it").done(value)
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* For a FLAT body only: `I_z = I_x + I_y`.
|
|
288
|
+
*
|
|
289
|
+
* The flatness is the whole condition and is where the marks go, so it is in the note rather than
|
|
290
|
+
* in a comment. This is how the disc's `¼MR²` about a diameter is obtained from its `½MR²` about
|
|
291
|
+
* the axis, which is exactly the move the textbook makes and never justifies.
|
|
292
|
+
*/
|
|
293
|
+
function perpendicularAxis(inPlaneX, inPlaneY, sf = 3) {
|
|
294
|
+
const value = inPlaneX + inPlaneY;
|
|
295
|
+
return {
|
|
296
|
+
value,
|
|
297
|
+
worked: calc().step("I_z = I_x + I_y", "for a LAMINA only: the body must be flat, and the two axes lie in it").step(`I_z = ${texSigFigs(inPlaneX, sf)} + ${texSigFigs(inPlaneY, sf)}`).step(`I_z = ${texSigFigs(value, sf)}\\ \\mathrm{kg\\,m^2}`).done(value)
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* Add rigid bodies that share an axis.
|
|
302
|
+
*
|
|
303
|
+
* Moment of inertia is a scalar once the axis is fixed, so assemblies just add. That is what makes
|
|
304
|
+
* a three-blade fan tractable: one disc plus three rods, each rod moved out by the parallel axis
|
|
305
|
+
* theorem. A lab that lets a learner build a body out of parts is this function.
|
|
306
|
+
*/
|
|
307
|
+
function combine(parts, sf = 3) {
|
|
308
|
+
const value = parts.reduce((sum, p) => sum + p.value, 0);
|
|
309
|
+
const w = calc().step("I = \\sum I_i", "about ONE axis, they simply add, because each part’s mass is at its own distance from that same axis");
|
|
310
|
+
for (const p of parts) w.step(`${texSigFigs(p.value, sf)}\\ \\mathrm{kg\\,m^2}`, p.label);
|
|
311
|
+
w.step(`I = ${texSigFigs(value, sf)}\\ \\mathrm{kg\\,m^2}`, "total");
|
|
312
|
+
return {
|
|
313
|
+
value,
|
|
314
|
+
worked: w.done(value)
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* `K = √(I/M)`: where a single point mass would have to sit to have the same moment of inertia.
|
|
319
|
+
*
|
|
320
|
+
* Worth saying in those words. It is routinely confused with the distance to the centre of mass,
|
|
321
|
+
* which it is not, and the textbook flags that confusion without explaining it.
|
|
322
|
+
*/
|
|
323
|
+
function radiusOfGyration(inertia, mass, sf = 3) {
|
|
324
|
+
const value = Math.sqrt(inertia / mass);
|
|
325
|
+
return {
|
|
326
|
+
value,
|
|
327
|
+
worked: calc().step("I = MK^2 \\;\\Rightarrow\\; K = \\sqrt{I/M}").step(`K = \\sqrt{${texSigFigs(inertia, sf)} / ${texSigFigs(mass, sf)}}`).step(`K = ${texSigFigs(value, sf)}\\ \\mathrm{m}`, "the radius a single point of the same mass would need. It is NOT the distance to the centre of mass").done(value)
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
//#endregion
|
|
332
|
+
export { SHAPES, combine, distanceFromAxis, inertiaComesFrom, momentOfInertia, parallelAxis, perpendicularAxis, pointMasses, radiusOfGyration, shapeIds, sweepOf };
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { Worked } from "../../core/worked.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/physics/rotation/torque.d.ts
|
|
4
|
+
/** The linear quantity and its rotational counterpart, for a lesson that prints the mapping. */
|
|
5
|
+
declare const ROTATIONAL_ANALOGUE: readonly {
|
|
6
|
+
linear: string;
|
|
7
|
+
rotational: string;
|
|
8
|
+
relation: string;
|
|
9
|
+
}[];
|
|
10
|
+
/**
|
|
11
|
+
* The turning effect of one force: `τ = F r sin θ`.
|
|
12
|
+
*
|
|
13
|
+
* `θ` is between the force and the line from the axis to where it acts. Only the PERPENDICULAR
|
|
14
|
+
* component turns anything; a force aimed straight at the hinge has no effect however large it is,
|
|
15
|
+
* which is why you push a door at its edge and at right angles.
|
|
16
|
+
*/
|
|
17
|
+
declare function torque(force: number, distance: number, angleDeg?: number, sf?: number): {
|
|
18
|
+
value: number;
|
|
19
|
+
worked: Worked;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* The moment of a couple: `M = F d`, with `d` the perpendicular distance BETWEEN the two forces.
|
|
23
|
+
*
|
|
24
|
+
* Not `F × distance from some axis`, because there is no axis in it. The moment of a couple is the
|
|
25
|
+
* same about every point in the plane, which is the property that makes it a couple rather than two
|
|
26
|
+
* separate moments, and it is why the answer never asks you where the pivot is.
|
|
27
|
+
*/
|
|
28
|
+
declare function couple(force: number, separation: number, sf?: number): {
|
|
29
|
+
value: number;
|
|
30
|
+
worked: Worked;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* The force a second couple needs to balance the first.
|
|
34
|
+
*
|
|
35
|
+
* Two couples balance when their moments are equal and opposite, so a wide couple can be held by a
|
|
36
|
+
* small force and a narrow one needs a large force. That is the whole of the rectangular-plate
|
|
37
|
+
* question these chapters set.
|
|
38
|
+
*/
|
|
39
|
+
declare function balancingCouple(known: {
|
|
40
|
+
force: number;
|
|
41
|
+
separation: number;
|
|
42
|
+
}, separation: number, sf?: number): {
|
|
43
|
+
force: number;
|
|
44
|
+
worked: Worked;
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* `τ = Iα`: Newton's second law, rotated.
|
|
48
|
+
*
|
|
49
|
+
* Give any two and it returns the third. The same torque produces very different accelerations on
|
|
50
|
+
* bodies of the same mass shaped differently, which is the thing moment of inertia is FOR.
|
|
51
|
+
*/
|
|
52
|
+
declare function angularAcceleration(torqueValue: number, inertia: number, sf?: number): {
|
|
53
|
+
alpha: number;
|
|
54
|
+
worked: Worked;
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* The torque needed to change angular momentum at a given rate: `τ = dL/dt`.
|
|
58
|
+
*
|
|
59
|
+
* The more fundamental statement, and the one that survives when the moment of inertia itself is
|
|
60
|
+
* changing, which `τ = Iα` does not. Supplied as a rate rather than as a derivative because that is
|
|
61
|
+
* how the question arrives: "the angular momentum changes by this much in this time".
|
|
62
|
+
*/
|
|
63
|
+
declare const torqueFromRate: (deltaL: number, deltaT: number) => number;
|
|
64
|
+
//#endregion
|
|
65
|
+
export { ROTATIONAL_ANALOGUE, angularAcceleration, balancingCouple, couple, torque, torqueFromRate };
|