<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta content="width=device-width, initial-scale=1.0">
<title>轮图弹簧系统能量守恒模拟</title>
<style>
* {margin: 0; padding: 0; box-sizing: border-box;}
body {display: flex; flex-direction: column; align-items: center; background: #f0f0f0; font-family: Arial; gap: 10px; padding: 10px;}
#controls {padding: 12px; background: #fff; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); display: flex; flex-wrap: wrap; gap: 8px; align-items: center;}
#controls input {width: 100px; padding: 5px; border: 1px solid #ddd; border-radius: 4px;}
#controls button {padding: 6px 12px; cursor: pointer; border: none; border-radius: 4px; color: #fff;}
#startBtn {background: #4285f4;}
#resetBtn {background: #f44336;}
#connectBtn {background: #4caf50;}
#energyPanel {padding: 10px 15px; background: #fff; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); min-width: 300px; text-align: left; font-size: 14px;}
#energyPanel div {margin: 4px 0;}
#energyPanel span {font-weight: bold; color: #4285f4;}
#canvas {background: #ffffff; border-radius: 8px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); touch-action: none;}
.mode-tip {font-size: 12px; color: #666; margin-top: 5px;}
</style>
</head>
<body>
<div>
节点数: <input type="number" value="6" min="3" max="20">
最短长度: <input type="number" value="50" min="20" max="200">
最长长度: <input type="number" value="150" min="50" max="300">
弹性系数: <input type="number" value="0.05" step="0.01" min="0.01" max="0.5">
<button>开始/暂停</button>
<button>重置系统</button>
<button>开启自定义连接</button>
<div>当前模式: 正常模拟</div>
</div>
<div>
<div>全局修正能量 H: <span>0.00</span></div>
<div>能量跳变总和 ΣΦ: <span>0.00</span></div>
<div>节点平均动能: <span>0.00</span></div>
<div>节点平均势能修正: <span>0.00</span></div>
</div>
<canvas></canvas>
<script>
// 1. 初始化画布与参数
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
let nodes = [], springs = [];
let isRunning = false, selectedNode = null, connectMode = false;
let nodeCount, minLen, maxLen, kVal, centerX, centerY;
let connectStartNode = null; // 自定义连接起始节点
// 能量显示DOM
const totalHElem = document.getElementById('totalH');
const phiSumElem = document.getElementById('phiSum');
const avgEkElem = document.getElementById('avgEk');
const avgVkElem = document.getElementById('avgVk');
const modeTipElem = document.getElementById('modeTip');
// 自适应屏幕尺寸
function resizeCanvas() {
canvas.width = Math.min(window.innerWidth - 40, 900);
canvas.height = Math.min(window.innerHeight - 200, 600);
centerX = canvas.width / 2;
centerY = canvas.height / 2;
}
window.addEventListener('resize', () => {resizeCanvas(); initSystem();});
// 2. 节点类(优化能量计算稳定性)
class Node {
constructor(x, y, id) {
this.x = x;
this.y = y;
this.vx = (Math.random() - 0.5) * 1.5; // 降低初始速度,减少能量波动
this.vy = (Math.random() - 0.5) * 1.5;
this.radius = 12;
this.id = id; // 节点ID,用于自定义连接
this.Ek = 0; // 局部动能 E(k)
this.Vk = 0; // 势能修正 V(k)
this.mass = 2.0; // 引入质量,使能量数值更合理
}