БлогNot. Javascript: маятник или как повернуть систему координат

Javascript: маятник или как повернуть систему координат

На канве HTML рисовать удобно под любым углом, ведь можно не вычислять угол поворота, а повернуть систему координат и отрисовать "вдоль осей".

Для иллюстрации этого подхода - небольшой скрипт, рисующий известный маятник (учитывается только сила тяжести и, условно, трение).

Ниже приводятся скрипт в работе и исходник файла на момент написания, предполагается, что он будет сохранён как документ .html в кодировке Юникода UTF-8.

По клику на канве движение начинается заново, остальное легко увидеть из комментариев в листинге.

<!DOCTYPE html>
<html lang="ru">
 <head>
  <meta charset="UTF-8">
  <title>Pendulum</title>
 </head>
 <body>

<div id="center">
 <canvas id="pendCanvas" width="600" height="600"></canvas>
</div>
<script>
 function Simulation (len, grav, angle0, tstep, callback) {
  //Аргументы: длина (м), ускорение свободного падения (м/c^2), 
  //начальный угол (рад.), шаг по времени (мс), функция отрисовки
  var velocity = 0;
  var angle = angle0;
  var k = - grav / len;
  var tsec = tstep / 1000;
  var coeffT = 0.999; //"трение" из интервала ]0;1], =1 - без замедления
  return setInterval (function () {
   var acceleration = k * Math.sin(angle);
   velocity += acceleration * tsec;
   angle += velocity * tsec;
   angle *= coeffT;
   callback (angle);
  }, tstep);
 }
 
 var canvas = document.getElementById('pendCanvas');
 var context = canvas.getContext('2d');
 var prev=0, simId = null;

 function myAngle (angle) {
  var size = Math.min (canvas.width, canvas.height); //размер, относительно которого считаем
  var rPend = size * 0.35; //длина плеча маятника
  var rBar = size * 0.005; //толшина плеча маятника
  var rBall = size * 0.03; //размер шарика
  var ballX = Math.sin(angle) * rPend;
  var ballY = Math.cos(angle) * rPend;
 
  context.fillStyle = 'rgba(255,255,255,0.51)';
  context.globalCompositeOperation = 'destination-out'; 
   //Целевое изображение отображается вне границ исходного
  context.fillRect (0, 0, canvas.width, canvas.height); //очистить
  context.fillStyle = "yellow"; //цвет заливки
  context.strokeStyle = "rgba(0,0,0,"+Math.max(0,1-Math.abs(prev-angle)*10)+")";
  context.globalCompositeOperation = "source-over";
   //Исходное изображение накрывает целевое
  context.save();
  context.translate (canvas.width/2, canvas.height/2); //начало координат
  context.rotate(angle); //поворот системы координат
  context.beginPath();
  context.rect (-rBar, -rBar, rBar*2, rPend+rBar*2); //плечо
  context.fill();
  context.stroke();
  context.beginPath();
  context.arc (0, rPend, rBall, 0, Math.PI*2, false); //шарик
  context.fill();
  context.stroke();
  context.restore();
  prev = angle;
 }

 canvas.onclick = function (event) {
  if (simId) {
   clearInterval (simId); simId = null;
  }
  simId = Simulation(0.75, 9.80665, Math.PI*0.9, 10, myAngle);
 }

 window.addEventListener('load', function (e) {
  simId = Simulation(0.75, 9.80665, Math.PI*0.9, 10, myAngle);
 }, false); 
</script>
<noscript>
 <div align="center">
  Извините, для работы приложения нужен включённый Javascript
 </div>
</noscript>
 
</body></html>

теги: javascript графика

13.06.2019, 12:18; рейтинг: 140