/* * Инициализация переменных и констант */ var MaxTemp, MinTemp; const deg2rad = Math.PI / 180.0; var theScene, SScene, IScene, TScene, tScene; // весь рисунок, подкупольное, межкупольное, // слой для кружочков от сенсоров (чувствительных к мыше), вспомогательный слой // угол phi в координатах датчиков - в плоскости рисунка // R, Z - в дециметрах const Ssen_pos = [ // сенсоры на неподвижной части, цилиндр. СК: [R,phi,Z] [123, 140, 3], // 12 [144, -40, 3], // 13 [150, -44, 36], // 14 [134, 170, 37], // 15 [122, 139, 35], // 16 [106, 27, 57], // 17 [185, -43, 77], // 18 [164, 175, 77], // 19 [186,-114, 69], // 20 [111, 137, 69], // 21 [179, 50, 76] // 22 ]; // в массивах sincos элемент 0 - синус, 1 - косинус угла phi положения сенсора const Ssen_num = [12,13,14,15,16,17,18,19,20,21,22]; // номер датчкика ssen (из DomeTemperatures) const Dsen_pos = [ // сенсоры на подвижной части купола, угловая к-та от стороны с датчиком 14 23, 39, 90, 125, 148, 167 ]; var Dsen_sincos = new Array(); const Dsen_num = [6, 8, 11, 9, 7, 5]; // номера датчиков (из DomeTemperatures) const Isen_pos = [ // сенсоры во внутрикупольном пространстве - 2 штуки 2, 70 ]; var Isen_sincos = new Array(); const Isen_num = [2, 10]; const MDsen_pos = [ // датчики на подв. части купола (металл), коорд.: R 243, 239, 233, 229 ]; const MDsen_num = [0, 1, 3, 4]; const ZAxisHeight = 88; // высота оси Z (зенитн. р.) от пола const Tsen_pos = [ // воздушные сенсоры на телескопе !!! Высоты - от оси Z !!! [37, 90,-55], // 1 [37, -90,-55], // 2 [37, 0,-55], // 3 [31, 69,-33], // 4 [33, 69,-28], // 5 [34,-171,-10], // 6 [ 4, -82, -8], // 7 [ 4, -82, 0], // 8 [35, 147, 40], // 9 [35, 117, 58], // 10 [35, -71, 82], // 11 [35, 20, 97], // 12 [35, 20,104], // 13 [36, 81,108], // 14 [36, -98,129], // 15 [ 0, 0,146], // 16 [40, -90,155], // 17 [10, 180,190], // 18 [ 0, 0,190], // 19 [ 9, 180,201] // 20 ]; var Tsen_sincos = new Array(); const Tsen_num = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]; // типы датчиков: const Tsen_type = [ "a", "a", "a", "a", "m", "a", "a", "m", "a", "a", "a", "m", "a", "a", "a", "a", "m", "m", "a", "a"]; var DomeTemperatures = new Array(); // показания температур датчиков купола var DomeTempsUsed = new Array(); // 1 - показания датчика используются var TubeTemperatures = new Array(); // показания датчиков телескопа var TubeTempsUsed = new Array(); // 1 - показания датчика используются const Az0 = 134.92; // азимут купола из чертежа (для "нулевой" проекции) var TelAz = Az0; var TelZ = 0; // азимут и зенитное расстояние телескопа var DomeAz = Az0; // азимут купола var RotAngle = Az0; // Угол вращения главной плоскости рисунка (вокруг вертикальной оси) var SSensors = new Array(); // датчики на неподвижной части var DSensors = new Array(); // датчики на подвижной части, в т.ч. в межкупольном var TSensors = new Array(); // датчики на телескопе var Tel; // "телескоп" var init = 1; function $(el){ return document.getElementById(el); } function fillDTused(){ function fill__(temps, tused){ var i, l = temps.length; for(i=0; i3){r=255; g=0; b=0;} if(i<0){r=0; g=0; b=255;} } var Color = '#' + to16(r) + to16(g) + to16(b); return Color; } var color = getColor(Temp); Gradient('r', gradId, [50,50,100], [0,50,100], [color, color, color], [1,0,0]); } function initGradients(){ var i, t, l; MaxTemp = -100.0; MinTemp = 100.0; function findExtrems(tmas){ l = tmas.length; for(i=0; i MaxTemp) MaxTemp = t; if(t < MinTemp) MinTemp = t; } } function mkGrads(tmas, def){ l = tmas.length; for(i=0; i0?1:-1; var Xabs1 = (X-Xc)/R, Yabs1 = (Y-Yc)/R; if(Xabs>1) Xabs=1; else if(Xabs<-1) Xabs=-1; if(Yabs>1) Yabs=1; else if(Yabs<-1) Yabs=-1; if(Xabs1>1) Xabs1=1; else if(Xabs1<-1) Xabs1=-1; if(Yabs1>1) Yabs1=1; else if(Yabs1<-1) Yabs1=-1; if(olddir == 0) olddir = dir; else if(olddir != dir){olddir = dir; sign = 0;} if((Y-yClick0)>0) dir *= -1; // тянут за "заднюю часть" var dphi = Math.abs(Math.acos(Xabs1) - Math.acos(Xabs))+ Math.abs(Math.asin(Yabs1) - Math.asin(Yabs)); xClick0 = X; yClick0 = Y; if(sign == 0) sign = dir; dphi *= sign/deg2rad; /* $("test").innerHTML = " Xabs="+Xabs+"
Yabs="+Yabs +"
sign="+sign+"
olddir="+olddir+"
dir="+dir +"
dphi="+dphi;*/ RotateScene(dphi); } function endRotate(evt){ SVGDoc.onmousemove = ''; SVGDoc.onmouseup = ''; doRotate(evt); olddir=sign=0; } function resizeSVG(){ var SVG = $("SVG"); var mainSVG = SVGDoc.getElementById("Main"); var W = document.body.clientWidth - 2*SVG.offsetLeft - 5; var H = document.body.clientHeight - 2*SVG.offsetTop - 5; var zoom = Math.min(W/mainWidth, H/mainHeight); if(Math.abs(zoom - 1) > 0.01) mainSVG.setAttribute("transform", "scale("+zoom+")"); else mainSVG.removeAttribute("transform"); SVGDoc.width = SVG.width = mainWidth * zoom; SVGDoc.height = SVG.height = mainHeight * zoom; } function MoveSensor(x, y, r){ this.outer.ChAttrs('r', r); this.outer.MoveTo(x,y); this.inner.MoveTo(x,y); } function RotateVisor(){ var angle = RotAngle - DomeAz , fil = 1; var X0= Visor.Parent.Xmax; var Y0= Visor.Parent.Ymax; var X = new Array(5); var Y = new Array(5); var Z = new Array(5); var i, phi, ss='M '; for(i=0; i<5; i++){ phi = (Visor.Points[i][1] + angle) * deg2rad; X[i] = X0 + Visor.Points[i][0] * Math.cos(phi); Y[i] = Y0 - Visor.Points[i][2]; // для сокращения записи Z[i] = Math.sin(phi); } var R1 = X[0]-X[3]; var R2 = X[1]-X[2]; var R3 = X[4]-(X[2]+X[3])/2; var f1 = (R1<0)?1:0; var f2 = (R2<0)?0:1; var f3 = (R3<0)?0:1; if(Z[0] < 0) ss += X[0]+','+Y[0]+' A '+Math.abs(R1)+',247 0 0 '+f1+' '; else fil = 0; ss += X[3]+','+Y[3]+' L '+X[2]+','+Y[2]+' '; if(Z[1] < 0) ss += 'A '+Math.abs(R2)+',247 0 0 '+f2+' '; else{ ss += 'M '; fil = 0;} ss += X[1]+','+Y[1]+' L '+X[0]+','+Y[0]; Visor.ChAttrs('d', ss); ss = "M "+(X[2]+X[3])/2+','+Y[2]+' A '+Math.abs(R3)+',247 0 0 '+f3+' '+X[4]+','+Y[4]+' L '+X[0]+','+Y[0]; Visor.Cline.ChAttrs('d', ss); if(fil) Visor.Fill("#aaaacc"); else Visor.Fill("none"); } function RotateScene(dPhi){ RotAngle += dPhi; if(RotAngle > 360) RotAngle -= 360; if(RotAngle < 0) RotAngle += 360; RotateVisor(); RotateSensors(); theScene.Draw(); update_coords_div(); } function RotateSensors(){ const Rmin=10, Rvar=110; var i, l, j, x, y, R, phi, op; l = Ssen_pos.length; for(i=0; i датчик "+ss+num+"
("+type+")"); } var tipobj, tiptext; function tooltip(evt, txt){ tipobj = document.createElement("DIV"); tipobj.onclick = help; tipobj.className = "tooltip"; tipobj.setAttribute("name", "tipobj"); tipobj.style.opacity = 0.3; document.body.appendChild(tipobj); tiptext = document.createElement("DIV"); tiptext.id = "tiptext"; tiptext.onclick = help; document.body.appendChild(tiptext); tipobj.innerHTML = txt; tiptext.innerHTML = txt; evt.target.onmouseout = hide_info; evt.target.onmouseover = ''; positiontip(evt); } function hide_info(el){ document.body.removeChild(tiptext); setTimeout(hide, 3000); setTimeout(function(){el.target.onmouseover = showTemp;}, 4000); el.target.onmouseout = ''; } var hideTmOut; function hide(){ var obj = document.getElementsByName("tipobj")[0]; if(!obj) return; var op = obj.style.opacity; op -= 0.01; document.getElementsByName("tipobj")[0].style.opacity = op; if(op > 0) hideTmOut = setTimeout(hide, 30); else document.body.removeChild(obj); } function onkey(code){ if(code != 27) return; clearTimeout(hideTmOut); var obj = document.getElementsByName("tipobj"); var l = obj.length - 1; for(var i=l; i>-1; i--) document.body.removeChild(obj[i]); } function positiontip(e){ var SVG = $('SVG'); var curX = e.clientX + SVG.offsetLeft; var curY = e.clientY + SVG.offsetTop - tipobj.offsetHeight - 5; var winwidth = SVG.offsetWidth - SVG.offsetLeft; var winheight = SVG.offsetHeight - SVG.offsetTop; var rightedge = winwidth - curX; if(rightedge < tipobj.offsetWidth) curX -= tipobj.offsetWidth+15; if(curY < SVG.offsetTop) curY += tipobj.offsetHeight*2+15; tipobj.style.left = curX+"px"; tipobj.style.top = curY+"px"; $('tiptext').style.top = curY+"px"; $('tiptext').style.left = curX+"px"; } function help(){ alert("Всплывающие подсказки показывают значения температуры для данного датчика\n" +"и номер этого датчика.\n" +"В случае, если датчик не подключен, появляется соответствующая надпись."); } /* * Запрос значений температур и координат */ function getData(){ $('coords').innerHTML = "Обновляю..."; sendrequest("http://tb.sao.ru/cgi-bin/eddy/bta_pos.cgi", "", parseCoords); } function update_coords_div(){ function azimuth(ang){ var x = ang; if(x > 180) x -= 360; else if(x < -180) x += 360; return x.toFixed(2); } var cDiv = $('coords'); var SVG = $('SVG'); cDiv.innerHTML = "Текущие координаты телескопа: A="+azimuth(TelAz)+ ", Z="+TelZ.toFixed(2)+"; азимут купола: A="+ azimuth(DomeAz)+"; азимут наблюдателя: "+azimuth(RotAngle-90); cDiv.style.left = (SVG.offsetLeft + 5) + "px"; cDiv.style.top = (SVG.offsetTop + 5) + "px"; } function parseCoords(req){ var i, args; var data = req.responseText.split(' '); var l = data.length; for(i=0; i -1){ // температура датчиков в подкупольном fillTemp("dome", args); } else if(args[0].indexOf("t_tube") > -1){ // температура датчиков на телескопе fillTemp("tube", args); } } initGradients(); if(init){ initSensors(); Tel = new Telescope(); init = 0; } RotateSensors(); RotateVisor(); theScene.Draw(); setTimeout(getData, 300000); // обновляем данные каждые 5 минут } function fillTemp(sObj, sArray){ var n, d, t, pos; if(sObj == "dome") pos=6; else pos=7; n = Number(parseInt(sArray[0].substr(pos))); // номер датчика t = Number(parseFloat(sArray[3]).toFixed(1)); if(sObj == "dome"){ if(DomeTempsUsed[n] == 1) // этот датчик отображается DomeTemperatures[n] = t; } else{ if(TubeTempsUsed[n] == 1) // этот датчик отображается TubeTemperatures[n] = t; } } function sendrequest(CGI_PATH, req_STR, fn_OK){ var timeout_id, str; var request = new XMLHttpRequest(); request.open("POST", CGI_PATH, true); request.setRequestHeader("Accept-Charset", "koi8-r"); request.overrideMimeType("multipart/form-data;"); request.onreadystatechange=function(){ if(request.readyState == 4){ if(request.status == 200){ clearTimeout(timeout_id); fn_OK(request); } else{ clearTimeout(timeout_id); } } } request.send(req_STR); timeout_id = setTimeout(function(){ request.onreadystatechange=null; request.abort(); }, 15000); }