function Scene(a,c){c||(c={});if(typeof a==="string"){this.canvas=document.getElementById(a)||alert("new Canvas(): #"+a+" not found")}else{this.canvas=a}this.center={x:this.canvas.width/2,y:this.canvas.height/2};this.halfScale=Math.min(this.center.x,this.center.y);this.focus=c.focus?c.focus:5;this.distance=c.distance?c.distance:1;this.orientation=new Orientation();var b=this;this.dragStart=false;this.dragOrient=false;this.canvas.onmousedown=function(d){d||(d=window.event);b.dragStart=b.scene2vector(innerPosition(d,b.canvas));b.dragOrient=b.orientation.clone()};this.canvas.onmousemove=function(f){f||(f=window.event);if(b.dragStart){var d=b.scene2vector(innerPosition(f,b.canvas));b.orientation=b.dragOrient.clone();b.translateOrientation(b.dragStart,d);b.show()}};this.canvas.onmouseup=function(d){b.dragStart=false}}Scene.prototype={ribWidth:2.1,faceColours:"#ff5,#5f5,#fa5,#aa5,#5a5,#f55,#a55,orange,red,white".split(","),ribColours:"blue,red,#5cc,khaki,green,cyan,#5af,lightblue,#55a".split(","),vertexColours:"#faf,#aaf,yellow,#afa,#faa,#aaa,#f5a,#a5a,#555,red,orange".split(","),setSurface:function(a){this.surface=a},show:function(){var r=this.surface;if(!r.inColor){var h="0123456789abcdef".split("");var b={ribColours:"ribRegister",vertexColours:"vertexRegister",faceColours:"faceRegister"};for(var l in b){var a=r[b[l]];var w=0;for(var f in a){if(this[l].length<=w){this[l][w]="#"+h[Math.floor(Math.random()*15.99)]+h[Math.floor(Math.random()*15.99)]+h[Math.floor(Math.random()*15.99)]}a[f].color=this[l][w++]}}r.inColor=true}var g=[];for(var w=0;w<r.vertexes.length;w++){g[w]=this.translateVector(r.vertexes[w])}var c=[];var z={};for(var w=0;w<r.faces.length;w++){var j=r.faces[w];var d=g[j[1]].x*g[j[2]].y-g[j[1]].y*g[j[2]].x+g[j[2]].x*g[j[0]].y-g[j[2]].y*g[j[0]].x+g[j[0]].x*g[j[1]].y-g[j[0]].y*g[j[1]].x;for(var e in j.ribs){if(!z[e]){var y=e.split("-"),n;var o=r.ribRegister[j.ribs[e]];c.push({moveTo:g[y[0]],lineTo:[g[y[1]]],color:o.color,number:o.number,z:(g[y[0]].z+g[y[1]].z)/2-0.1,seen:d>0});while(n=y.pop()){if(!g[n].showed){var q=r.vertexRegister[r.vertexes[n].unique];c.push({moveTo:g[n],lineTo:[],color:q.color,number:q.number,z:g[n].z-0.2,seen:d>0});g[n].showed=1}}z[e]=1}}var k=r.faceRegister[j.unique];c.push({moveTo:g[j[0]],lineTo:[g[j[1]],g[j[2]]],color:k.color,number:k.number,z:(g[j[0]].z+g[j[1]].z+g[j[2]].z)/3,seen:d>0})}c.sort(function(v,i){return v.z-i.z});var s=this.canvas.getContext("2d"),j,t,x;s.lineCap="round",s.lineJoin="bevel",s.miterLimit=10;s.clearRect(0,0,this.canvas.width,this.canvas.height);var m,p;while(m=c.pop()){s.globalAlpha=m.seen?0.83:0.3;var u=m.lineTo.length>1;s.fillStyle=m.color;s.lineWidth=[8,this.ribWidth,0][m.lineTo.length];s.strokeStyle=m.color;s.beginPath();s.moveTo(m.moveTo.x,m.moveTo.y);if(m.lineTo.length){while(p=m.lineTo.shift()){s.lineTo(p.x,p.y)}}else{s.lineTo(m.moveTo.x,m.moveTo.y)}s.closePath();if(u){s.fill()}else{s.stroke()}}},translateVector:function(a,b){var c=this.orientation.translateVector(a);var e=c.z+this.distance+this.focus;if(e==0){return}var d=(this.focus/e)*this.halfScale;return{x:this.center.x+c.x*d,y:this.center.y+c.y*d,z:e}},scene2vector:function(g){var j=new Vector((g.x-this.center.x)/this.halfScale,(g.y-this.center.y)/this.halfScale,this.focus);var l=-this.distance-this.focus,k=j.length()*j.length(),i=-2*j.z*l,h=l*l-1,d=i*i-4*k*h,e=-i/2/k;if(d>0){e-=Math.sqrt(d)/2/k}var f=j.scale(e).add(new Vector(0,0,-l));return new Vector(-f.x,-f.y,f.z)},translateOrientation:function(b,a){return this.orientation.rotateFrom(b,a)}};innerPosition=function(c,b){var a=getPosition(b);return{x:c.clientX+window.pageXOffset-a.x,y:c.clientY+window.pageYOffset-a.y}};Number.prototype.NaN0=function(){return isNaN(this)?0:this};function getPosition(c){var b=0;var a=0;while(c.offsetParent){b+=c.offsetLeft+(c.currentStyle?(parseInt(c.currentStyle.borderLeftWidth)).NaN0():0);a+=c.offsetTop+(c.currentStyle?(parseInt(c.currentStyle.borderTopWidth)).NaN0():0);c=c.offsetParent}b+=c.offsetLeft+(c.currentStyle?(parseInt(c.currentStyle.borderLeftWidth)).NaN0():0);a+=c.offsetTop+(c.currentStyle?(parseInt(c.currentStyle.borderTopWidth)).NaN0():0);return{x:b,y:a}};
