function Surface(){this.vertexes=[];this.faces=[];this.ribs={};this.ribRegister={};this.inColor=false}Surface.prototype={sort:function(){var g=new Vector(0,0,0);this.ribs={};this.rAngleRegister={},this.angleRegister={},this.ribRegister={},this.ribLengthRegister={},this.vertexRegister={},this.faceRegister={};var G;for(var y=0;y<this.vertexes.length;y++){this.vertexes[y].scheme={}}for(var a=0;a<this.faces.length;a++){var h=this.faces[a];h.unique=[];h.ribs={};for(var y=2;y>=0;y--){var D=h[y],c=h[(y+1)%3],k=h[(y+2)%3];var s=this.vertexes[D],q=this.vertexes[c],n=this.vertexes[k];var x=this.regUnique(this.ribLengthRegister,this.ribLength(D,c));var w=[D,c].sort().join("-"),H;if(!this.ribs[w]){var r=[this.angle([s.center?s.center:g,s,q],this.rAngleRegister),this.angle([q.center?q.center:g,q,s],this.rAngleRegister)];H=this.regUnique(this.ribRegister,[x,r[0],r[1]].sort().join("-"),w);this.ribs[w]={length:x,rAngles:r,vertexes:[s,q],unique:H}}else{H=this.ribs[w].unique}h.ribs[w]=H;h.unique.push(x);q.scheme[D]={vertex:D,byFace:this.angle([s,q,n],this.angleRegister),byRadius:this.angle([g,q,s],this.rAngleRegister),face:a,next:k}}var F=h.unique,t=(0+F[0]+F[1]+F[2])/2;var o=Math.sqrt(t*(t-F[0])*(t-F[1])*(t-F[2]));h.unique=this.regUnique(this.faceRegister,h.unique.sort().join("-"),a);this.faceRegister[h.unique].square=o}for(var y=0;y<this.vertexes.length;y++){var l=this.vertexes[y];var m=l.scheme;var z=[];for(var e in m){var d=[],E=e;do{d.push(m[E]);E=m[E].next}while(m[E]&&E!=e);z.push(d)}if(z.length>1){z.sort(function(p,i){if(p.length!=i.length){return i.length-p.length}for(var v=0;v<p.length;v++){if(p[v].byFace!=i[v].byFace){return i[v].byFace-p[v].byFace}}return 0})}var b=[],u;m={};var e=z[0][0].vertex,j;while(u=z[0].shift()){b.push([u.byFace,u.byRadius].join("/"));m[u.vertex]=u;j=u.next}if(e!=j){e=this.vertexes[e];j=this.vertexes[j];b.push([this.angle([j,l,e],this.angleRegister),this.angle([g,l,j],this.rAngleRegister)].join("/"))}this.vertexes[y].scheme=m;this.vertexes[y].unique=this.regUnique(this.vertexRegister,b.join("-"),y)}return this},angle:function(h,g){var e=h[1].clone().subtract(h[2]).length();var d=h[2].clone().subtract(h[0]).length();var j=h[0].clone().subtract(h[1]).length();var i=Math.acos((e*e+j*j-d*d)/(2*e*j));return this.regUnique(g,i)},regUnique:function(c,d,b){if(typeof(d)=="number"){d=Math.round(d*10000)/10000}if(c==undefined){return d}if(c[d]!=undefined){b==undefined||c[d].push(b);return d}if(typeof(d)==="number"){for(var a in c){if(Math.abs(a-d)<0.0001){b==undefined||c[a].push(b);return a}}}c[d]=(b==undefined)?[]:[b];return d},slice:function(d,b,c){b||(b=0.5);b=b*2-1;var a=[],e;while(e=this.faces.pop()){if(this.vertexes[e[0]][d]+this.vertexes[e[1]][d]+this.vertexes[e[2]][d]<b){a.push(e)}}this.faces=a;this.deleteUnusedVertexes();c&&this.fixSelvage();return this},fixSelvage:function(){var m={};for(var e=0;e<this.faces.length;e++){for(var d=2;d>=0;d--){var h=this.faces[e][d],c=this.faces[e][(d+1)%3];var l=[h,c].sort().join("-");if(m[l]){m[l]++}else{m[l]=1}}}var b={},a=new Vector(0,0,0),g=0;for(var k in m){if(m[k]==1){k=k.split("-");b[k[0]]=1;a.add(this.vertexes[k[0]]);b[k[1]]=1;a.add(this.vertexes[k[1]]);g++}}g&&a.scale(0.5/g);for(var e in b){a.radius||(a.radius=Vector.subtract(a,this.vertexes[e]).length());this.vertexes[e].center=a}},spec:function(){return{connectors:this.specConnectors(),ribs:this.specRibs(),faces:this.specFaces()}},specFaces:function(){var a=[];a.square=0;a.count=0;for(var d in this.faceRegister){var e=this.faceRegister[d];a.square+=e.length*e.square;a.count+=this.faceRegister[d].length;var b=this.faces[e[0]].unique.split("-");e.trilens=[];for(var c=0;c<3;c++){e.trilens[c]=new Number(b[c])}e.key=d;e.count=e.length;a.push(e)}for(var c=0;c<a.length;c++){a[c].number=this.faceRegister[a[c].key].number=c+1}return a},specRibs:function(){var b=[];for(var e in this.ribRegister){var c=this.ribRegister[e];var a=this.ribs[c[0]];var g=c[0].split("-");b.push({key:e,count:c.length,length:a.length,selvage:(a.vertexes[0].center&&!a.vertexes[0].center.isZero()?1:0)+(a.vertexes[1].center&&!a.vertexes[1].center.isZero()?1:0),rAngles:a.rAngles,endsUnique:[a.vertexes[0].unique,a.vertexes[1].unique],instance:a})}b.sort(function(i,h){return(i.selvage!=h.selvage)?i.selvage-h.selvage:h.count-i.count});for(var d=0;d<b.length;d++){b[d].number=this.ribRegister[b[d].key].number=d+1}return b},specConnectors:function(){var t=[],e=[];for(var C in this.vertexRegister){var h=this.vertexRegister[C];var B=h[0],y=this.vertexes[B],g,q;var r=new Surface();r.vertexRegister=this.vertexRegister;r.faceRegister=this.faceRegister;r.ribRegister=this.ribRegister;var d={};d[B]=0;var a=r.vertexes[0]=__clone(y);if(y.center){a.subtract(y.center)}var c=a.length();r.thisSelvage=(y.center&&!y.center.isZero())?1:0;for(var x in y.scheme){g||(g=x);q=y.scheme[x].next;var o=__clone(this.vertexes[x]);if(y.center){o.subtract(y.center)}d[x]=r.vertexes.length;r.vertexes.push(o);var m=this.faces[y.scheme[x].face],A=__clone(m,true);r.faces.push(A)}if(q!=g){var o=__clone(this.vertexes[q]);if(y.center){o.subtract(y.center)}d[q]=r.vertexes.length;r.vertexes.push(o)}for(var w=0;w<r.faces.length;w++){var m=r.faces[w],A=__clone(m).subst(d);A.ribs={};for(var n in m.ribs){var j=n.split("-").subst(d).sort().join("-");A.ribs[j]=m.ribs[n];var u=r.ribs[j]=this.ribs[n]}A.unique=m.unique;r.faces[w]=A}r.rotate(-Math.atan2(a.y,a.z),"x");r.rotate(Math.atan2(a.z,a.x)+Math.PI/2,"y");var p=0,b=-1;for(var w=0;w<r.vertexes.length;w++){var k=r.vertexes[w].z;(k>b)&&(b=k)}r.offset(new Vector(0,0,-b));for(var w=0;w<r.vertexes.length;w++){var s=r.vertexes[w].length();(s>p)&&(p=s)}r.scale(1/Math.max(s));r.inColor=true;t.push({key:C,count:h.length,selvage:r.thisSelvage,radius:c,surface:r})}t.sort(function(l,i){return l.selvage!=i.selvage?l.selvage-i.selvage:i.count-l.count});for(var w=0;w<t.length;w++){t[w].number=this.vertexRegister[t[w].key].number=w+1}return t},triangulation:function(){var b=this.faces.length;var d={};for(var g=0;g<b;g++){var m=this.faces[g];var n={};for(var k=2,h=0;k>=0;h=k--){var e=[m[k],m[h]];var c=[e[1],e[0]].sort().join("-");if(d[c]==undefined){var a,l;if(this.vertexes[e[0]].center&&(a=this.vertexes[e[1]].center)){l=Vector.add(a,Vector.add(Vector.subtract(this.vertexes[e[0]],a),Vector.subtract(this.vertexes[e[1]],a)).normalize().scale(a.radius));l.center=a}else{l=Vector.add(this.vertexes[e[0]],this.vertexes[e[1]]).normalize()}this.vertexes[d[c]=this.vertexes.length]=l}n[""+k+h]=d[c]}this.addFace(m[0],n["01"],n["20"]);this.addFace(m[1],n["12"],n["01"]);this.addFace(m[2],n["20"],n["12"]);this.addFace(n["01"],n["12"],n["20"])}this.faces.splice(0,b);return this},triangulationN:function(e){var q=this.faces.length;var v=__verts={};for(var a=0;a<q;a++){var g=this.faces[a];var l=[g[0],g[1],g[2]].sort(function(n,i){return n-i})[0];var t=[g[0],g[1],g[2]];while(t[0]!=l){t.push(t.shift())}var s=t[0],b=t[1],j=t[2];var h=[s];for(var p=1;p<=e;p++){var c=[s,b,p].join("-");li=v[c]?v[c]:(v[c]=this._duangulation(s,b,p,e));var d=[s,j,p].join("-"),m=v[d]?v[d]:(v[d]=this._duangulation(s,j,p,e));var k=[],r;for(r=0;r<=p;r++){var o=(li<m)?""+li+"-"+m+"-"+r:""+m+"-"+li+"-"+(p-r);var u=v[o]?v[o]:(v[o]=this._duangulation(li,m,r,p));k.push(u)}this.addFace(h[0],k[0],k[1]);for(r=1;r<h.length;r++){this.addFace(h[r],h[r-1],k[r]);this.addFace(h[r],k[r],k[r+1])}h=k}}this.faces.splice(0,q);return this},_duangulation:function(b,c,i,h){if(i==0){return b}if(i==h){return c}var g=i/h;var a,d=this.vertexes[b].center&&(a=this.vertexes[c].center);a=d?a:new Vector();d||(a.radius=1);var e=Vector.add(Vector.subtract(this.vertexes[b],a).scale(1-g),Vector.subtract(this.vertexes[c],a).scale(g)).normalize().scale(a.radius).add(a);d&&(e.center=a);this.vertexes.push(e);return this.vertexes.length-1},rotate:function(d,c){for(var b=0;b<this.vertexes.length;b++){var a=Vector.rotate(this.vertexes[b],d,c);this.vertexes[b].x=a.x;this.vertexes[b].y=a.y;this.vertexes[b].z=a.z}},transform:function(a){for(var b=0;b<this.vertexes.length;b++){var c=a.translateVector(this.vertexes[b]);this.vertexes[b].x=c.x;this.vertexes[b].y=c.y;this.vertexes[b].z=c.z}},offset:function(b){for(var a=0;a<this.vertexes.length;a++){this.vertexes[a].add(b)}},scale:function(b){for(var a=0;a<this.vertexes.length;a++){this.vertexes[a].scale(b)}},ribLength:function(c,b){var a=this.vertexes[c].clone().subtract(this.vertexes[b]).length();if(a>5){alert("ribLength("+this.vertexes[c]+", "+this.vertexes[b]+")="+a);asf=af.asf.as.f/f}return a},deleteUnusedVertexes:function(){var d={},c=[];for(var b=0;b<this.faces.length;b++){for(var a=0;a<3;a++){d[this.faces[b][a]]=1}}for(var b=0,a=0;b<this.vertexes.length;b++){if(d[b]){c[b]=a++}}for(var b=this.vertexes.length-1;b>=0;b--){if(!d[b]){this.vertexes.splice(b,1)}}for(var b=0;b<this.faces.length;b++){for(var a=0;a<3;a++){this.faces[b][a]=c[this.faces[b][a]]}}},addFace:function(e,d,g){this.faces.push([e,d,g])},empty:function(){return this}};function Icosahedron(){var d=4/Math.sqrt(2*(5+Math.sqrt(5)))/2,c=Math.sqrt(1-d*d);var g=[[-d,0,c],[d,0,c],[-d,0,-c],[d,0,-c],[0,c,d],[0,c,-d],[0,-c,d],[0,-c,-d],[c,d,0],[-c,d,0],[c,-d,0],[-c,-d,0]];this.vertexes=[];for(var e=0;e<g.length;e++){this.vertexes[e]=new Vector(g[e][0],g[e][1],g[e][2])}this.faces=[[0,4,1],[0,9,4],[9,5,4],[4,5,8],[4,8,1],[8,10,1],[8,3,10],[5,3,8],[5,2,3],[2,7,3],[7,10,3],[7,6,10],[7,11,6],[11,0,6],[0,1,6],[6,1,10],[9,0,11],[9,11,2],[9,2,5],[7,2,11]];this.rotate(Math.atan(d/c),"x")}Icosahedron.prototype=new Surface();__clone=function(a,c){if(a instanceof Array){var d=[];for(var b=0;b<a.length;b++){d[b]=a[b]}if(c){for(var b in a){if(typeof(b)!="number"){d[b]=a[b]}}}return d}else{var d={};for(var b in a){d[b]=a[b]}return d}};Array.prototype.subst=function(c){var a=[];for(var b=0;b<this.length;b++){a[b]=(c[this[b]]!=undefined)?c[this[b]]:undefined}return a};Array.prototype.toString=Object.prototype.toString=function(){var b=[];for(var c in this){if((""+c).indexOf("Moz")!=0&&typeof(this[c])!="function"){b[b.length]=""+c+": "+this[c]}}return"{"+b.join(", ")+"}"};
