/** * 调试:retro_pinball 满力发射轨迹追踪 * 目的:定位能量增益 bug(理论上满力发射到不了顶部,实测 minY=28) * 运行:node dev_test_scripts/debug/debug_retro_pinball_launch.js */ 'use strict' const fs = require('fs') const path = require('path') const vm = require('vm') const HTML_PATH = path.join(__dirname, '..', '..', 'public', 'tools', 'thought_lab', 'labs', 'retro_pinball', 'index.html') const html = fs.readFileSync(HTML_PATH, 'utf-8') const grab = (a, b) => { const s = html.indexOf(a), e = html.indexOf(b) if (s < 0 || e < 0 || e <= s) throw new Error('未找到标记块: ' + a) return html.slice(s, e) } const code = grab('/* ==PHYSICS_CORE_START== */', '/* ==PHYSICS_CORE_END== */') + '\n' + grab('/* ==TABLE_GEOM_START== */', '/* ==TABLE_GEOM_END== */') const sandbox = { Math, console } vm.createContext(sandbox) vm.runInContext(code, sandbox) const PC = sandbox.PhysicsCore const { BALL_R, G_PX, SPRING_X, SPRING_TOP, buildTableStatics } = sandbox const DT = 1 / 360 function defaultParams() { return { g: G_PX * Math.sin(14 * Math.PI / 180), e: 0.55, mu: 0.12, airK: 0.02, rollR: 0.25, restV: 50, iterations: 8, slop: 0.3, correction: 0.8, maxV: 4200 }; } const gEff = G_PX * Math.sin(14 * Math.PI / 180) console.log('g_eff =', gEff.toFixed(1), 'px/s^2') const table = buildTableStatics(5, 1) const b = PC.createBall(SPRING_X, SPRING_TOP - BALL_R, BALL_R) b.vy = -2900 b.vx = 5 const balls = [b] let maxSp = 0, maxSpAt = '' let minY = 1e9, minYAt = '' let maxEnergy = -1e9, maxEnergyAt = '' const startEnergy = 0.5 * (b.vx * b.vx + b.vy * b.vy) + gEff * b.y console.log('初始动能+势能基准 E0 =', startEnergy.toFixed(0)) for (let i = 0; i < 360 * 3; i++) { PC.stepWorld(balls, table.statics, defaultParams(), DT) const sp = Math.hypot(b.vx, b.vy) const t = ((i + 1) / 360).toFixed(2) // 机械能 = 动能 + 势能(y 向下为正,势能取 g*y,越高 y 越小能量越小) const E = 0.5 * sp * sp + gEff * b.y if (sp > maxSp) { maxSp = sp; maxSpAt = `t=${t} pos=(${b.x.toFixed(1)},${b.y.toFixed(1)})` } if (b.y < minY) { minY = b.y; minYAt = `t=${t} pos=(${b.x.toFixed(1)},${b.y.toFixed(1)}) sp=${sp.toFixed(0)}` } if (E > maxEnergy) { maxEnergy = E; maxEnergyAt = `t=${t} pos=(${b.x.toFixed(1)},${b.y.toFixed(1)}) sp=${sp.toFixed(0)}` } if (i % 36 === 0) { console.log(`t=${t} pos=(${b.x.toFixed(1)},${b.y.toFixed(1)}) v=(${b.vx.toFixed(0)},${b.vy.toFixed(0)}) sp=${sp.toFixed(0)} E=${E.toFixed(0)}`) } } console.log('----') console.log('maxSp =', maxSp.toFixed(1), '@', maxSpAt) console.log('minY =', minY.toFixed(1), '@', minYAt) console.log('maxE =', maxEnergy.toFixed(0), '@', maxEnergyAt, '(E0=' + startEnergy.toFixed(0) + ')')