console
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
<title>刚体平面运动仿真 题8-30 推钢机</title>
<style>
* {
box-sizing: border-box;
font-family: "Microsoft Yahei", sans-serif;
}
body {
padding:10px;
max-width:100%;
margin:0 auto;
}
canvas {
border:2px solid #666;
background:#f9f9f9;
width:100%;
height:auto;
}
.control-panel{
margin:10px 0;
padding:12px;
background:#eee;
border-radius:8px;
}
.item{
margin:10px 0;
}
input[type="range"]{
width:100%;
}
.result{
margin-top:10px;
font-size:16px;
color:#c82423;
}
</style>
</head>
<body>
<h2>习题8-30 推钢机 刚体平面运动仿真</h2>
<canvas id="simCanvas" width="700" height="520"></canvas>
<div class="control-panel">
<div class="item">
<label>曲柄角速度 ω_OA:<span id="wval">0.5</span> rad/s</label>
<input type="range" id="sliderW" min="0.1" max="1.2" step="0.05" value="0.5">
</div>
<div class="result">
摇杆 O₁B 角速度 ω₁ = <span id="omega1">0.000</span> rad/s
</div>
</div>
<script>
const canvas = document.getElementById('simCanvas');
const ctx = canvas.getContext('2d');
//固定铰点坐标
const Ox = 580;
const Oy = 380;
const O1x = 120;
const O1y = 380;
//参数 r=0.2m l=1m
let r = 80;
let wOA = 0.5;
let t = 0;
const sliderW = document.getElementById("sliderW");
const wval = document.getElementById("wval");
const omega1Dom = document.getElementById("omega1");
sliderW.oninput = ()=>{
wOA = Number(sliderW.value);
wval.innerText = wOA.toFixed(2);
}
function drawArrow(fromX, fromY, toX, toY, color="#ff3333"){
ctx.strokeStyle = color;
ctx.fillStyle = color;
ctx.lineWidth=2;
ctx.beginPath();
ctx.moveTo(fromX,fromY);
ctx.lineTo(toX,toY);
ctx.stroke();
const headLen = 8;
const angle = Math.atan2(toY-fromY,toX-fromX);
ctx.beginPath();
ctx.moveTo(toX,toY);
ctx.lineTo(toX - headLen*Math.cos(angle-Math.PI/6), toY - headLen*Math.sin(angle-Math.PI/6));
ctx.lineTo(toX - headLen*Math.cos(angle+Math.PI/6), toY - headLen*Math.sin(angle+Math.PI/6));
ctx.closePath();
ctx.fill();
}
function animate(){
ctx.clearRect(0,0,canvas.width,canvas.height);
t += 0.015;
const phi = wOA * t;
//A点坐标,曲柄OA
const Ax = Ox - r*Math.sin(phi);
const Ay = Oy - r*Math.cos(phi);
//连杆AB长度 sqrt(3)*r
const L_AB = Math.sqrt(3)*r;
//绘制机架固定铰
ctx.beginPath();
ctx.arc(Ox,Oy,8,0,Math.PI*2);
ctx.fillStyle="#333";
ctx.fill();
ctx.fillText("O",Ox+12,Oy);
ctx.beginPath();
ctx.arc(O1x,O1y,8,0,Math.PI*2);
ctx.fill();
ctx.fillText("O₁",O1x-25,Oy);
//曲柄OA
ctx.beginPath();
ctx.moveTo(Ox,Oy);
ctx.lineTo(Ax,Ay);
ctx.strokeStyle="#4488ff";
ctx.lineWidth=3;
ctx.stroke();
//B点 几何近似
const Bx = O1x + 180*Math.cos(Math.PI/3);
const By = O1y - 180*Math.sin(Math.PI/3);
//连杆AB
ctx.beginPath();
ctx.moveTo(Ax,Ay);
ctx.lineTo(Bx,By);
ctx.strokeStyle="#d82020";
ctx.lineWidth=3;
ctx.stroke();
//摇杆 O1B
ctx.beginPath();
ctx.moveTo(O1x,O1y);
ctx.lineTo(Bx,By);
ctx.lineTo(Bx+220*Math.cos(Math.PI/3), By -220*Math.sin(Math.PI/3));
ctx.strokeStyle="#22aa22";
ctx.lineWidth=3;
ctx.stroke();
//滑块C
const Cx = Bx+160*Math.cos(Math.PI/3);
const Cy = By -160*Math.sin(Math.PI/3);
ctx.beginPath();
ctx.arc(Cx,Cy,7,0,Math.PI*2);
ctx.fillStyle="#ff8822";
ctx.fill();
ctx.fillText("C",Cx+10,Cy);
//A点
ctx.beginPath();
ctx.arc(Ax,Ay,6,0,Math.PI*2);
ctx.fillStyle="#4488ff";
ctx.fill();
//B点
ctx.beginPath();
ctx.arc(Bx,By,6,0,Math.PI*2);
ctx.fillStyle="#d82020";
ctx.fill();
//理论计算,图示位置60度
const vA = wOA * r;
const omega1 = vA / (2*r);
omega1Dom.innerText = omega1.toFixed(3);
requestAnimationFrame(animate);
}
animate();
</script>
</body>
</html>