Редактирование: Поперечные волны в струне

Перейти к: навигация, поиск

Внимание! Вы не авторизовались на сайте. Ваш IP-адрес будет публично видимым, если вы будете вносить любые правки. Если вы войдёте или создадите учётную запись, правки вместо этого будут связаны с вашим именем пользователя, а также у вас появятся другие преимущества.

Правка может быть отменена. Пожалуйста, просмотрите сравнение версий, чтобы убедиться, что это именно те изменения, которые вас интересуют, и нажмите «Записать страницу», чтобы изменения вступили в силу.
Текущая версия Ваш текст
Строка 1: Строка 1:
[[Виртуальная лаборатория]] > [[Поперечные волны в струне]] <HR>
+
[[Виртуальная лаборатория]] > [[Динамика взаимодействия частиц произвольной формы]] <HR>
 
[[Файл:1449683138190745365.gif|thumb|600px|right|Движение струны, со скоростью 1200 кадров в секунду]]
 
[[Файл:1449683138190745365.gif|thumb|600px|right|Движение струны, со скоростью 1200 кадров в секунду]]
  
Строка 10: Строка 10:
 
Разработка программы моделирующая колебания струны
 
Разработка программы моделирующая колебания струны
 
    
 
    
===Математическая модель===  
+
 
<math> m\begin{pmatrix} {\ddot x_i} \\ {\ddot y_i} \end{pmatrix}= -k (|\vec{r}_{i,i-1}|-l_0)\frac{\vec{r}_{i,i-1}}{|\vec{r}_{i,i-1}|} - B (\begin{pmatrix} {\dot x_i} \\ {\dot y_i} \end{pmatrix}-\begin{pmatrix} {\dot x_{i-1}} \\ {\dot y_{i-1}} \end{pmatrix}) </math><br />
+
===Решение===  
  <math>\vec{r}_{i,i-1} = \begin{pmatrix} {x_i} \\ {y_i} \end{pmatrix}-\begin{pmatrix} {x_{i-1}} \\ {y_{i-1}} \end{pmatrix} </math><br />
+
<math> m \ddot r=\sum -k \Delta r - B \dot </math><br />
<math>l_0</math>-начальная длина одной пружины <br/>
+
  r = r(x,y)<br />
 
  m - масса одной частицы<br />
 
  m - масса одной частицы<br />
 
  k - жесткость пружины<br />
 
  k - жесткость пружины<br />
 
  B - вязкость
 
  B - вязкость
 
+
Обе конца пружины закреплены
===Интерфейс программы===
 
Оба конца закреплены. Возможно задавать колебания, оттягивая один из элементов. По нажатию кнопки "Sin", левая граница движется по закону синуса. При повторном нажатии, левая граница останавливается. Кнопка "Reset" устанавливает систему в начальное положение. Ползунки:<br/>
 
g - сила тяжести<br/>
 
B - вязкость<br/>
 
&nu; - частота колебания левой границы (работает только при "Sin")<br/>
 
A - амплитуда колебания левой границы (работает только при "Sin")<br/> 
 
  
 
===Результаты===
 
===Результаты===
Строка 31: Строка 25:
 
<br />
 
<br />
  
[[Медиа:OscSpring.rar|Скачать архив]]
+
[[Медиа:Discrete_mechanics.zip|Скачать архив]]
<br />
 
<br />
 
<div class="mw-collapsible mw-collapsed" style="width:100%" >
 
'''Текст программы на языке JavaScript (разработчик [[Богданов Дмитрий]]):''' <div class="mw-collapsible-content">
 
Файл '''"Test.js"'''
 
<syntaxhighlight lang="javascript" line start="1" enclose="div">
 
