Chain v3
Материал из Department of Theoretical and Applied Mechanics
Версия от 18:52, 8 марта 2015; Wikiadmin (обсуждение | вклад) (Замена текста — «<source lang="(.*)" first-line="(.*)">» на «<syntaxhighlight lang="$1" line start="$2" enclose="div">»)
Виртуальная лаборатория > Динамика одномерного кристалла > Цепь - версии > Chain v3
Скачать программу: Chain_v3_release.zip Текст программы на языке JavaScript (разработчик Цветков Денис): <toggledisplay status=hide showtext="Показать↓" hidetext="Скрыть↑" linkstyle="font-size:default"> Файл "Chain_v3_release.js" <syntaxhighlight lang="javascript" line start="1" enclose="div"> function MainChain(canvas, vCanvas) {
// Предварительные установки
var context = canvas.getContext("2d"); // на context происходит рисование var vContext = vCanvas.getContext("2d");// на context происходит рисование
var Pi = 3.1415926; // число "пи"
var m0 = 1; // масштаб массы var T0 = 1; // масштаб времени (период колебаний исходной системы) var a0 = 1; // масштаб расстояния (диаметр шара)
var k0 = 2 * Pi / T0; // масштаб частоты var C0 = m0 * k0 * k0; // масштаб жесткости
// *** Задание физических параметров ***
var m = 1 * m0; // масса var C = 1 * C0; // жесткость var numStart = 24; // начальное количество частиц
// *** Задание вычислительных параметров ***
var fps = 50; // frames per second - число кадров в секунду (качечтво отображения) var spf = 10; // steps per frame - число шагов интегрирования между кадрами (скорость расчета) var dt = 0.4 * T0 / fps; // шаг интегрирования (качество расчета)
// Выполнение программы
var scale = canvas.height / a0; // масштабный коэффициент для перехода от расчетных к экранным координатам var wScale = canvas.width; // ширина окна в экранных координатах var hScale = canvas.height; // высота окна в экранных координатах var w = wScale / scale; // ширина окна в расчетных координатах var h = hScale / scale; // высота окна в расчетных координатах var chainHeightScale = hScale/2; // высота положения цепи в экранных координатах
// константы для графика скорости var vWScale = vCanvas.width; // ширина окна в экранных координатах var vHScale = vCanvas.height; // высота окна в экранных координатах var vHeightScale = vHScale/2; // высота графика скорости в экранных координатах var vAxisScale = vHScale * 0.4; // масштаб оси "y" графика скорости var uvWResize = vWScale/wScale; // пересчет ширины относительно основного окна
// Генерорование начальных условий
var particles; // массив частиц var num, pDist; // количество частиц и расстояние между шарами (в начальном положении) MainChain.prototype.setNum = function(n){num = n; pDist = w/(num-1);}; // задать новое количество частиц MainChain.prototype.setNum(numStart); var uAxisScale; // масштаб оси "y" цепи MainChain.prototype.newSystem = function(conf){ MainChain.prototype.actualConf = conf; particles = []; for (var i = 1; i < num + 1; i++) { var b = [];
b.x0 = pDist*(i-1); // расчетные координаты начального положения частицы b.x0Scale = b.x0*scale; // экранные координаты начального положения частицы b.fu = 0; b.vu = 0; b.uu = 0; // сила; скорость; смещение отн. нач. положения
conf(b, i); // конфигурации начальных условий заданы ниже particles[i] = b; // добавить элемент в массив }
// здесь задается периодическая система particles[0] = particles[num]; particles[num+1] = particles[1];
// уравновешивание суммарной скорости по оси х (чтобы частицы не улетали в сторону) var sumvu = 0; for (var i0 = 1; i0 < num+1; i0++) sumvu += particles[i0].vu; var vuAverage = sumvu/num; for (var i1 = 1; i1 < num+1; i1++) particles[i1].vu -= vuAverage;
// настройка оси "y" var confCoeff = 1; if (conf == MainChain.prototype.conf_random) confCoeff = Math.sqrt(num)/6; if (conf == MainChain.prototype.conf_one || conf == MainChain.prototype.conf_stair2) confCoeff = num/5; if (conf == MainChain.prototype.conf_stair3) confCoeff = num/10; uAxisScale = hScale/(num/35) * confCoeff; };
// настройки для конфигураций var v0 = 1*a0/T0; // conf_random - начальный разброс скоростей var sinNum = 2; // conf_sin - количество периодов синуса в цепи var hillDiv = 1/4; // conf_hill - часть (доля) цепи, которую занимает "холм"
// конфигурации MainChain.prototype.conf_random = function(b){b.vu = v0*(2*Math.random()-1);}; MainChain.prototype.conf_sin = function(b, i){b.vu = Math.sin(2*Pi * i/num*sinNum);}; MainChain.prototype.conf_one = function(b, i){if (i == Math.ceil(num/2)) b.vu = 0.5; else b.vu = 0;}; MainChain.prototype.conf_stair2 = function(b, i){if (i%4 == 0 || (i-1)%4 == 0) b.vu = 1; else b.vu = 0;}; MainChain.prototype.conf_stair3 = function(b, i){if (i%6 == 0 || (i-1)%6 == 0 || (i-2)%6 == 0) b.vu = 1; else b.vu = 0;}; MainChain.prototype.conf_hill = function(b, i){ var nd2 = hillDiv *num/2; // количество частиц, у которых изменится начальная скорость / 2 (половина параболы) if (i > num/2-nd2 && i < num/2+nd2) b.vu = (1 - (i-num/2)*(i-num/2)/(nd2*nd2)); // парабола else b.vu = 0; };
// Основной цикл программы
function control() { physics(); draw(); }
// Расчетная часть программы
function physics(){ for (var s=1; s<=spf; s++) {// то, что происходит каждый шаг времени for (var i=1; i<particles.length-1; i++) { particles[i].fu = C*(particles[i+1].uu - 2*particles[i].uu + particles[i-1].uu); particles[i].vu += particles[i].fu / m * dt; } // присваиваем новые перемещения for (var i2=1; i2 < particles.length-1; i2++ ) particles[i2].uu += particles[i2].vu * dt; } }
// Рисование
function draw(){ function clearAndPrepairCtx(ctx, wS, hS, lineHeight){ // очистить экран и нарисовать линию посередине ctx.clearRect(0, 0, wS, hS); // очистить экран ctx.strokeStyle = 'gray'; ctx.beginPath(); ctx.moveTo(0, lineHeight); ctx.lineTo(wS, lineHeight); ctx.stroke(); ctx.strokeStyle = 'black'; }
// цепь clearAndPrepairCtx(context, wScale, hScale, chainHeightScale); context.beginPath(); context.moveTo(particles[1].x0Scale, chainHeightScale + particles[1].uu*uAxisScale); for (var i = 2; i < particles.length-1; i++) context.lineTo(particles[i].x0Scale, chainHeightScale + particles[i].uu*uAxisScale); context.stroke();
// график скорости clearAndPrepairCtx(vContext, vWScale, vHScale, vHeightScale); vContext.beginPath(); vContext.moveTo(particles[1].x0Scale * uvWResize, vHeightScale + particles[1].vu*vAxisScale); for (var i0 = 2; i0 < particles.length-1; i0++) vContext.lineTo(particles[i0].x0Scale * uvWResize, vHeightScale + particles[i0].vu*vAxisScale); vContext.stroke(); }
// Запуск системы
MainChain.prototype.newSystem(MainChain.prototype.conf_hill); setInterval(control, 1000/fps);
} </source> Файл "Chain_v2_release.html" <syntaxhighlight lang="html" line start="1" enclose="div"> <!DOCTYPE html> <html> <head>
<title>Chain</title> <script src="Chain_v3_release.js"></script>
</head> <body>
u | <canvas id="canvasChain" width="800" height="200" style="border:1px solid #000000;"></canvas> |
Конфигурации Количество частиц: |
x | ||
v | <canvas id="canvasChainV" width="800" height="100" style="border:1px solid #000000;"></canvas> | |
x |
<script type="text/javascript">var app = new MainChain(document.getElementById('canvasChain'), document.getElementById('canvasChainV'));</script>
</body> </html> </source> </toggledisplay>