Elizaveta99, эту систему дифференциальных уравнении можно решить методом Эйлера-Коши.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Маятник</title>
<style>
body {
text-align: center;
max-width: 50em;
margin: 0 auto;
padding: 8px;
}
h1, h2 {
text-align: center;
}
#canvas {
display: block;
margin: 0 auto;
padding: 0;
background: #f1f5f5;
pointer-events: none;
}
.quantity-block {
display: grid;
grid-template-columns: 1fr 1fr;
align-items: flex-start;
gap: 1em;
padding: 10px;
}
.quantity-block label {
text-align: end;
}
.button {
background-color: white;
color: black;
border: 2px solid #555555;
padding: 15px 20px;
text-align: center;
cursor: pointer;
border-radius: 8px;
}
input, select, button {
font: inherit;
}
</style>
</head>
<body>
<h1>Маятник</h1>
<canvas id="canvas" width="350" height="350"></canvas>
<div class="quantity-block">
<label> Масса шарика</label>
<input name="m" type="number" value="1" step="any">
<label>Длина маятника</label>
<input name="l" type="number" value="0.5" step="any">
<label>Коэффициент сопротивления окружающей среды</label>
<input name="kf" type="number" value="2" step="any">
<label>Начальный угол маятника</label>
<input name="α" type="range" value="1" min="-1.57" max="1.57" step="any">
</div>
<button class="button" onclick="toggleSimulation();">Моделировать</button>
<script>
var canvas = $("#canvas");
var context = canvas.getContext("2d");
context.lineWidth = 3;
var WIDTH = canvas.width;
var HEIGHT = canvas.height;
var α = 0;
var ω = 0;
var m = 0.1;
var g = 9.8;
var l = 0.5;
var kf = 1;
var M = 0;
var isSimulationOn = false;
var lastT = performance.now();
function $(selector, context) {
return (context || document).querySelector(selector);
}
function $$(selector, context) {
return Array.from((context || document).querySelectorAll(selector));
}
function draw(t) {
requestAnimationFrame(draw);
var dt = Math.min(1 / 24, (t - lastT) / 1000);
lastT = t;
if(isSimulationOn) {
α += dt * ω;
ω += dt * (- g / l * Math.sin(α) - kf * l / m * ω * ω * Math.sign(ω) + M / m / l / l);
}
var angle = α + Math.PI / 2;
var size = Math.min(WIDTH, HEIGHT);
var ox = WIDTH / 2;
var rPend = size * 0.45 * Math.tanh(0.5 * l);
var rBall = size * 0.05 * Math.tanh(0.5 * m);
var x = ox - rPend * Math.cos(angle);
var y = rPend * Math.sin(angle) + 2;
context.clearRect(0, 0, WIDTH, HEIGHT);
// draw a ball
context.beginPath();
context.arc(x, y, rBall, 0, Math.PI * 2);
context.fill();
// draw a base and a string
context.moveTo(0, 2);
context.lineTo(WIDTH, 2);
context.moveTo(ox, 0);
context.lineTo(x, y);
context.stroke();
}
function updateVariables() {
$$(".quantity-block input[name]").forEach(function (input) {
assignVariable(input.name, input.value);
});
}
function assignVariable(name, value) {
if (name in window) {
window[name] = Number(value);
if (name === "α") ω = 0;
if (name === "l" || name === "m") window[name] = Math.max(0.01, window[name]);
}
}
function toggleSimulation() {
isSimulationOn = !isSimulationOn;
$(".button").textContent = isSimulationOn ? "Остановить" : "Моделировать"
updateVariables();
}
$(".quantity-block").addEventListener("input", function (event) {
var input = event.target;
if (input.matches("input[name]")) {
assignVariable(input.name, input.value);
}
});
requestAnimationFrame(draw);
toggleSimulation();
</script>
</body>
</html>