Редактирование: Взаимодействие двух заряженных тел (Закон Кулона)

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

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

Правка может быть отменена. Пожалуйста, просмотрите сравнение версий, чтобы убедиться, что это именно те изменения, которые вас интересуют, и нажмите «Записать страницу», чтобы изменения вступили в силу.
Текущая версия Ваш текст
Строка 1: Строка 1:
 
[[Виртуальная лаборатория]] > [[Динамика взаимодействующих частиц]] <HR>
 
[[Виртуальная лаборатория]] > [[Динамика взаимодействующих частиц]] <HR>
{{#widget:Iframe |url=http://tm.spbstu.ru/htmlets/Drepin/Culon/culon.html |width=1139 |height=625 |border=0 }}
+
{{#widget:Iframe |url=http://tm.spbstu.ru/htmlets/Drepin/culon.html |width=1139 |height=600 |border=0 }}
 +
Разработка: [[Дрепин_Михаил|Дрепин Михаил]]
  
== Управление ==
 
''Работа с полем''
 
*Возможность перетаскивания тел и рабочего пространства по клику левой кнопкой мыши
 
*Прорисовка векторов скоростей по клику правой кнопкой мыши
 
*Приближение к точке колёсиком мыши (отдаление)
 
*При клике по любому телу во время паузы скорости обоих тел сохраняются в таблицу
 
''Кнопки''
 
*Кнопка "Запустить" - запуск анимации с начальными параметрами, взятыми из таблицы
 
*Кнопка "Остановить/Продолжить" - пауза и продолжение уже запущенной анимации
 
*Активное бесконечное построение позволяет следить за телами без остановки, но автоматически меняет начальные параметры в таблицах
 
*Активная кнопка слежения за телом перемещает его и фиксирует в центре поля, анимация происходит относительно зафиксированного тела
 
*Обратная анимация позволяет совершить перемотку от последнего положения тел до начальных условий
 
 
== Разработка ==
 
Скачать программу: [[Медиа:Culon.zip|Culon.zip]]
 
<div class="mw-collapsible mw-collapsed">
 
'''Текст программы на языке JavaScript (разработчик [[Дрепин Михаил]]):'''
 
<div class="mw-collapsible-content">
 
Файл '''"Code.js"'''
 
<syntaxhighlight lang="javascript" line start="1" enclose="div">
 
window.addEventListener("load", program_code, false);
 
var ctx; //Поле canvas_example
 
var xx1, yy1, xx2, yy2; //координаты тела в данный момент - в статичной прорисовке
 
var koef; //коэфициент масштаба для прорисовки сетки, тел и т.д.
 
var w; //ширина поля
 
var h;//высота поля
 
var vrem=1;//переменная для изменения скорости отрисовки
 
var kx=0, ky=0; //переменная положения мыши для вектора скорости
 
var dx=0, dy=0;  //сдвиг поля - обнуляемая переменная
 
var px=0, py=0; //сдвиг поля (по X и по Y)
 
var intervalID; //переменная для функции setInterval (для остановки прорисовки)
 
var Switch=0; //переменная для кнопки - бесконечное/конечное постоение
 
var second_obj=0; //переменная-индикатор слежения за 1 телом ("==1" - активно, "==0" - отключено)
 
var first_obj=0; //переменная-индикатор слежения за 2 телом ("==1" - активно, "==0" - отключено)
 
var idi=0; //переменная для кнопок запустить/пауза/продолжить:
 
/*idi:
 
  "==2" - активна прорисовка анимации (нажата "Запустить");
 
  "==1" - анимация приостановлена (нажата "Остановить");
 
  "==0" - анимация полностью остановлена или не запускалась
 
*/
 
var n = 0; //номер активного элемента массива (X/Y/T/V/A)
 
var t = []; //массив "времени"
 
var T=100; //максимальное "время"
 
var a1x = a2x = a1y = a2y = []; //массивы ускорений
 
var vx1 = vx2 = vy1 = vy2 = []; //массивы скоростей
 
var x1 = y1 = x2 = y2 = []; //массивы координат
 
var m1, m2 //масса синего/красного тела
 
var q1, q2, q; //Заряды тел (синего/красного/произведение)
 
const kulkof=8.9875517873681764*3.1; //Н·м2/Кл2 - константа закона Кулона
 
const dt=0.0001; // Шаг времен
 
document.oncontextmenu = function (e) {return false}; //Заблокировать контекстное меню
 
function program_code() {    //Часть кода, запускающаяся при загрузке страницы
 
  ctx = canvas_example.getContext("2d");
 
  w = canvas_example.width;
 
  h = canvas_example.height;
 
  //параметры для слайдера "Масштаба"
 
  Slider_01.value = 20;
 
    Slider_01.min = 5;
 
    Slider_01.max = 90;
 
    Slider_01.step = 1;
 
  Text_01.value = Slider_01.value;
 
  koef = parseFloat(Slider_01.value);
 
  canvas_static_func(); //первоначальная прорисовка
 
  time_code(); //включение временного масштаба
 
  start.onclick = Start; //клик по кнопке Запустить
 
  pauseplay.onclick = PausePlay; //клик по кнопке Остановить/Продолжить
 
  telo1.onclick = first_t; //слежение за синим телом
 
  telo2.onclick = second_t; //слежение за красным телом
 
  switcher.onclick = SwitchForInf; //клик по кнопке "бесконечная прорисовка"
 
  returner.onclick = function(){ //Обратная прорисовка
 
    if (vrem>0) { //если выключена
 
      vrem=-vrem; //включить
 
      document.getElementById("returner").innerHTML= "Включить прямую анимацию";
 
      if (idi==1&&n!=0) { //если включена пауза
 
        document.getElementById("text_u").innerHTML= "Остановить ";
 
        animation(); idi=2;
 
      }
 
    } else if (vrem<0) { //если включена
 
        vrem=-vrem; //выключить
 
        document.getElementById("returner").innerHTML= "Включить обратную анимацию";
 
    }
 
  }
 
  /*Изменение масштаба колёсиком*/
 
  var elem = document.getElementById('canvas_example');
 
    if (elem.addEventListener) { //если в окне canvas_example крутится колёсико (для разных браузеров)
 
      if ('onwheel' in document) {
 
        // IE9+, FF17+
 
        elem.addEventListener("wheel", onWheel);
 
      } else if ('onmousewheel' in document) {
 
        // устаревший вариант события
 
        elem.addEventListener("mousewheel", onWheel);
 
      } else {
 
        // Firefox < 17
 
        elem.addEventListener("MozMousePixelScroll", onWheel);
 
      }
 
    } else { // IE8-
 
      elem.attachEvent("onmousewheel", onWheel);
 
    }
 
  function onWheel(e) {
 
    //e = e || window.event;
 
    // deltaY, detail содержат пиксели
 
    // wheelDelta не дает возможность узнать количество пикселей
 
    // onwheel || MozMousePixelScroll || onmousewheel
 
    var m = mouseCoords(e); //получаем координаты курсора
 
    var delta = e.deltaY || e.detail || e.wheelDelta;
 
    var wheel_x=(m.x-20)/koef; //разность координаты по оси X положения курсора мыши и координаты левого края
 
    var wheel_y=(h-m.y-20)/koef; //разность координаты по оси Y положения курсора мыши и координаты нижнего края
 
    Slider_01.value = Slider_01.value - delta/100; //меняем ползунок слайдера масштаба
 
    Text_01.value=Slider_01.value; //меняем численное значение в окне масштаба
 
      if (first_obj==0&&second_obj==0) { //если не включено слежение за телами
 
        px=px*(koef-delta/100)/koef+m.x-wheel_x*(koef-delta/100)-20;
 
        py=py*(koef-delta/100)/koef+m.y-(h-(wheel_y*(koef-delta/100)))+20;
 
        /*сдвиги по Х и Y складывается из старого сдвига и сдвига,
 
        необходимого для фиксации положения точки с некоторыми координатами,
 
        соответствующими положению мыши*/
 
      }
 
      if (idi!=2) {
 
        xx1=(xx1-20)*(koef-delta/100)/koef+20;
 
        yy1=h-((h-(yy1+20))*(koef-delta/100)/koef+20);
 
        xx2=(xx2-20)*(koef-delta/100)/koef+20;
 
        yy2=h-((h-(yy2+20))*(koef-delta/100)/koef+20);
 
        canvas_static_func(); // запускаем статичную рисовалку
 
      }
 
      koef=parseFloat(Slider_01.value); //обновляем коэфициент масштаба
 
      e.preventDefault ? e.preventDefault() : (e.returnValue = false); //отменяем прокрутку страницы
 
    }
 
  Text_01.oninput = function() {
 
    if (!this.checkValidity()) return;
 
    document.getElementById('Slider_01').value = this.value;
 
    app.set_01(this.value);
 
  };
 
  Slider_01.oninput = function() {
 
    document.getElementById('Text_01').value = this.value;
 
    app.set_01(this.value);
 
  }
 
  Text_02.oninput = function() {
 
    if (!this.checkValidity()) return;
 
    app2.set_02(this.value);
 
    document.getElementById('Slider_01').value = this.value;
 
  };
 
  Slider_02.oninput = function() {
 
    app2.set_02(this.value);
 
    document.getElementById('Text_02').value = this.value;
 
  };
 
  if (idi!=2){ //Если не включена прорисовка, то изменение координат в таблице влечёт изменение положения тел на экране
 
    iksi.onchange = canvas_static_func;
 
    igri.onchange = canvas_static_func;
 
    iksii.onchange = canvas_static_func;
 
    igrii.onchange = canvas_static_func;
 
  }
 
}
 
function SwitchForInf() {    //переключатель "бесконечное/конечное постоение"
 
  if (Switch==0) {
 
    document.getElementById("switch_span").innerHTML= "Выключить бесконечное построение";
 
    Switch=1;
 
  } else {
 
    document.getElementById("switch_span").innerHTML= "Включить бесконечное построение";
 
    Switch=0;   
 
  };
 
}
 
function first_t() {    //функция слежения за синим телом
 
  if (first_obj==0) { //слеженеие за синим телом не активно
 
    first_obj=1; //включить слежение за синим телом
 
    second_obj=0; //отключить слежение за красным
 
    document.getElementById("text_sl_1").innerHTML= "Прекратить слежение";
 
    document.getElementById("text_sl_2").innerHTML= "Следить за красным телом";
 
  } else { //слеженеие за синим телом активно
 
    first_obj=0; //отключить слежение за синим телом
 
  document.getElementById("text_sl_1").innerHTML= "Следить за синим телом";     
 
  };
 
  if (idi!=2&&first_obj==1) { //если не включена анимация
 
    px=w/2-xx1; //смещение по X - такое, что 1 тело по центру
 
    py=h/2-yy1; //смещение по Y - такое, что 1 тело по центру
 
    canvas_static_func(); //нарисовать
 
  }
 
}
 
function second_t() {    //функция слежения за красным телом
 
  if (second_obj==0) { //слеженеие за красным телом не активно
 
    second_obj=1;  //включить слежение за красным телом
 
    first_obj=0; //отключить слежение за синим
 
    document.getElementById("text_sl_2").innerHTML= "Прекратить слежение";
 
    document.getElementById("text_sl_1").innerHTML= "Следить за синим телом";
 
  }
 
  else { //слеженеие за красным телом активно
 
    second_obj=0;  //отключить слежение за красным телом
 
    document.getElementById("text_sl_2").innerHTML= "Следить за красным телом";     
 
  }
 
     
 
  if (idi!=2&&second_obj==1) {
 
    px=w/2-xx2;
 
    py=h/2-yy2;
 
    canvas_static_func();
 
  }
 
}
 
function save() {    //сохранение активных элементов (участвуют в анимации) массивов в таблицы
 
  skor(); //скорости
 
  koord(); //координат
 
}
 
function koord() {    //сохранение координат
 
  iksi.value = Math.round(x1[20*n]*100)/100;
 
  igri.value = Math.round(y1[20*n]*100)/100;
 
  iksii.value = Math.round(x2[20*n]*100)/100;
 
  igrii.value = Math.round(y2[20*n]*100)/100; 
 
}
 
function skor () {    //сохранение скоростей
 
  vxi.value = Math.round(vx1[20*n]*10000)/10000;
 
  vyi.value = Math.round(vy1[20*n]*10000)/10000;
 
  vxii.value = Math.round(vx2[20*n]*10000)/10000;
 
  vyii.value = Math.round(vy2[20*n]*10000)/10000;
 
}
 
function mouseCoords(e) { //функция, определяющая координаты мыши (в пикселях) внутри canvas_example
 
        var m = [];
 
        var rect = canvas_example.getBoundingClientRect(); //координаты canvas_example относительно окна
 
        m.x = e.clientX - rect.left; //координаты курсора в canvas_example по X: положение курсора - расстояние до поля слева
 
        m.y = e.clientY - rect.top; //координаты курсора в canvas_example по Y: положение курсора - расстояние до поля сверху
 
        return m;
 
}
 
function canvas_static_func() {    //прорисовка во время паузы
 
  var click; //Идентификатор клика
 
  /*click:
 
  "==1" - клик ЛКМ по синему телу
 
  "==2" - клик ЛКМ по красному телу
 
  "==3" - клик ЛКМ по полю
 
  "==4" - клик ПКМ по синему телу
 
  "==5" - клик ПКМ по красному телу
 
  */
 
  var vxx1, vxx2, vyy1, vyy2; //координаты скорости при прорисовке векторов
 
  var r = 15; //условный радиус обоих тел
 
    var xShift, yShift;
 
  ctx = canvas_example.getContext("2d");
 
  koef = parseFloat(Text_01.value);
 
  m1=parseFloat(mi.value); //1а.е.м = 1.6606*10^-27 кг - масса для создания масштаба
 
  m2=parseFloat(mii.value); //1а.е.м = 1.6606*10^-27 кг - масса для создания масштаба
 
  if (idi!=1) {    //если не включена пауза, то при вызове canvas_static_func() сохранить значения из таблицы
 
    xx1 = 20+parseFloat(iksi.value)*koef;
 
    yy1 = h-(20+parseFloat(igri.value)*koef); 
 
    xx2 = 20+parseFloat(iksii.value)*koef;
 
    yy2 = h-(20+parseFloat(igrii.value)*koef);
 
  }
 
  if (idi!=2) {    //если не включена анимация, то при вызове canvas_static_func() запускать отрисовку
 
    draw_static();
 
  }
 
  this.set_01 = function(input) {
 
    var Old_koef=koef; //переменная для сохранения значения koef до его изменения
 
    koef=parseFloat(Slider_01.value); //меняем koef
 
    if (first_obj==0&&second_obj==0) { //если не включено слежение за телами
 
        px=px*koef/Old_koef+w/2-(w/2-20)*koef/Old_koef-20;
 
        py=py*koef/Old_koef+h/2-(h-(h/2-20)*koef/Old_koef)+20;
 
        /*сдвиги по Х и Y складывается из старого сдвига и сдвига,
 
        необходимого для фиксации положения центра*/
 
        koef=parseFloat(Slider_01.value); //обновляем коэфициент масштаба
 
      }
 
    if (idi!=2) {
 
      xx1=(xx1-20)*koef/Old_koef+20;
 
      yy1=h-((h-(yy1+20))*koef/Old_koef+20);
 
      xx2=(xx2-20)*koef/Old_koef+20;
 
      yy2=h-((h-(yy2+20))*koef/Old_koef+20);
 
      draw_static();
 
    }
 
  }
 
// функция запускается при нажатии клавиши мыши 
 
    function draw_static() { 
 
    koef=parseFloat(Slider_01.value);
 
    /*Учитываем  условие слежения за синим/красным телом*/
 
    if (second_obj==1) {
 
      px=w/2-(dx+xx2);
 
      py=h/2-(dy+yy2);
 
    }
 
    if (first_obj==1) {
 
      px=w/2-(dx+xx1);
 
      py=h/2-(dy+yy1);
 
    }
 
   
 
    field(); //нарисовать поле, сетку и расставить числа на осях
 
    ctx.beginPath();    //синий шарик
 
        ctx.arc(dx+xx1+px, dy+yy1+py, (m1/(m1+m2)+2/3)*koef/4, 0, 2 * Math.PI);
 
    ctx.fillStyle="#6666ff";
 
    ctx.closePath();
 
        ctx.fill();
 
   
 
    ctx.beginPath();    //красный шарик
 
        ctx.arc(dx+xx2+px, dy+yy2+py, (m2/(m1+m2)+2/3)*koef/4, 0, 2 * Math.PI);
 
    ctx.fillStyle="red";
 
    ctx.closePath();
 
        ctx.fill();
 
   
 
    /* Прорисовка векторов в визуальном редакторе по ПКМ */
 
    if(click==5||click==4) {
 
      ctx.beginPath();
 
        var xxx1=xx2+px;
 
        var xxx2=vxx2+px;
 
        var yyy1=yy2+py;
 
        var yyy2=vyy2+py;
 
        var path=Math.sqrt((xxx2-xxx1)*(xxx2-xxx1)+(yyy2-yyy1)*(yyy2-yyy1)); //длина вектора скорости
 
        var x0=xxx1+(1-Math.pow(path,-0.45))*(xxx2-xxx1);
 
        var y0=yyy1+(1-Math.pow(path,-0.45))*(yyy2-yyy1);
 
        ctx.moveTo(xxx1, yyy1); //начало вектора - координаты тела
 
        ctx.lineTo(xxx2, yyy2);
 
        ctx.lineTo(x0+(Math.pow(path,0.3))*(yyy2-yyy1)/path, y0-(Math.pow(path,0.3))*(xxx2-xxx1)/path);
 
        ctx.lineTo(x0-(Math.pow(path,0.3))*(yyy2-yyy1)/path, y0+(Math.pow(path,0.3))*(xxx2-xxx1)/path);
 
        ctx.lineTo(xxx2, yyy2);
 
      ctx.closePath();
 
      ctx.fillStyle="#000";
 
      ctx.fill();
 
      ctx.strokeStyle="#000";
 
      ctx.stroke();
 
    }
 
    if(click==4||click==5) {
 
      ctx.beginPath();
 
        var xxx1=xx1+px;
 
        var xxx2=vxx1+px;
 
        var yyy1=yy1+py;
 
        var yyy2=vyy1+py;
 
        var path=Math.sqrt((xxx2-xxx1)*(xxx2-xxx1)+(yyy2-yyy1)*(yyy2-yyy1));
 
        var x0=xxx1+(1-Math.pow(path,-0.45))*(xxx2-xxx1);
 
        var y0=yyy1+(1-Math.pow(path,-0.45))*(yyy2-yyy1);
 
        ctx.moveTo(xxx1, yyy1);
 
        ctx.lineTo(xxx2, yyy2);
 
        ctx.lineTo(x0+(Math.pow(path,0.3))*(yyy2-yyy1)/path, y0-(Math.pow(path,0.3))*(xxx2-xxx1)/path);
 
        ctx.lineTo(x0-(Math.pow(path,0.3))*(yyy2-yyy1)/path, y0+(Math.pow(path,0.3))*(xxx2-xxx1)/path);
 
        ctx.lineTo(xxx2, yyy2);
 
        ctx.fillStyle="#000";
 
      ctx.closePath();
 
      ctx.fill();
 
      ctx.strokeStyle="#000";
 
      ctx.stroke();
 
    }
 
    }
 
    canvas_example.onmousedown = function(e) {    // функция запускается при нажатии клавиши мыши
 
        var m = mouseCoords(e);
 
        var xc1 = xx1+px - m.x;
 
        var yc1 = yy1+py - m.y;
 
    var rLen1 = xc1 * xc1 + yc1 * yc1;
 
    var xc2 = xx2+px - m.x;
 
        var yc2 = yy2+py - m.y;
 
        var rLen2 = xc2 * xc2 + yc2 * yc2;
 
    if (e.which == 1) { //клик ЛКМ
 
      if (rLen1 <= r * r) {
 
        if (n!==0&&idi!=2) skor();  //Сохранение скорости из массива при клике по телу во время паузы
 
        if (rLen1>rLen2) {
 
          xShift = xx2 - m.x;
 
          yShift = yy2 - m.y;
 
          click=2; //Перемещение красного тела
 
          canvas_example.onmousemove = mouseMove;
 
        } else {
 
          xShift = xx1 - m.x;
 
          yShift = yy1 - m.y;
 
          click=1; //Перемещение синего тела
 
          canvas_example.onmousemove = mouseMove;
 
        }
 
      }  else if (rLen2 <= r * r) {
 
        if (n!==0&&idi!=2) skor();  //Сохранение скорости из массива при клике по телу во время паузы
 
        if (rLen2>rLen1) {
 
          xShift = xx1 - m.x;
 
          yShift = yy1 - m.y;
 
          click=1; //Перемещение синего тела
 
          canvas_example.onmousemove = mouseMove;
 
        }  else {
 
          xShift = xx2 - m.x;
 
          yShift = yy2 - m.y;
 
          click=2; //Перемещение красного тела
 
          canvas_example.onmousemove = mouseMove;
 
        }
 
      }
 
      else {
 
        click=3; //Клик по полю
 
        kx=m.x;
 
        ky=m.y;
 
        canvas_example.onmousemove = mouseMove;
 
      }
 
    }
 
    if (e.which == 3){ //Клик ПКМ
 
      if (rLen1 <= r * r) { //попадание по синему телу
 
        if (rLen1>rLen2) { //расстояние до центра красного меньше, чем расстояние дл центра синего
 
          click=5; //Изменение вектора скорости красного тела
 
          canvas_example.onmousemove = mouseMove;
 
        } else {
 
          click=4; //Изменение вектора скорости синего тела
 
          canvas_example.onmousemove = mouseMove;
 
        }
 
      }
 
      else if (rLen2 <= r * r) { //попадание по красному телу
 
        if (rLen2>rLen1) { //расстояние до центра синего меньше, чем расстояние дл центра красного
 
          click=4; //Изменение вектора скорости синего тела
 
          canvas_example.onmousemove = mouseMove;
 
        } else {
 
          click=5; //Изменение вектора скорости красного тела
 
          canvas_example.onmousemove = mouseMove;
 
        }
 
      }
 
    }
 
};
 
    canvas_example.onmouseup = function() {
 
    if (click==3) {
 
      px=px+dx;
 
      py=py+dy;
 
      kx=ky=dx=dy=0;
 
    }
 
        canvas_example.onmousemove = null;
 
    };
 
  function mouseMove(e) {
 
    var m = mouseCoords(e);
 
    if (idi!=2) {
 
      if (click==1) {
 
        xx1 = m.x + xShift;
 
        yy1 = m.y + yShift; 
 
        iksi.value = (xx1-20)/koef;
 
        igri.value = (h-(yy1+20))/koef;
 
        draw_static();
 
        };
 
      if (click==2) {
 
        xx2 = m.x + xShift;
 
        yy2 = m.y + yShift;
 
        iksii.value = (xx2-20)/koef;
 
        igrii.value = (h-(yy2+20))/koef;
 
        draw_static();
 
        };
 
    }
 
      if (click==3) {
 
        dx=m.x-kx;
 
        dy=m.y-ky;
 
        if (idi!=2) draw_static();
 
        };
 
    if (idi!=2) {
 
      if (click==4) {
 
        vxx1 = m.x-px;
 
        vyy1 = m.y-py;
 
        vxi.value = (vxx1-xx1)/koef;
 
        vyi.value = (yy1-vyy1)/koef;
 
        iksi.value = (xx1-20)/koef;
 
        igri.value = (h-(yy1+20))/koef;
 
        iksii.value = (xx2-20)/koef;
 
        igrii.value = (h-(yy2+20))/koef;
 
        draw_static();
 
        };
 
      if (click==5) {
 
        vxx2 = m.x-px;
 
        vyy2 = m.y-py;
 
        vxii.value = (vxx2-xx2)/koef;
 
        vyii.value = (yy2-vyy2)/koef;
 
        iksi.value = (xx1-20)/koef;
 
        igri.value = (h-(yy1+20))/koef;
 
        iksii.value = (xx2-20)/koef;
 
        igrii.value = (h-(yy2+20))/koef;
 
        draw_static();
 
      };
 
    };
 
  };
 
}
 
function time_code() {    //временной масштаб
 
  Slider_02.min = 1;
 
    Slider_02.max = 90;
 
    Slider_02.step = 1;
 
  Slider_02.value = 1;
 
  Text_02.value = Slider_02.value;
 
  this.set_02 = function(input) {      //запуск при изменении значения set_02
 
    vrem=Math.sign(vrem)*parseFloat(Slider_02.value); //изменение переменной скорости отрисовки
 
  }
 
}
 
function Start() {    //Старт по кнопке "Запустить"
 
  buttonStart(); //функция, сообщающая, что старт совершён по кнопке "Запустить": порядок прорисовки прямой, с нулевого элемента
 
  animation(); //запуск анимации
 
}
 
function buttonStart() {    //Изменение значений кнопок и идентификатора idi
 
document.getElementById("returner").innerHTML= "Включить обратную анимацию";
 
document.getElementById("text_u").innerHTML= "Остановить ";
 
idi=2;
 
}
 
function PausePlay() {    //Кнопка "Остановить/Продолжить"
 
  if (idi!=1) { //Если пауза не включена
 
    clearInterval(intervalID); //остановить прорисовку
 
    document.getElementById("text_u").innerHTML= "Продолжить";
 
    idi=1; //активировать паузу
 
  }
 
  else { //иначе
 
    if (n!==0) { //если уже была включена анимация, следовательно кнопка нажата во время паузы
 
      document.getElementById("text_u").innerHTML= "Остановить "; animation(); idi=2; //запустить прорисовку
 
    };
 
    if (n==0) {  //если анимация не включалась
 
    document.getElementById("text_u").innerHTML= "Остановить "; idi=0;
 
    }
 
  }
 
}   
 
function animation(){    //анимация движения частиц
 
  clearInterval(intervalID);  //обнулять старый интервал при каждом новом запуске анимации
 
  koef=parseFloat(Slider_01.value);
 
  function A(a1,a2,b1,b2,q,m) { //рассчёт ускорения тела из условия взаимного притяжения/отталкивания двух тел по закону Кулона
 
    var r=Math.sqrt((a2-a1)*(a2-a1)+(b2-b1)*(b2-b1));
 
    return (-1)*kulkof*q*(a2-a1)/(m*r*r*r)
 
  };
 
  if (idi==2) { //если система запущена по кнопке "Запустить"
 
    physics(); //сосчитать массивы координат и скоростей
 
    n=0; //обнулить переменную, пробегающую массивы
 
  }
 
  function physics() {
 
    vrem=Math.abs(vrem);
 
    t = [];
 
    a1x = []; a2x = [];  a1y = []; a2y = [];
 
    vx1 = []; vx2 = [];  vy1 = []; vy2 = [];
 
    x1 = []; y1 = []; x2 = []; y2 = [];
 
    t[0]=0;
 
    x1[0]=parseFloat(iksi.value);
 
    y1[0]=parseFloat(igri.value);
 
    x2[0]=parseFloat(iksii.value);
 
    y2[0]=parseFloat(igrii.value);
 
    vx1[0]=parseFloat(vxi.value);
 
    vy1[0]=parseFloat(vyi.value);
 
    vx2[0]=parseFloat(vxii.value);
 
    vy2[0]=parseFloat(vyii.value);
 
    m1=parseFloat(mi.value);
 
    m2=parseFloat(mii.value);
 
    q1=parseFloat(qi.value);
 
    q2=parseFloat(qii.value);
 
    q=q1*q2;
 
    a1x[0]= A(x1[0],x2[0],y1[0],y2[0],q,m1);
 
    a1y[0]= A(y1[0],y2[0],x1[0],x2[0],q,m1);
 
    a2x[0]= A(x2[0],x1[0],y1[0],y2[0],q,m2);
 
    a2y[0]= A(y2[0],y1[0],x1[0],x2[0],q,m2);
 
    var i=0;
 
    while (t[i] < T) {
 
      vx1[i+1]= vx1[i]+a1x[i]*dt;
 
      vy1[i+1]= vy1[i]+a1y[i]*dt;
 
      vx2[i+1]= vx2[i]+a2x[i]*dt;
 
      vy2[i+1]= vy2[i]+a2y[i]*dt;
 
     
 
      x1[i+1] = x1[i]+vx1[i+1]*dt;
 
      y1[i+1] = y1[i]+vy1[i+1]*dt;
 
      x2[i+1] = x2[i]+vx2[i+1]*dt;
 
      y2[i+1] = y2[i]+vy2[i+1]*dt;
 
     
 
      a1x[i+1]= A(x1[i+1],x2[i+1],y1[i+1],y2[i+1],q,m1);
 
      a1y[i+1]= A(y1[i+1],y2[i+1],x1[i+1],x2[i+1],q,m1);
 
      a2x[i+1]= A(x2[i+1],x1[i+1],y1[i+1],y2[i+1],q,m2);
 
      a2y[i+1]= A(y2[i+1],y1[i+1],x1[i+1],x2[i+1],q,m2);
 
      t[i+1]=t[i]+dt;
 
      i=i+1;
 
    }
 
  }
 
  function draw_dinamic() {
 
    field(); //Прорисовка поля
 
    /*Учитываем  условие слежения за синим/красным телом*/
 
    if (second_obj==1) {
 
      px=w/2-(dx+20+x2[20*n]*koef);
 
      py=-h/2-(dy-(20+y2[20*n]*koef));
 
    }
 
    if (first_obj==1) {
 
      px=w/2-(dx+20+x1[20*n]*koef);
 
      py=-h/2-(dy-(20+y1[20*n]*koef));
 
    }
 
    ctx.beginPath(); //рисуем синее тело
 
    ctx.arc(px+dx+20+x1[20*n]*koef,py+dy+h-(20+y1[20*n]*koef), 1/4*(m1/(m1+m2)+2/3)*koef, 0, Math.PI*2);
 
      ctx.fillStyle = "#6666ff";
 
    ctx.closePath();
 
    ctx.fill();
 
 
    ctx.beginPath(); //рисуем красное тело
 
    ctx.arc(px+dx+20+x2[20*n]*koef,py+dy+h-(20+y2[20*n]*koef), 5*(m2/(m1+m2)+2/3)*koef/20, 0, Math.PI*2);
 
      ctx.fillStyle = "red";
 
    ctx.closePath();
 
    ctx.fill();
 
   
 
    xx1=20+x1[20*n]*koef; yy1=h-(20+y1[20*n]*koef); //положение синего тела сохраняем для визуального редактирования
 
    xx2=20+x2[20*n]*koef; yy2=h-(20+y2[20*n]*koef); //положение красного тела сохраняем для визуального редактирования
 
    n=n+vrem;
 
  }
 
  function control() {
 
    draw_dinamic();
 
    if(n>=(t.length/20-vrem)){
 
    n=n-vrem; //возвращаем n к значению, соответствующему одному из последних существующих элементов массива
 
      if (Switch==1) { //Если включено бексконечное построение
 
        save(); //Сохранять последнее значение координат и скоростей
 
        idi=2; //Инициировать запуск системы по кнопке
 
        animation(); //И запускать прорисовку с новыми элементами массивов
 
      } else if (Switch==0) { //Если выключено бексконечное построение
 
        clearInterval(intervalID); //остановить прорисовку
 
        draw_dinamic(); //Нарисовать положение в последний момент
 
        idi=0; //Инициировать остановку анимации
 
      }
 
    }
 
    if (n<0) { //Если перемотка привела к началу массивов/начальному положению системы тел
 
      clearInterval(intervalID); //остановить прорисовку
 
      n=0; //Вернуться к начальным условиям
 
      vrem=-vrem; //нормальный ход времени
 
      draw_dinamic();  //Нарисовать тела
 
      idi=0; //Инициировать остановку анимации
 
    }
 
  }
 
  intervalID=setInterval(control,1); //Выполнение "control", обеспечивающего прорисовку анимации, через 1 миллисекунду
 
}
 
function field() {    //Функция прорисовки поля
 
  ctx.clearRect(0, 0, w, h);
 
  ctx.fillStyle = 'white';
 
  ctx.fillRect(20, 20, w-40, h-40);
 
  ctx.strokeStyle = 'black';
 
  ctx.strokeRect(20, 20, w-40, h-40);
 
  ctx.fillStyle = 'black';
 
  ctx.font = "bold italic 20px Times";
 
  ctx.fillText("x", w-15, h - 20);
 
  ctx.fillText("y", 15, 15);
 
  ctx.font = "italic 16px Times";
 
  ctx.fillText(0, 1.5, h - 4.5);
 
  /*Сетка*/
 
  for (var k = dx+px+20+koef; k < w-20; k = k+koef) {
 
    ctx.beginPath();
 
    if (k>20) {
 
      ctx.moveTo(k,h-20);
 
      ctx.lineTo(k,20);
 
      ctx.strokeStyle = "#cab0b0";
 
      ctx.closePath();
 
      ctx.stroke();
 
    }
 
  }
 
  for (var k = dx+px+20; (k > 0); k = k-koef) {
 
    ctx.beginPath();
 
    if (k>20&&k<w-20) {
 
      ctx.moveTo(k,h-20);
 
      ctx.lineTo(k,20);
 
      ctx.strokeStyle = "#cab0b0";
 
      ctx.closePath();
 
      ctx.stroke();
 
    }
 
  }
 
  for (var u = dy+h+py-20-koef; u >20 ; u = u-koef) {
 
    ctx.beginPath();
 
    if (u<h-20) {
 
      ctx.strokeStyle = "#cab0b0";
 
      ctx.moveTo(20, u);
 
      ctx.lineTo(w-20, u);
 
      ctx.closePath();
 
      ctx.stroke();
 
      }
 
    }
 
  for (var u = dy+h+py-20; u < h ; u = u+koef) {
 
    ctx.beginPath();
 
    if (u<h-20&&u>20) {
 
      ctx.strokeStyle = "#cab0b0";
 
      ctx.moveTo(20, u);
 
      ctx.lineTo(w-20, u);
 
      ctx.closePath();
 
      ctx.stroke();
 
      }
 
    }
 
  /* "+5" нумерация */
 
  if (koef<20) {
 
  for (var oy = dy+py+h-15-5*koef, ooy=5; oy>20; oy=oy-5*koef) {
 
    ctx.fillStyle = 'black';
 
        ctx.font = "italic 16px Times";
 
    if (oy<h-20) {
 
      ctx.fillText(ooy, 1.5, oy);
 
      }
 
    ooy+=5;
 
    }
 
  for (var oy = dy+h+py-15, ooy=0; oy<h; oy=oy+5*koef) {
 
    ctx.fillStyle = 'black';
 
        ctx.font = "italic 16px Times";
 
    if (oy<h-20&&oy>20) {
 
      ctx.fillText(ooy, 1.5, oy);
 
      }
 
    ooy-=5;
 
    }
 
  for (var ox = dx+px+15.5+5*koef, oox=5; ox<w-20; ox=ox+5*koef) {
 
    ctx.fillStyle = 'black';
 
        ctx.font = "italic 16px Times";
 
    if (ox>20) {
 
      ctx.fillText(oox, ox, h-2);
 
      }
 
    oox+=5;
 
    }
 
  for (var ox = dx+px+15.5, oox=0; ox>0; ox=ox-5*koef) {
 
    ctx.fillStyle = 'black';
 
        ctx.font = "italic 16px Times";
 
    if (ox>20&&ox<w-20) {
 
      ctx.fillText(oox, ox, h-2);
 
      }
 
    oox-=5;
 
    }
 
  }
 
  /* Простая нумерация */
 
  else {
 
  for (var oy = dy+h+py-15-koef, ooy=1; oy>20; oy=oy-koef) {
 
    ctx.fillStyle = 'black';
 
        ctx.font = "italic 16px Times";
 
    if (oy<h-20) {
 
    ctx.fillText(ooy, 1.5, oy);
 
      }
 
    ooy++;
 
    }
 
  for (var ox = dx+px+15.5+koef, oox=1; ox<w-20; ox=ox+koef) {
 
    ctx.fillStyle = 'black';
 
        ctx.font = "italic 16px Times";
 
    if (ox>20) {
 
      ctx.fillText(oox, ox, h-2);
 
      }
 
    oox++;
 
    if (oox>100) {    //После X=100 единицы масштаба наносятся через 5 клеток
 
      ox=ox+4*koef;
 
      oox=oox+4;
 
      }
 
    }
 
  for (var oy = dy+h+py-15, ooy=0; oy<h; oy=oy+koef) {
 
    ctx.fillStyle = 'black';
 
        ctx.font = "italic 16px Times";
 
    if (oy<h-20&&oy>20) {
 
      ctx.fillText(ooy, 1.5, oy);
 
      }
 
    ooy--;
 
    }
 
  for (var ox = dx+px+15.5, oox=0; ox>0; ox=ox-koef) {
 
    ctx.fillStyle = 'black';
 
        ctx.font = "italic 16px Times";
 
    if (ox>20&&ox<w-20) {
 
      ctx.fillText(oox, ox, h-2);
 
      }
 
    oox--;
 
    if (oox<-10) {    //До X=-10 единицы масштаба наносятся через 5 клеток
 
      ox=ox-4*koef;
 
      oox=oox-4;
 
      }
 
    }
 
  }
 
}
 
</syntaxhighlight>
 
Файл '''"culon.html"'''
 
<syntaxhighlight lang="html5" line start="1" enclose="div">
 
<!DOCTYPE html>
 
<html>
 
<head>
 
  <meta charset="utf-8">
 
  <script src="Code.js"></script>
 
  <script src="bg.js"></script>
 
  <link rel="stylesheet" type="text/css" href="style.css" />
 
  <title>Взаимодействие двух заряженных тел (Закон Кулона)</title>
 
</head>
 
<body>
 
  <canvas id="canvas_bg" class="canvas_bg"></canvas>
 
  <div class="main" id="main">
 
    <div id="workspace"  style="float:right; margin-right: 20px;"><canvas  id="canvas_example" class="canvas_example" width="750" height="550"></canvas>
 
    </div>
 
  <div style="float:left; text-align: center; margin-left: 20px;">
 
    <p>Масштаб:
 
      <I>1 м.</I> = <input id="Text_01" style="width: 2.2ex;" required pattern="[-+]?([0-9]*\.[0-9]+|[0-9]+)" > пкс.
 
      <input type="range" id="Slider_01" style="width: 100px;" value="20">
 
    </p>
 
    <p>FPS:<input id="Text_02" style="width: 2.2ex;" required pattern="[-+]?([0-9]*\.[0-9]+|[0-9]+)">
 
      <input type="range" id="Slider_02" style="width: 100px;">
 
    </p><br />
 
    <a href="#" id=start class="button">Запустить</a>
 
    <a href="#" id=pauseplay class="button"><SPAN id=text_u>Остановить&nbsp;</SPAN></a><br>
 
    <a href="#" id=linka class="button28" onclick="save(); canvas_static_func()">
 
      Сохранить координаты и скорость тел<br>для последующего запуска</a>  <br> 
 
  <h2>Синее тело</h2>
 
    <table>
 
    <tbody>
 
      <tr><th colspan="5">Координаты тела</th></tr>
 
      <tr><td><I>X: </I><input id=iksi type=number value=18></td>
 
      <td><I> Y: </I><input id=igri type=number value=12.71></td></tr>
 
      <tr><th colspan="5">Проекции скорости</th></tr>
 
      <tr><td><I>На OX: </I><input id=vxi type=number value=0></td>
 
      <td><I> на OY: </I><input id=vyi type=number value=0></td></tr>
 
      <tr><th colspan="5">Масса и заряд</th></tr>
 
      <tr><td><input id=mi type=number value=1670><I>x 10<sup>-30</sup>кг</I></td>
 
      <td><input id=qi type=number value=1><I> x 10<sup>-19</sup>Кл</I></td></tr>
 
    </tbody>
 
    </table>
 
      <h2>Красное тело</h2>
 
    <table>
 
    <tbody>
 
      <tr><th colspan="5">Координаты тела</th></tr>
 
      <tr><td><I>X: </I><input id=iksii type=number value=18></td>
 
      <td><I> Y: </I><input id=igrii type=number value=18.29></td></tr>
 
      <tr><th colspan="5">Проекции скорости</th></tr>
 
      <tr><td><I>X:</I><input id=vxii type=number value=2.22><I>x 10<sup>6</sup></I><sub>с</sub><sup>м</sup></td>
 
      <td><I>Y:</I><input id=vyii type=number value=0><I>x 10<sup>6</sup></I><sub>с</sub><sup>м</sup></td></tr>
 
      <tr><th colspan="5">Масса и заряд</th></tr>
 
      <tr><td><input id=mii type=number value=0.91><I>x 10<sup>-30</sup>кг</I></td>
 
      <td><input id=qii type=number value=-1><I>x 10<sup>-19</sup>Кл</I></td></tr>
 
    </tbody>
 
    </table>
 
    </div>
 
    <div class="follow" style="float: left" >
 
        <a style="background: #6666ff!important;" href="#" id=telo1 class="button28"><SPAN id=text_sl_1>Следить за синим телом</span></a>
 
        <a style="background: red!important;" href="#" id=telo2 class="button28"><SPAN id=text_sl_2>Следить за красным телом</span></a>
 
        <a href="#" id=switcher class="button28"><SPAN id=switch_span>Включить бесконечное построение</span></a>
 
        <a href="#" id=returner class="button28"><SPAN id=switch_span>Включить обратную анимацию</span></a>
 
      </div>
 
  </div>
 
<script type="text/javascript">
 
  var app = new canvas_static_func(document.getElementById('canvas_example'));
 
  var app2 = new time_code(document.getElementById('canvas_example'));
 
</script>
 
</body>
 
</html>
 
</syntaxhighlight>
 
Файл '''"bg.js"'''
 
<syntaxhighlight lang="javascript" line start="1" enclose="div">
 
window.addEventListener("load", program_code, false);
 
function program_code() {
 
var canvas = document.getElementById('canvas_bg')[0],
 
    ctx = null,
 
    grad = null,
 
    body = document.getElementsByTagName('body')[0],
 
    color = 255; //изначальный цвет фона сайта
 
 
if (canvas_bg.getContext('2d')) {
 
  ctx = canvas_bg.getContext('2d');
 
  ctx.clearRect(0, 0, 600, 600);
 
  ctx.save();
 
 
  // создание радиального градиента
 
  grad = ctx.createRadialGradient(0,0,0,0,0,600);
 
  grad.addColorStop(0, '#DFDFDF');
 
  grad.addColorStop(1, 'rgb(' + color + ', ' + color + ', ' + color + ')');
 
 
  // сам фон-градиент
 
  ctx.fillStyle = grad;
 
 
  first_time(); //при первом запуске
 
  function first_time() {
 
    var width = window.innerWidth,
 
      height = window.innerHeight,
 
      x = width/2,
 
      y = height/2,
 
      rx = 600 * x / width,
 
      ry = 600 * y / height;
 
     
 
    var xc = ~~(256 * x / width);
 
    var yc = ~~(256 * y / height);
 
 
    grad = ctx.createRadialGradient(rx, ry, 0, rx, ry, 500);  //размер указателя мышки
 
    grad.addColorStop(0, '#478CFB'); //цвет  указателя мышки
 
    grad.addColorStop(1, ['rgb(', xc, ', ', (255 - xc), ', ', yc, ')'].join(''));
 
    ctx.fillStyle = grad;
 
    ctx.fillRect(0,0,600,600);
 
  };
 
 
 
  body.onmousemove = function (event) {
 
    var width = window.innerWidth,
 
      height = window.innerHeight,
 
      x = event.clientX,
 
      y = event.clientY,
 
      rx = 600 * x / width,
 
      ry = 600 * y / height;
 
    var xc = ~~(256 * x / width);
 
    var yc = ~~(256 * y / height);
 
 
    grad = ctx.createRadialGradient(rx, ry, 0, rx, ry, 500);  //размер указателя мышки
 
    grad.addColorStop(0, '#478CFB'); //цвет  указателя мышки
 
    grad.addColorStop(1, ['rgb(', xc, ', ', (255 - xc), ', ', yc, ')'].join(''));
 
    //ctx.restore();
 
    ctx.fillStyle = grad;
 
    ctx.fillRect(0,0,600,600);
 
    // ctx.save();
 
  };
 
}
 
}
 
</syntaxhighlight>
 
Файл '''"style.css"'''
 
<syntaxhighlight lang="css" line start="1" enclose="div">
 
h2, h1 {
 
  margin: 10px 0 0 0;
 
  color: #fff;
 
  text-shadow: 1px 1px 1px black, 0 0 0.1em blue;;
 
}
 
.button {
 
  font-size: 18px;
 
  font-weight: 700;
 
  color: white;
 
  text-decoration: none;
 
  padding: .4em 1em calc(.4em + 3px);
 
  border-radius: 3px;
 
  background: rgb(64,199,129);
 
  box-shadow: 0 -3px rgb(53,167,110) inset;
 
  transition: 0.2s;
 
}
 
.button:hover { background: rgb(53, 167, 110); }
 
.button:active {
 
  background: rgb(33,147,90);
 
  box-shadow: 0 3px rgb(33,147,90) inset;
 
}
 
a.button28 {
 
  position: relative;
 
  display: inline-block;
 
  font-size: 90%;
 
  font-weight: 700;
 
  color: rgb(209,209,217);
 
  text-decoration: none;
 
  text-shadow: 0 -1px 2px rgba(0,0,0,.2);
 
  padding: .5em 1em;
 
  outline: none;
 
  border-radius: 3px;
 
  background: linear-gradient(rgb(110,112,120), rgb(81,81,86)) rgb(110,112,120);
 
  box-shadow:
 
  0 1px rgba(255,255,255,.2) inset,
 
  0 3px 5px rgba(0,1,6,.5),
 
  0 0 1px 1px rgba(0,1,6,.2);
 
  transition: .2s ease-in-out;
 
  margin-top: 10px;
 
}
 
a.button28:hover:not(:active) {
 
  background: linear-gradient(rgb(126,126,134), rgb(70,71,76)) rgb(126,126,134);
 
}
 
a.button28:active {
 
  top: 1px;
 
  background: linear-gradient(rgb(76,77,82), rgb(56,57,62)) rgb(76,77,82);
 
  box-shadow:
 
  0 0 1px rgba(0,0,0,.5) inset,
 
  0 2px 3px rgba(0,0,0,.5) inset,
 
  0 1px 1px rgba(255,255,255,.1);
 
}
 
input[type="number"] {
 
  border: 1px solid black;
 
  border-radius: 5px;
 
 
 
    color: #000000;
 
    padding: 3px;
 
    margin-top: 2px;
 
    margin-bottom: 2px;
 
    font-size: 16px;
 
    font-family: Verdana;
 
    background: #FFF;
 
  width: 70px;
 
}
 
input[type="number"]:focus {
 
  color: #000000;
 
  border: 1px solid #000000
 
}
 
canvas.canvas_bg {
 
  position: absolute; /* позиционирование */
 
  top: 0;    /* фиксируем */
 
  left: 0;    /* фиксируем */
 
  height: 100%; /* делаем фон резиновым */
 
  width: 100%;    /* делаем фон резиновым */
 
}
 
 
 
div.main {
 
    position: absolute;
 
    top:0;
 
    left:0;
 
    /*width:100%;
 
    height:100%;*/
 
}
 
sub + sup {
 
  margin-left: -0.4em;
 
}
 
 
/*Таблица*/
 
table {
 
border-spacing: 0;
 
text-align: center;
 
border-top-right-radius: 10px;
 
border-top-left-radius: 10px;
 
}
 
th {
 
background: rgba(101, 11, 95, 0.86);
 
color: white;
 
text-shadow: 0 1px 1px #2D2020;
 
padding: 0px;
 
}
 
th, td {
 
colspan: 5;
 
border-style: solid;
 
border-width: 0 1px 1px 0;
 
border-color: white;
 
}
 
th:first-child, td:first-child {
 
text-align: center;
 
}
 
th:first-child {
 
}
 
th:last-child {
 
 
border-right: none;
 
}
 
td {
 
padding: 1px 2px;
 
background: #ecfc95;
 
}
 
tr:last-child td:first-child {
 
border-radius: 0 0 0 10px;
 
}
 
tr:last-child td:last-child {
 
border-radius: 0 0 10px 0;
 
}
 
tr td:last-child {
 
border-right: none;
 
}
 
p{
 
margin:0;
 
}
 
 
.follow {
 
margin-left: 150px;
 
}
 
</syntaxhighlight>
 
</div>
 
</div>
 
 
 
Совместный проект студентов [[Дрепин_Михаил|Дрепина Михаила]] и [[Калинин_Илья|Калинина Ильи]]
 
 
[[Category: Виртуальная лаборатория]]
 
[[Category: Виртуальная лаборатория]]
 
[[Category: Программирование]]
 
[[Category: Программирование]]
 
[[Category: JavaScript]]
 
[[Category: JavaScript]]
Вам запрещено изменять защиту статьи. 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:

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