Заключение
В ходе работы были рассмотрены возможности современных систем имитационного моделирования и актуальность внедрения веб-ориентированных интерфейсов для систем имитационного моделирования в современной жизни. Разработано веб-приложение, визуализирующее структуру имитационной модели и принцип ее работы в динамике. Разработка велась на языке PHP и JavaScript, с использованием библиотек Tween, Arbor, Graphics, jQuery и элемента HTML5 Canvas. В качестве примеров были визуализированы модели из таких областей применения, как: производство, системы массового обслуживания, социальная динамика, городской транспорт.
Список использованных источников
1 Имитационное моделирование. Теория и практика [Электронный ресурс]. URL: http://immod.gpss.ru/static/materialy_konferencii.html (дата обращения: 5.05.2014).
2 Инструмент многоподходного имитационного моделирования AnyLogic [Электронный ресурс]. URL:http:// http://www.anylogic.ru (дата обращения: 5.05.2014).
3 Cоветов, Б.Я. Моделирование систем. Практикум, 5-е издание / Б.Я. Советов, С.А. Яковлев. - Высшая школа, 2003. - 293 с.
4 Карпов, Ю. Г.Имитационное моделирование систем. Введение в моделирование с AnyLogic 5 / Ю.Г. Карпов. - СПб: БХВ-Петербург, 2006. - 400 с.
5 Замятина, О.М. Система имитационного моделирования Arena 7.0. Basic Process Panel / О.М. Замятина, Н.Г. Саночкина. - Томск: ТПУ, 2005. - 24 с.
6 Задорожный, В.Н. Мультиагентное моделирование микромира / В.Н. Задорожный, Е.Б. Юдин. - Омск: ОмГТУ, 2009. - 179 с.
7 Ганеева, М.И. Построение агентных моделей в системе моделирования SIMBIGRAPH / М.И. Ганеева, Д.А. Огнев, Е.А. Пендер. - Омск: ОмГТУ, 2011. - 105 с.
8 Forio [Электронный ресурс]. URL: http://www.forio.com (дата обращения: 11.05.2014).
9 JSON - Википедия [Электронный ресурс]. URL: http://ru.wikipedia.org/wiki/JSON (дата обращения: 11.05.2014).
10 Русская документация по jQuery [Электронный ресурс]. URL: http://jquery-docs.ru (дата обращения: 11.05.2014).
11 Arbor.js [Электронный ресурс]. URL: http://arborjs.org (дата обращения: 11.05.2014).
12 Oсновы HTML5: Часть 4. Завершающий штрих - Canvas [Электронный ресурс]. URL: http://www.ibm.com/developerworks/ru/library/wa-html5fundamentals4 (дата обращения: 11.05.2014).
13 Tween J.S. [Электронный ресурс]. URL: http://www.createjs.com/#!/TweenJS (дата обращения: 11.05.2014).
14 Что такое requestAnimationFrame()? [Электронный ресурс]. URL: http://html5.by/blog/what-is-requestanimationframe (дата обращения: 11.05.2014).
15 Имитационное моделирование систем массового обслуживания на языке GPSS [Электронный ресурс]. URL: http://gpss.h11.ru/norenkov.php#c11 (дата обращения: 11.05.2014).
16 Сочнев А.Н. Имитационное моделирование движения маршрутных автобусов // Современные научные исследования и инновации. - Май 2012. - № 5 [Электронный ресурс]. URL: http://web.snauka.ru/issues/2012/05/12603 (дата обращения: 11.05.2014).
17 Pedestrian dynamics [Электронный ресурс]. URL: http://www.runthemodel.com/models/pedestrian_dynamics (дата обращения: 11.05.2014).
Приложение А
{
nodes:{
1:{color:yellow,shape:dot,label:source1},
2:{color:yellow,shape:dot,label:source2},
3:{color:orange,shape:dot,label:queue1},
4:{color:orange,shape:dot,label:queue2},
5:{color:brown,shape:dot,label:kas1},
6:{color:brown,shape:dot,label:kas2},
7:{color:grey,shape:dot,label:sink}
},
edges:{
1:{ 3:{directed:1}},
2:{4:{directed:1}},
3:{5:{directed:1}},
4:{6:{directed:1}},
6:{7:{directed:1}},
5:{7:{directed:1}}
}
Приложение Б
{stream:{
1:{color:green,speed:3000},
3:{color:green,speed:3000, delay:0},
5:{color:green,speed:3000, delay:5000},
7:{}
},
stream:{
2:{color:yelow, speed:3000},
4:{color:yelow, speed:3000, delay:0},
6:{color:yelow, speed:3000, delay:4500},
7:{}
},
stream:{
1:{color:blue,speed:3000},
3:{color:blue,speed:3000, delay:2000},
5:{color:blue,speed:3000, delay:5000},
7:{}
},
stream:{
2:{color:#99ff66, speed:3000},
4:{color:#99ff66, speed:3000, delay:1000},
6:{color:#99ff66, speed:3000, delay:4000},
7:{}
},
stream:{
1:{color:brown,speed:3000},
3:{color:brown,speed:3000, delay:5000},
5:{color:brown,speed:3000, delay:5000},
7:{}
},
stream:{
2:{color:#66ccff, speed:3000},
4:{color:#66ccff, speed:3000, delay:2000},
6:{color:#66ccff, speed:3000, delay:5000},
7:{}
},
stream:{
1:{color:red,speed:3000},
3:{color:red,speed:3000, delay:7000},
5:{color:red,speed:3000, delay:5000},
7:{}
},
stream:{
2:{color:orange, speed:3000},
4:{color:orange, speed:3000, delay:4000},
6:{color:orange, speed:3000, delay:4000},
7:{}
}
Приложение В
init.json
{
nodes:{
1:{color:yellow,shape:dot,label:source1},
2:{color:yellow,shape:dot,label:source2},
3:{color:grey,shape:rect,label:A1},
4:{color:grey,shape:rect,label:A2},
5:{color:grey,shape:rect,label:A3}
},
edges:{
1:{ 3:{directed:1}},
2:{3:{directed:1}},
3:{4:{directed:1}},
4:{5:{}},
3:{5:{}}
}
redraw.json
{period: {speed:3000}
stream:{
1:{color:green,speed:1000},
3:{color:blue,speed:1000, delay:22000},
4:{color:brown,speed:1000, delay:11000},
5:{color:yellow,speed:1000, delay:8000},
3:{color:orange,speed:1000, delay:13000},
5:{color:black,speed:1000, delay:15000}
4:{}
},
stream:{
2:{color:green,speed:1000},
3:{color:#33ffcc,speed:1000, delay:22000},
4:{color:#9933ff,speed:1000, delay:11000},
5:{color:#66ff66,speed:1000, delay:8000},
3:{color:red,speed:1000, delay:13000},
5:{color:#990000,speed:1000, delay:15000}
4:{}
}
Приложение Г
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Network diagram</title>
<style>
#canv {
width:100%;
height:100%;
}
#but1{
background: #3399ff;
padding: 7px 30px;
font-size:13px;
font-weight: bold;
color:#fff;
text-align: center;
border:solid 1px #73c8f0;
border-radius: 5px;}
</style>
</head>
<body onload="Start()">
<script src="js/jquery.min.js"></script>
<script src="js/arbor.js"></script>
<script src="js/graphics.js" ></script>
<script src="js/tween.min.js"></script>
<script src="js/RequestAnimationFrame.js"></script>
<script>
var ma = <?
//удалим содержимое директории upload/
$handle = opendir (upload/);
while(false !== ($file = readdir ($handle)))
if($file != "." && $file != "..") unlink (upload/.$file);
closedir ($handle);
$fileElementName = $_FILES[myfile];
$i = 0;
$j = 0;
$files_count = sizeof($fileElementName["name"]);
$mas = array();
for ($i = 0; $i < $files_count; $i++) {
$b= $fileElementName["tmp_name"][$i];
if (substr($fileElementName["type"][$i],0,5) == "image"){
$mas[$j] = $fileElementName["name"][$i];
$j++;
}
move_uploaded_file($fileElementName[tmp_name][$i], "upload/". $fileElementName[name][$i]);
}
echo json_encode($mas);
?>;
var a = <?$p=file_get_contents("upload/init.json"); echo $p; ?>;
var b = <?$p=file_get_contents("upload/redraw.json"); echo json_encode($p); ?>;
var mas = new Array();
var i = 0;
$.each(ma,function(name, value){ mas[i]= String(value);i++;});
var ar = new Array();
for (var q=0;q<mas.length;q++){
ar[q] = new Image();
ar[q].src=upload/+mas[q];
}
var nodeBoxes = {};
function findArrVal(arr,value) {
for (var ind=0;ind<arr.length;ind++){
if (arr[ind].substr(0,arr[ind].length-4) == value) {return ind;}
}
function Renderer(canvas)
{
var canvas = $(canvas).get(0);
var ctx = canvas.getContext("2d");
var gfx = arbor.Graphics(canvas);
var particleSystem = null;
var that = {
init:function(system){
//начальная инициализация
particleSystem = system;
particleSystem.screenSize(canvas.width, canvas.height);
particleSystem.screenPadding(80);
that.initMouseHandling();
},
redraw:function(){
//действия при перересовке
gfx.clear();
particleSystem.eachNode(//теперь каждую вершину
function(node, pt){//получаем вершину и точку где она
var label = node.data.label||""
var w = ctx.measureText(""+label).width + 10
if (!(""+label).match(/^[ ]*$/)){
pt.x = Math.floor(pt.x)
pt.y = Math.floor(pt.y)
}else{
label = null
}
if (node.data.color==none) {ctx.fillStyle = #333333} else {ctx.fillStyle=node.data.color}
if (node.data.shape==image){
ctx.drawImage(ar[findArrVal(mas,node.data.label)],pt.x, pt.y,50,50);
if (label){
ctx.font = "12px Helvetica"
ctx.textAlign = "center"
ctx.fillStyle = "black"
ctx.fillText(label||"", pt.x+11, pt.y-5)
nodeBoxes[node.name] = [pt.x, pt.y, w,w]
}
else if (node.data.shape==dot){
if (node.data.color==none) {ctx.fillStyle = #333333} else {ctx.fillStyle=node.data.color}
gfx.oval(pt.x-10, pt.y-10, 20,20, {fill:ctx.fillStyle})
nodeBoxes[node.name] = [pt.x-10, pt.y-10, w,w]
ctx.fillStyle = "black"
if (label) {ctx.fillText(label||"", pt.x, pt.y-12);}
}else{
if (node.data.color==none) {ctx.fillStyle = #333333} else {ctx.fillStyle=node.data.color}
gfx.rect(pt.x-w/2, pt.y-10, w,20, 4, {fill:ctx.fillStyle})
nodeBoxes[node.name] = [pt.x-w/2, pt.y-11, w, 22]
ctx.fillStyle = "black"
if (label) {ctx.fillText(label||"", pt.x, pt.y-12);}
}
});
particleSystem.eachEdge(//отрисуем каждую грань
function(edge, pt1, pt2){//будем работать с гранями и точками её начала и конца
var weight = !isNaN(edge.data.weight) ? parseFloat(weight): 1;
var color = !isNaN(edge.data.color) ? parseString(edge.data.color): "rgba(100,0,50,.5)";
var tail = intersect_line_box(pt1, pt2, nodeBoxes[edge.source.name]);
var head = intersect_line_box(tail, pt2, nodeBoxes[edge.target.name]);
ctx.strokeStyle = "rgba(100,0,50,.8)";//грани будут чёрным цветом с некой прозрачностью
ctx.lineWidth = 1;//толщиной в один пиксель
ctx.beginPath();//начинаем рисовать
ctx.moveTo(tail.x, tail.y)
ctx.lineTo(head.x, head.y)
ctx.stroke()
ctx.restore()
// draw an arrowhead if this is a -> style edge
if (edge.data.directed){
ctx.save()
// move to the head position of the edge we just drew
var wt = 1
var arrowLength = 6 + wt
var arrowWidth = 2 + wt
ctx.fillStyle = color
ctx.translate(head.x, head.y);
ctx.rotate(Math.atan2(head.y - tail.y, head.x - tail.x));
// delete some of the edge thats already there (so the point isnt hidden)
ctx.clearRect(-arrowLength/2,-wt/2, arrowLength/2,wt)
// draw the chevron
ctx.beginPath();
ctx.moveTo(-arrowLength, arrowWidth);
ctx.lineTo(0, 0);
ctx.lineTo(-arrowLength, -arrowWidth);
ctx.lineTo(-arrowLength * 0.8, -0);
ctx.closePath();
ctx.fill();
ctx.restore()
}
initMouseHandling:function(){//события с мышью
var dragged = null;//вершина которую перемещают
var handler = {
clicked:function(e){//нажали
var pos = $(canvas).offset();//получаем позицию canvas
_mouseP = arbor.Point(e.pageX-pos.left, e.pageY-pos.top); //и позицию нажатия кнопки относительно canvas
dragged = particleSystem.nearest(_mouseP);//определяем ближайшую вершину к нажатию
if (dragged && dragged.node !== null){
dragged.node.fixed = true;//фиксируем её
}
$(canvas).bind(mousemove, handler.dragged);//слушаем события перемещения мыши
$(window).bind(mouseup, handler.dropped);//и отпускания кнопки
return false;
},
dragged:function(e){//перетаскиваем вершину
var pos = $(canvas).offset();
var s = arbor.Point(e.pageX-pos.left, e.pageY-pos.top);
if (dragged && dragged.node !== null){
var p = particleSystem.fromScreen(s);
dragged.node.p = p;//тянем вершину за нажатой мышью
}
return false;
},
dropped:function(e){//отпустили
if (dragged===null || dragged.node===undefined) return;//если не перемещали, то уходим
if (dragged.node !== null) dragged.node.fixed = false;//если перемещали - отпускаем
dragged = null; //очищаем
$(canvas).unbind(mousemove, handler.dragged); //перестаём слушать события
$(window).unbind(mouseup, handler.dropped);
_mouseP = null;
return false;
}
// слушаем события нажатия мыши
$(canvas).mousedown(handler.clicked);
},
// helpers for figuring out where to draw arrows (thanks springy.js)
var intersect_line_line = function(p1, p2, p3, p4)
{
var denom = ((p4.y - p3.y)*(p2.x - p1.x) - (p4.x - p3.x)*(p2.y - p1.y));
if (denom === 0) return false // lines are parallel
var ua = ((p4.x - p3.x)*(p1.y - p3.y) - (p4.y - p3.y)*(p1.x - p3.x)) / denom;
var ub = ((p2.x - p1.x)*(p1.y - p3.y) - (p2.y - p1.y)*(p1.x - p3.x)) / denom;
if (ua < 0 || ua > 1 || ub < 0 || ub > 1) return false
return arbor.Point(p1.x + ua * (p2.x - p1.x), p1.y + ua * (p2.y - p1.y));
}
var intersect_line_box = function(p1, p2, boxTuple)
{
var p3 = {x:boxTuple[0], y:boxTuple[1]},
w = 20//boxTuple[2],
h = 20//boxTuple[3]
var tl = {x: p3.x, y: p3.y};
var tr = {x: p3.x + w, y: p3.y};
var bl = {x: p3.x, y: p3.y + h};
var br = {x: p3.x + w, y: p3.y + h};
return intersect_line_line(p1, p2, tl, tr) ||
intersect_line_line(p1, p2, tr, br) ||
intersect_line_line(p1, p2, br, bl) ||
intersect_line_line(p1, p2, bl, tl) ||
false
}
return that;
}
function Start(){
var sys = arbor.ParticleSystem(1,000, 600,0.9);
sys.parameters({gravity:true});
sys.parameters({dt:0.5});
sys.renderer = Renderer("#canv");//начинаем рисовать в выбраной области
sys.graft(a);
};
function redraw(){
var nm = b.split(;);
for (var i=0; i<nm.length;i++){nm[i]=JSON.parse(nm[i]);}
init(nm);
animate();
}
function init(mas) {
var x0=nodeBoxes[mas[0].name][0],
y0=nodeBoxes[mas[0].name][1];
var xx = new Array();
var yy = new Array();
for (var i=1; i<mas.length-1; i++){
xx[i-1] = nodeBoxes[mas[i].name][0]
yy[i-1] = nodeBoxes[mas[i].name][1]
}
var canvas = $("#canv").get(0);
var context = canvas.getContext( 2d );
context.lineWidth = 2;
context.strokeStyle = "#00ff00";
var obj = { x: x0, y: y0,old: { x: x0, y: y0}};
mtween = new TWEEN.Tween( obj ).to( { x: xx, y: yy }, 9000);
mtween.interpolation(TWEEN.Interpolation.Linear);
mtween.easing( TWEEN.Easing.Linear.None );
mtween.delay( 10 );
mtween.onComplete(function(){mtween.stop()});
mtween.onUpdate( function() {
context.beginPath();
context.moveTo( this.old.x, this.old.y );
context.lineTo( this.x, this.y );
context.closePath();
context.stroke();
this.old.x = this.x;
this.old.y = this.y;
}).start();
}
function animate() {
requestAnimationFrame( animate );
TWEEN.update();
}
</script>
<canvas id="canv" width="1260" height="600"></canvas>
<div>
<input type="button" id="but1" value="reload" style="position:absolute;bottom:50px;left:50px;" onclick="test()"></input>
<a href="http://site/index.html"><input type="button" id="but1" value="Home" style="position:absolute;bottom:50px;right:50px;"></input></a>
</div> </body></html>
- Введение
- 1. Системы имитационного моделирования
- 1.1 Система имитационного моделирования AnyLogic
- 1.2 Система имитационного моделирования Arena
- 1.3 Система имитационного моделирования SimuLab
- 1.4 Система имитационного моделирования Simbigraph
- 1.5 Система Forio. Имитационное моделирование в Web
- 2. Web-приложение для имитационного моделирования
- 2.1 Серверная часть
- 2.2 Клиентская часть
- 2.3 Описание приложения
- 2.4 Примеры визуализации имитационных моделей
- 2.4.1 Модель работы отдела банка
- 2.4.2 Модель работы участка цеха
- 2.4.3 Модель движения автобуса по маршруту
- 2.4.4 Модель социальной сети
- Заключение