function Main_Spring(canvas, slider_g, text_g, slider_nu, text_nu, slider_A, text_A, sinbutton) {
 
var canvas, ctx, w, h, world, lineBody, lineBody1, mouseConstraint, s, s1; // переменные: канвас, содержимое канваса, ширина и высота канваса, создание "мира" p2, парвая и левая "стена", закрепление мыши, пружины для связи со стенами
 
var scaleX = 50, scaleY = -50; //масштаб
 
var circleBody2 = new Array(); //массив шариков
 
var circleShape2 = new Array(); //массив форм шариков
 
var ss = new Array();//массив пружин
 
var num = 100; //общее кол-во частиц
 
var k = 250; // жесткость пружин
 
var B = 4; // вязкость
 
var R = 0.05; //радиус шаров
 
var dx = 0.01; // начальная длина пружин
 
var g = 0; // сила тяжести
 
var dtt = 0; // время для колебаний по sin
 
var LA = 2; // смещение по вертикали для sin
 
var dt = 0.03; // "скорость" для sin
 
var sw = 0; // переключатель для кнопок
 
 
// Инициализируем канвал и действия маши
 
canvas = document.getElementById("myCanvas");
 
    w = canvas.width;
 
    h = canvas.height;
 
    ctx = canvas.getContext("2d");
 
    ctx.lineWidth = 0.05;
 
canvas.addEventListener("mousedown", doMouseDown, false);
 
canvas.addEventListener("mousemove", doMouseMove, false);
 
canvas.addEventListener("mouseup", doMouseUp, false);
 
 
// Ползунки и текстовые поля
 
this.setSlider_g = function(new_g){g = new_g; world.gravity[1] = -g;};
 
this.setSlider_nu = function(new_nu){dt = new_nu/10;};
 
this.setSlider_A = function(new_A){LA = new_A*4;};
 
this.setSlider_B = function(new_B){B = new_B*12; s.damping = B; s1.damping = B;
 
for (var i = 0; i < num-1; i++){ss[i].damping = B;};
 
for (var j = 0; j < num; j++){circleBody2[j].damping=B/24;};};
 
 
slider_g.min = 0;              slider_g.max = 1;
 
    slider_g.step = 0.10;
 
    slider_g.value = g;
 
    text_g.value = g.toFixed(1);
 
 
slider_A.min = 0;              slider_A.max = 1;
 
    slider_A.step = 0.10;
 
    slider_A.value = LA/4;
 
    text_A.value = (LA/4).toFixed(1);
 
 
 
slider_B.min = 0;              slider_B.max = 1;
 
    slider_B.step = 0.10;
 
    slider_B.value = B/12;
 
    text_B.value = (B/12).toFixed(1);
 
 
slider_nu.min = 0;              slider_nu.max = 1;
 
    slider_nu.step = 0.10;
 
    slider_nu.value = dt*10;          // начальное значение ползунка должно задаваться после min и max
 
    text_nu.value = (dt*10).toFixed(1);
 
 
 
      init();
 
      animate();
 
 
 
// Функция "переключения" кнопок
 
this.sw = function(a)
 
{
 
if (a==-1) sw = a;
 
else
 
sw += a;
 
}
 
 
// Функция движения левой границы по Sin
 
function FSin()
 
{
 
sinbutton.value = "Стоп";
 
sw = 1;
 
dtt+=dt;
 
s.localAnchorB[0] = 4-LA * (Math.sin(dtt)/2);
 
return 0;
 
}
 
 
function Stop()
 
{
 
sw = 0;
 
sinbutton.value = "Sin";
 
}
 
 
// Функция сброса
 
function Reset()
 
{
 
if (sinbutton.value != "Sin") sinbutton.value = "Sin";
 
dtt = 0;
 
sw = 0;
 
world.clear();
 
init();
 
 
 
}
 
 
// Функция создания всех объектов
 
      function init(){
 
       
 
// Создание мира p2
 
        world = new p2.World();
 
world.gravity[1] = -g;
 
world.solver.iterations = 10;
 
world.solver.frictionIterations = 0;
 
 
 
// Создаем левую границу
 
lineShape = new p2.Line({ length: 6 });
 
        lineBody = new p2.Body({
 
          position: [-6,-4],
 
          angle: Math.PI/2
 
        });
 
        lineBody.addShape(lineShape, [0,0], Math.PI );
 
        world.addBody(lineBody);
 
 
// Создаем правую границу
 
lineShape1 = new p2.Line({ length: 6 });
 
        lineBody1 = new p2.Body({
 
          position: [6,-4],
 
          angle: Math.PI/2
 
        });
 
        lineBody1.addShape(lineShape1, [0,0], Math.PI );
 
        world.addBody(lineBody1);
 
 
 
// Создаем все шарики
 
for (var i = 0; i < num; i++)
 
{
 
circleShape2[i] = new p2.Circle({ radius: R });
 
circleBody2[i] = new p2.Body({ mass:0.5, position:[(-6 + (12*(i+1)/(num+1))) ,0] , angularDamping:0, damping:B/24});
 
circleBody2[i].addShape(circleShape2[i]);
 
world.addBody(circleBody2[i]);
 
};
 
 
//Создаем пружину для связи с левой границей
 
s = new p2.LinearSpring(circleBody2[0], lineBody, {
 
                restLength : dx,
 
                stiffness : k,
 
damping : B,
 
                localAnchorB : [4,0],
 
            });
 
        world.addSpring(s);
 
 
// Создаем пружину для связи с правой границей
 
s1 = new p2.LinearSpring(circleBody2[num-1], lineBody1, {
 
                restLength : dx,
 
                stiffness : k,
 
damping : B,
 
                localAnchorB : [4,0],
 
            });
 
        world.addSpring(s1);
 
 
// Создаем пружины для связи шариков вместе
 
for (var i = 0; i < num-1; i++)
 
{
 
ss[i] = new p2.LinearSpring(circleBody2[i], circleBody2[i+1], {
 
                restLength : dx,
 
                stiffness : k,
 
damping : B,
 
                localAnchorA : [0,0],
 
                localAnchorB : [0,0],
 
            });
 
world.addSpring(ss[i]);
 
};
 
 
//Отключаем взаимодействие между пружинами и между шариками
 
for (var i = 0; i < num-1; i++)
 
{
 
for (var j = i; j < num-1; j++)
 
{
 
world.disableBodyCollision(ss[i], ss[j]);
 
}
 
};
 
 
for (var i = 0; i < num; i++)
 
{
 
for (var j = i; j < num; j++)
 
{
 
world.disableBodyCollision(circleBody2[i], circleBody2[j]);
 
world.disableBodyCollision(circleBody2[i], lineBody1);
 
world.disableBodyCollision(circleBody2[i], lineBody);
 
}
 
};
 
 
// Создаем объект для мыши
 
        mouseBody = new p2.Body();
 
        world.addBody(mouseBody);
 
 
      }
 
 
 
  // Функция нажатия мыши вниз
 
  function doMouseDown(event){
 
          var position = getPhysicsCoord(event);
 
          circleBody2.forEach(function(item, i, circleBody2)
 
  {
 
  var hitBodies = world.hitTest(position, [item]);
 
          if(hitBodies.length){
 
            mouseBody.position[0] = position[0];
 
            mouseBody.position[1] = position[1];
 
          mouseConstraint = new p2.LockConstraint(mouseBody, item);
 
            world.addConstraint(mouseConstraint);
 
  }
 
          });
 
        }
 
 
// Функция перемещения мыши
 
  function doMouseMove(event){
 
          var position = getPhysicsCoord(event);
 
          mouseBody.position[0] = position[0];
 
          mouseBody.position[1] = position[1];
 
        }
 
 
// Функция отпуская клавиши мыши
 
        function doMouseUp(event){
 
          world.removeConstraint(mouseConstraint);
 
        } 
 
 
 
// Перевод координат мыши в текущие координаты
 
    function getPhysicsCoord(mouseEvent){
 
          var rect = canvas.getBoundingClientRect();
 
          var x = mouseEvent.clientX - rect.left;
 
          var y = mouseEvent.clientY - rect.top;
 
          x = (x - w / 2) / scaleX;
 
          y = (y - h / 2) / scaleY;
 
 
 
          return [x, y];
 
}
 
 
 
  // Функция рисования всех шаров
 
  function drawAllCircle(){
 
for (var i = 0; i < num; i++)
 
{
 
ctx.beginPath();
 
        var x1 = circleBody2[i].position[0],
 
            y1 = circleBody2[i].position[1],
 
            radius1 = circleShape2[i].radius;
 
        ctx.arc(x1,y1,radius1,0,2*Math.PI);
 
ctx.fill();
 
ctx.stroke();
 
}
 
ctx.strokeStyle = "black";
 
      }
 
 
// Рисуем пол
 
      function drawPlane(){
 
        ctx.moveTo(-w, -4);
 
        ctx.lineTo( w, -4);
 
ctx.strokeStyle = "black";
 
        ctx.stroke();
 
      }
 
 
 
  // Рисуем правую стену
 
  function drawRL(){
 
        ctx.beginPath();
 
        var x = lineBody.position[0],
 
            y = lineBody.position[1];
 
        ctx.moveTo(x, -y);
 
        ctx.lineTo(x, y);
 
        ctx.strokeStyle = "black";
 
ctx.stroke();
 
      }
 
 
 
 
 
  // Рисуем левую стену
 
  function drawLL(){
 
        ctx.beginPath();
 
        var x = lineBody1.position[0],
 
            y = lineBody1.position[1];
 
        ctx.moveTo(x, -y);
 
        ctx.lineTo(x, y);
 
ctx.strokeStyle = "black";
 
        ctx.stroke();
 
      }
 
 
 
  // Рисуем все пружины
 
  function drawAllSpring(){
 
for (var i = 0; i < num-1; i++)
 
{
 
ctx.beginPath();
 
        var x = circleBody2[i].position[0],
 
            y = circleBody2[i].position[1];
 
var x1 = circleBody2[i+1].position[0],
 
            y1 = circleBody2[i+1].position[1];
 
            ctx.moveTo(x, y);
 
ctx.lineTo(x1, y1);
 
ctx.strokeStyle = "black";
 
        ctx.stroke();
 
}
 
      }
 
 
 
  // Рисуем пружину для связи первого шарика со стеной
 
  function draw1S(){
 
ctx.beginPath();
 
        var x = circleBody2[0].position[0],
 
            y = circleBody2[0].position[1];
 
ctx.moveTo(-6, (s.localAnchorB[0]-4));
 
        ctx.lineTo(x, y);
 
        ctx.strokeStyle = "black";
 
ctx.stroke();
 
      }
 
 
 
  // Рисуем пружину для связи последнего шарика со стеной
 
  function draw2S(){
 
        ctx.beginPath();
 
        var x = circleBody2[num-1].position[0],
 
            y = circleBody2[num-1].position[1];
 
        ctx.moveTo(6, 0);
 
        ctx.lineTo(x, y);
 
        ctx.strokeStyle = "black";
 
ctx.stroke();
 
      }
 
 
 
      function render(){
 
        ctx.clearRect(0,0,w,h);
 
        ctx.save();
 
        ctx.translate(w/2, h/2);  // Переводим начало в центр
 
        ctx.scale(50, -50);      //Зумируем канвас
 
        // Рисуем все тела на канвасе
 
drawAllCircle();
 
        drawRL();
 
drawLL();
 
drawPlane();
 
drawAllSpring();
 
draw1S();
 
draw2S();
 
        ctx.restore();
 
      }
 
 
 
      function animate(){
 
        requestAnimationFrame(animate);
 
if (sw == 1) FSin();
 
if (sw == 2) Stop();
 
if (sw == -1) Reset();
 
        world.step(1/60);
 
        render();
 
      }
 
 
 
}
 
 
 
</syntaxhighlight>
 
</div>
 
</div>
 
 
 
== Ссылки ==
 
*[https://ru.wikipedia.org/wiki/%D0%9F%D1%80%D1%83%D0%B6%D0%B8%D0%BD%D0%BD%D1%8B%D0%B9_%D0%BC%D0%B0%D1%8F%D1%82%D0%BD%D0%B8%D0%BA Пружинный маятник]
 
*[[Курсовые работы по ВМДС: 2015-2016]]
 
*[[Введение в механику дискретных сред]]
 
* [[VirtLab| Виртуальная лаборатория]]
 
Вам запрещено изменять защиту статьи. Edit Создать редактором

Обратите внимание, что все добавления и изменения текста статьи рассматриваются как выпущенные на условиях лицензии Public Domain (см. Department of Theoretical and Applied Mechanics:Авторские права). Если вы не хотите, чтобы ваши тексты свободно распространялись и редактировались любым желающим, не помещайте их сюда.
Вы также подтверждаете, что являетесь автором вносимых дополнений или скопировали их из источника, допускающего свободное распространение и изменение своего содержимого.
НЕ РАЗМЕЩАЙТЕ БЕЗ РАЗРЕШЕНИЯ МАТЕРИАЛЫ, ОХРАНЯЕМЫЕ АВТОРСКИМ ПРАВОМ!

To protect the wiki against automated edit spam, we kindly ask you to solve the following CAPTCHA:

Отменить | Справка по редактированию  (в новом окне)