Template:Team:UC Davis/KO3D
From 2013.igem.org
(Difference between revisions)
Line 246: | Line 246: | ||
//cool_color_ramp = [[0,0,0], [0,0,1], [1,1,1]]; | //cool_color_ramp = [[0,0,0], [0,0,1], [1,1,1]]; | ||
+ | function plot_3d(){ | ||
+ | data_3d = []; | ||
+ | errorbars_3d = []; | ||
+ | particles = []; | ||
+ | meshchildren = []; | ||
+ | //Parse datas! | ||
+ | $('.zdata_3d').each( | ||
+ | function(index) | ||
+ | { | ||
+ | particles.push(new THREE.Geometry()); | ||
+ | thisdataz = $(this).text().split(','); | ||
+ | thisdatax = $('.xdata_3d').eq(index).text().split(','); | ||
+ | thisdatay = $('.ydata_3d').eq(index).text().split(','); | ||
+ | thisdataerr = $('.stdevs_3d').eq(index).text().split(','); | ||
+ | |||
+ | |||
+ | //numxpoints = thisdatax.length; | ||
+ | //numypoints = thisdatay.length; | ||
+ | meshchildren.push(new THREE.Object3D()); | ||
+ | errorbars_3d.push(new THREE.Object3D()); | ||
+ | data_3d.push(new THREE.PlaneGeometry(100,100,numxpoints-1, numypoints-1)); | ||
+ | var i; | ||
+ | for(i=0; i < thisdatax.length; ++i) | ||
+ | { | ||
+ | thisdatax[i] = parseFloat(thisdatax[i]); | ||
+ | } | ||
+ | for(i=0; i < thisdatay.length; ++i) | ||
+ | { | ||
+ | thisdatay[i] = parseFloat(thisdatay[i]); | ||
+ | } | ||
+ | for(i=0; i < thisdataz.length; ++i) | ||
+ | { | ||
+ | thisdataz[i] = parseFloat(thisdataz[i]); | ||
+ | |||
+ | /* | ||
+ | var particle = new THREE.Vertex( | ||
+ | new THREE.Vector3(thisdatax[i%thisdatax.length]/axisdimensions[1]*100, | ||
+ | thisdatay[Math.floor(i/thisdatax.length)]/axisdimensions[3]*100, | ||
+ | thisdataz[i]/axisdimensions[5]*100) | ||
+ | ); | ||
+ | particles[index].vertices.push(particle); | ||
+ | var newparticle = new THREE.Particle(pointMaterial) | ||
+ | newparticle.position.x = particle.position.x; | ||
+ | newparticle.position.y = particle.position.y; | ||
+ | newparticle.position.z = particle.position.z; | ||
+ | meshchildren[index].addChild(newparticle); | ||
+ | */ | ||
+ | |||
+ | |||
+ | } | ||
+ | var lineMat = new THREE.LineBasicMaterial( | ||
+ | { | ||
+ | color:mutantcolors_hex[index], | ||
+ | opacity:1, | ||
+ | linewidth:2 | ||
+ | } | ||
+ | ); | ||
+ | for(i=0; i < thisdataerr.length; i++) | ||
+ | { | ||
+ | thisdataerr[i] = parseFloat(thisdataerr[i]); | ||
+ | var errbargeom = new THREE.Geometry(); | ||
+ | errbargeom.vertices.push(new THREE.Vertex(new THREE.Vector3( | ||
+ | thisdatax[i%thisdatax.length]/axisdimensions[1]*100, | ||
+ | thisdatay[Math.floor(i/thisdatax.length)]/axisdimensions[3]*100, | ||
+ | thisdataz[i]/axisdimensions[5]*100-thisdataerr[i]/axisdimensions[5]*100 | ||
+ | ))); | ||
+ | errbargeom.vertices.push(new THREE.Vertex(new THREE.Vector3( | ||
+ | thisdatax[i%thisdatax.length]/axisdimensions[1]*100, | ||
+ | thisdatay[Math.floor(i/thisdatax.length)]/axisdimensions[3]*100, | ||
+ | thisdataz[i]/axisdimensions[5]*100+thisdataerr[i]/axisdimensions[5]*100 | ||
+ | ))); | ||
+ | var errbar = new THREE.Line(errbargeom, lineMat); | ||
+ | errorbars_3d[index].addChild(errbar); | ||
+ | } | ||
+ | //Particles look like ass. | ||
+ | //Use lines instead. | ||
+ | |||
+ | for(i=0; i < thisdatax.length*(thisdatay.length-1); i++) | ||
+ | { | ||
+ | |||
+ | var linegeom = new THREE.Geometry(); | ||
+ | linegeom.vertices.push(new THREE.Vertex(new THREE.Vector3( | ||
+ | thisdatax[i%thisdatax.length]/axisdimensions[1]*100, | ||
+ | thisdatay[Math.floor(i/thisdatax.length)]/axisdimensions[3]*100, | ||
+ | thisdataz[i]/axisdimensions[5]*100 | ||
+ | ))); | ||
+ | linegeom.vertices.push(new THREE.Vertex(new THREE.Vector3( | ||
+ | thisdatax[(i+thisdatax.length)%thisdatax.length]/axisdimensions[1]*100, | ||
+ | thisdatay[Math.floor((i+thisdatax.length)/thisdatax.length)]/axisdimensions[3]*100, | ||
+ | thisdataz[i+thisdatax.length]/axisdimensions[5]*100 | ||
+ | ))); | ||
+ | meshchildren[index].addChild(new THREE.Line(linegeom, lineMat)); | ||
+ | } | ||
+ | for(i=0; i < (thisdatax.length-1)*(thisdatay.length); i++) | ||
+ | { | ||
+ | //Particles look like ass. | ||
+ | //Use lines instead. | ||
+ | var linegeom = new THREE.Geometry(); | ||
+ | linegeom.vertices.push(new THREE.Vertex(new THREE.Vector3( | ||
+ | thisdatax[i%(thisdatax.length-1)]/axisdimensions[1]*100, | ||
+ | thisdatay[Math.floor(i/(thisdatax.length-1))]/axisdimensions[3]*100, | ||
+ | thisdataz[Math.floor(i/(thisdatax.length-1))+i]/axisdimensions[5]*100 | ||
+ | ))); | ||
+ | linegeom.vertices.push(new THREE.Vertex(new THREE.Vector3( | ||
+ | thisdatax[i%(thisdatax.length-1)+1]/axisdimensions[1]*100, | ||
+ | thisdatay[Math.floor(i/(thisdatax.length-1))]/axisdimensions[3]*100, | ||
+ | thisdataz[Math.floor(i/(thisdatax.length-1))+i+1]/axisdimensions[5]*100 | ||
+ | ))); | ||
+ | meshchildren[index].addChild(new THREE.Line(linegeom, lineMat)); | ||
+ | } | ||
+ | |||
+ | for(i=0; i < numxpoints; ++i) | ||
+ | { | ||
+ | for(var j=0; j < numypoints; ++j) | ||
+ | { | ||
+ | var thisx = thisdatax[thisdatax.length-1]*i/(numxpoints-1); | ||
+ | var thisy = thisdatay[thisdatay.length-1]*j/(numypoints-1); | ||
+ | data_3d[index].vertices[j*numxpoints+i].position.x = thisx/axisdimensions[1]*100; | ||
+ | data_3d[index].vertices[j*numxpoints+i].position.y = thisy/axisdimensions[3]*100; | ||
+ | //Find flanking x,y values | ||
+ | var kx = ky = 0; | ||
+ | while(thisx >= thisdatax[kx]) { | ||
+ | kx=kx+1; | ||
+ | } | ||
+ | while(thisy >= thisdatay[ky]) { | ||
+ | ky=ky+1; | ||
+ | } | ||
+ | if(kx > thisdatax.length-1) | ||
+ | { | ||
+ | kx = thisdatax.length-1; | ||
+ | } | ||
+ | if(ky > thisdatay.length-1) | ||
+ | { | ||
+ | ky = thisdatay.length-1; | ||
+ | } | ||
+ | kx--; | ||
+ | ky--; | ||
+ | |||
+ | kx = parseInt(kx); | ||
+ | ky = parseInt(ky); | ||
+ | var tli = kx+ky*thisdatax.length; | ||
+ | var tri = kx+ky*thisdatax.length+1; | ||
+ | var bli = kx+(ky+1)*thisdatax.length; | ||
+ | var bri = kx+1+(ky+1)*thisdatax.length; | ||
+ | if(!thisdataz[bli] || !thisdataz[tli] || !thisdataz[tri] || !thisdataz[bri]) | ||
+ | { | ||
+ | alert("Porblem!\nkx:" + kx + "\nky:" + ky + "\nkx is a "+typeof(kx) + "\nky is a" +typeof(ky) + "\nset:" + index); | ||
+ | } | ||
+ | thisz = interp2(thisdatax[kx], | ||
+ | thisdatay[ky], | ||
+ | thisdatax[kx+1], | ||
+ | thisdatay[ky+1], | ||
+ | thisdataz[tli], | ||
+ | thisdataz[tri], | ||
+ | thisdataz[bli], | ||
+ | thisdataz[bri], thisx, thisy) | ||
+ | data_3d[index].vertices[j*numxpoints+i].position.z = thisz/axisdimensions[5]*100; | ||
+ | } | ||
+ | } | ||
+ | data_3d[index].computeCentroids(); | ||
+ | //vertex colors | ||
+ | /* | ||
+ | var colors = []; | ||
+ | for(i=0; i < thisdataz.length; ++i) | ||
+ | { | ||
+ | var color = new THREE.Color(0x550000); | ||
+ | // color.setHSV(.125, 1, 0); | ||
+ | colors.push(color); | ||
+ | } | ||
+ | */ | ||
+ | materials = []; | ||
+ | for(i=0; i < data_3d[index].faces.length; ++i) | ||
+ | { | ||
+ | thisfacecolor = ( | ||
+ | data_3d[index].vertices[data_3d[index].faces[i].a].position.z+ | ||
+ | data_3d[index].vertices[data_3d[index].faces[i].b].position.z+ | ||
+ | data_3d[index].vertices[data_3d[index].faces[i].c].position.z+ | ||
+ | data_3d[index].vertices[data_3d[index].faces[i].d].position.z)/4/100; | ||
+ | materials.push([new THREE.MeshBasicMaterial( | ||
+ | { | ||
+ | color:thisfacecolor*0xffffff, | ||
+ | opacity:.6 | ||
+ | } | ||
+ | )]); | ||
+ | if(!thisfacecolor) | ||
+ | { | ||
+ | alert("Something is terribly wrong!\na ("+data_3d[index].faces[i].a+"):"+data_3d[index].vertices[data_3d[index].faces[i].a].position.z+"\nb("+data_3d[index].faces[i].b+"):"+data_3d[index].vertices[data_3d[index].faces[i].b].position.z+"\nc("+data_3d[index].faces[i].c+"):"+data_3d[index].vertices[data_3d[index].faces[i].c].position.z+"\nd("+data_3d[index].faces[i].d+"):"+data_3d[index].vertices[data_3d[index].faces[i].a].position.z); | ||
+ | } | ||
+ | var newcolor = colorRamp(thisfacecolor, cool_color_ramp); | ||
+ | materials[i][0].color.setRGB(newcolor[0], newcolor[1], newcolor[2]); | ||
+ | data_3d[index].faces[i].materials = materials[i]; | ||
+ | } | ||
+ | |||
+ | } | ||
+ | ); | ||
+ | |||
+ | var origin = new THREE.Vertex(new THREE.Vector3(0,0,0)); | ||
+ | |||
+ | theta = -Math.PI/4; | ||
+ | phi = Math.PI/8; | ||
+ | |||
+ | //Axis labels | ||
+ | var x = document.createElement("canvas"); | ||
+ | var xc = x.getContext("2d"); | ||
+ | x.width = 400; | ||
+ | x.height = 40; | ||
+ | xc.fillStyle = "#ffffff"; | ||
+ | xc.font = "20pt arial"; | ||
+ | xc.textBaseline = "top"; | ||
+ | xc.fillText("Arabinose (% w/v)", 10, 0); | ||
+ | |||
+ | var xm = new THREE.MeshBasicMaterial({ | ||
+ | map: new THREE.Texture(x) | ||
+ | }); | ||
+ | xm.map.needsUpdate = true; | ||
+ | |||
+ | xaxislabel = new THREE.Mesh(new THREE.PlaneGeometry(400, 40, 2, 2), xm); | ||
+ | xaxislabel.position.x = -50; | ||
+ | xaxislabel.position.y = 0; | ||
+ | xaxislabel.position.z = -48; | ||
+ | xaxislabel.scale.x = 0.2; | ||
+ | xaxislabel.scale.y = -0.2; | ||
+ | xaxislabel.rotation.x = -Math.PI/2; | ||
+ | xaxislabel.rotation.y = -Math.PI/2; | ||
+ | xaxislabel.doubleSided = true; | ||
+ | |||
+ | var x = document.createElement("canvas"); | ||
+ | var xc = x.getContext("2d"); | ||
+ | x.width = 400; | ||
+ | x.height = 40; | ||
+ | xc.fillStyle = "#ffffff"; | ||
+ | xc.font = "20pt arial"; | ||
+ | xc.textBaseline = "top"; | ||
+ | xc.fillText("Theophylline (mM)", 10, 0); | ||
+ | |||
+ | var xm = new THREE.MeshBasicMaterial({ | ||
+ | map: new THREE.Texture(x) | ||
+ | }); | ||
+ | xm.map.needsUpdate = true; | ||
+ | |||
+ | yaxislabel = new THREE.Mesh(new THREE.PlaneGeometry(400, 40, 2, 2), xm); | ||
+ | yaxislabel.position.x = 0; | ||
+ | yaxislabel.position.y = -50; | ||
+ | yaxislabel.position.z = -48; | ||
+ | yaxislabel.scale.x = 0.2; | ||
+ | yaxislabel.scale.y = -0.2; | ||
+ | yaxislabel.rotation.x = -Math.PI/2; | ||
+ | yaxislabel.doubleSided = true; | ||
+ | |||
+ | var x = document.createElement("canvas"); | ||
+ | var xc = x.getContext("2d"); | ||
+ | x.width = 400; | ||
+ | x.height = 40; | ||
+ | xc.fillStyle = "#ffffff"; | ||
+ | xc.font = "20pt arial"; | ||
+ | xc.textBaseline = "top"; | ||
+ | xc.fillText("Fluorescence/OD", 10, 0); | ||
+ | |||
+ | var xm = new THREE.MeshBasicMaterial({ | ||
+ | map: new THREE.Texture(x) | ||
+ | }); | ||
+ | xm.map.needsUpdate = true; | ||
+ | |||
+ | zaxislabel = new THREE.Mesh(new THREE.PlaneGeometry(400, 40, 2, 2), xm); | ||
+ | zaxislabel.position.x = -50; | ||
+ | zaxislabel.position.y = -52; | ||
+ | zaxislabel.position.z = 0; | ||
+ | zaxislabel.rotation.x = -Math.PI/2; | ||
+ | zaxislabel.rotation.y = -Math.PI/2; | ||
+ | zaxislabel.rotation.z = -Math.PI/2; | ||
+ | zaxislabel.scale.x = 0.2; | ||
+ | zaxislabel.scale.y = -0.2; | ||
+ | |||
+ | zaxislabel.doubleSided = true; | ||
+ | zaxislabel.updateMatrix(); | ||
+ | |||
+ | |||
+ | var $container = $('#mw_3dplot'); | ||
+ | $('body').mouseup(function(){ | ||
+ | isdragging = false; | ||
+ | $container.unbind('mousemove'); | ||
+ | }); | ||
+ | $container.mousedown(function(event){ | ||
+ | isdragging = true; | ||
+ | lastMouseX = event.pageX; | ||
+ | lastMouseY = event.pageY; | ||
+ | $container.mousemove(function(event) | ||
+ | { | ||
+ | theta += (lastMouseX - event.pageX)/70 | ||
+ | phi -= (lastMouseY - event.pageY)/70; | ||
+ | lastMouseX = event.pageX; | ||
+ | lastMouseY = event.pageY; | ||
+ | rerender(); | ||
+ | }); | ||
+ | }); | ||
+ | renderer = new THREE.CanvasRenderer(); | ||
+ | //renderer.autoClear = false; | ||
+ | camera = new THREE.OrthoCamera( -75, 75, 75, -75, - 2000, 1000 ); | ||
+ | |||
+ | scene = new THREE.Scene(); | ||
+ | camera.position.x = 250; | ||
+ | camera.position.y = -150; | ||
+ | camera.position.z = 75; | ||
+ | camera.up.y = 0; | ||
+ | camera.up.z = 1; | ||
+ | // camera.rotation.y = -Math.PI/6; | ||
+ | camera.position.x = 250*Math.cos(theta); | ||
+ | camera.position.y = 250*Math.sin(theta); | ||
+ | renderer.setSize(WIDTH, HEIGHT); | ||
+ | $container.append(renderer.domElement); | ||
+ | var radius = 50, segments = 16, rings = 16; | ||
+ | |||
+ | sphere = new THREE.Mesh( | ||
+ | new THREE.SphereGeometry(radius, | ||
+ | segments, | ||
+ | rings), | ||
+ | sphereMaterial | ||
+ | ); | ||
+ | sphere.position.x = 50; | ||
+ | sphere.position.y = 50; | ||
+ | sphere.position.z = 50; | ||
+ | |||
+ | // add it to the scene | ||
+ | plot_mesh = []; | ||
+ | plot_points = []; | ||
+ | for(var i = 0; i < data_3d.length; ++i) | ||
+ | { | ||
+ | plot_mesh.push(new THREE.Mesh(data_3d[i], plotMaterial)); | ||
+ | plot_mesh[i].doubleSided = true; | ||
+ | |||
+ | plot_points.push(new THREE.ParticleSystem( | ||
+ | particles[i], | ||
+ | pointMaterial)); | ||
+ | } | ||
+ | |||
+ | plot_obj = new THREE.Object3D(); | ||
+ | plot_obj.rotation.z = -Math.PI/2; | ||
+ | plot_obj.scale.x = -1; | ||
+ | //plot_mesh.addChild(sphere); | ||
+ | |||
+ | |||
+ | axisgeom = new THREE.Geometry(); | ||
+ | axisgeom.vertices.push(origin); | ||
+ | axisgeom.vertices.push(new THREE.Vertex(new THREE.Vector3(100,0,0))); | ||
+ | axisgeom.vertices.push(new THREE.Vertex(new THREE.Vector3(98, 1, 0))); | ||
+ | axisgeom.vertices.push(new THREE.Vertex(new THREE.Vector3(98, -1, 0))); | ||
+ | axisgeom.vertices.push(new THREE.Vertex(new THREE.Vector3(100, 0, 0))); | ||
+ | |||
+ | xaxis = new THREE.Line( | ||
+ | axisgeom, | ||
+ | axisMat | ||
+ | ); | ||
+ | |||
+ | yaxis = new THREE.Line( | ||
+ | axisgeom, | ||
+ | axisMat | ||
+ | ); | ||
+ | yaxis.rotation.z = 90*Math.PI/180; | ||
+ | |||
+ | zaxis = new THREE.Line( | ||
+ | axisgeom, | ||
+ | axisMat | ||
+ | ); | ||
+ | scene.addChild(xaxislabel); | ||
+ | scene.addChild(yaxislabel); | ||
+ | scene.addChild(zaxislabel); | ||
+ | |||
+ | zaxis.rotation.y = -90*Math.PI/180; | ||
+ | |||
+ | plot_obj.position.x = -50; | ||
+ | plot_obj.position.z = -50; | ||
+ | plot_obj.position.y = -50; | ||
+ | |||
+ | zaxis.position.x = -50; | ||
+ | zaxis.position.z = -50; | ||
+ | zaxis.position.y = -50; | ||
+ | |||
+ | xaxis.position.x = -50; | ||
+ | xaxis.position.z = -50; | ||
+ | xaxis.position.y = -50; | ||
+ | |||
+ | yaxis.position.x = -50; | ||
+ | yaxis.position.z = -50; | ||
+ | yaxis.position.y = -50; | ||
+ | |||
+ | //plot_obj.addChild(particleSystem); | ||
+ | |||
+ | |||
+ | scene.addChild(xaxis); | ||
+ | scene.addChild(yaxis); | ||
+ | scene.addChild(zaxis); | ||
+ | scene.addChild(plot_obj); | ||
+ | // origin_object.addChild(sphere); | ||
+ | |||
+ | |||
+ | //Grid | ||
+ | var gridlinegeom = new THREE.Geometry(); | ||
+ | gridlinegeom.vertices.push(new THREE.Vertex(new THREE.Vector3(0,0,0))); | ||
+ | gridlinegeom.vertices.push(new THREE.Vertex(new THREE.Vector3(100,0,0))); | ||
+ | |||
+ | for(var i=1; i <= 5; i++) | ||
+ | { | ||
+ | var gridline = new THREE.Line(gridlinegeom, axisMat); | ||
+ | gridline.position.y = i/5*100-50; | ||
+ | gridline.position.x = -50; | ||
+ | gridline.position.z = -50; | ||
+ | scene.addChild(gridline); | ||
+ | |||
+ | |||
+ | |||
+ | var gridline = new THREE.Line(gridlinegeom, axisMat); | ||
+ | gridline.position.x = i/5*100-50; | ||
+ | gridline.position.y = -50; | ||
+ | gridline.position.z = -50; | ||
+ | gridline.rotation.z = Math.PI/2; | ||
+ | scene.addChild(gridline); | ||
+ | } | ||
+ | yticklabels = []; | ||
+ | xticklabels = []; | ||
+ | for(var i=1; i <= 5; i++) | ||
+ | { | ||
+ | var x = document.createElement("canvas"); | ||
+ | var xc = x.getContext("2d"); | ||
+ | x.width = 40; | ||
+ | x.height = 40; | ||
+ | xc.fillStyle = "#ffffff"; | ||
+ | xc.font = "12pt arial"; | ||
+ | xc.textBaseline = "top"; | ||
+ | xc.fillText(i/5*axisdimensions[1], 10, 0); | ||
+ | |||
+ | var xm = new THREE.MeshBasicMaterial({ | ||
+ | map: new THREE.Texture(x) | ||
+ | }); | ||
+ | xm.map.needsUpdate = true; | ||
+ | var xtick = new THREE.Mesh(new THREE.PlaneGeometry(13/ASPECT, 13, 2, 2), xm); | ||
+ | xtick.position.y = i/5*100-50; | ||
+ | xtick.position.x = -50; | ||
+ | xtick.position.z = -58; | ||
+ | xtick.rotation.x = Math.PI/2; | ||
+ | xtick.doubleSided = true; | ||
+ | xtick.updateMatrix(); | ||
+ | scene.addChild(xtick); | ||
+ | |||
+ | var x = document.createElement("canvas"); | ||
+ | var xc = x.getContext("2d"); | ||
+ | x.width = 80; | ||
+ | x.height = 40; | ||
+ | xc.fillStyle = "#ffffff"; | ||
+ | xc.font = "12pt arial"; | ||
+ | xc.textBaseline = "top"; | ||
+ | xc.fillText((i/5*axisdimensions[3]).toFixed(4), 10, 0); | ||
+ | |||
+ | var xm = new THREE.MeshBasicMaterial({ | ||
+ | map: new THREE.Texture(x) | ||
+ | }); | ||
+ | xm.map.needsUpdate = true; | ||
+ | var ytick = new THREE.Mesh(new THREE.PlaneGeometry(26/ASPECT, 13, 2, 2), xm); | ||
+ | ytick.position.x = i/5*100-50; | ||
+ | ytick.position.y = -50; | ||
+ | ytick.position.z = -58; | ||
+ | ytick.rotation.x = Math.PI/2; | ||
+ | ytick.doubleSided = true; | ||
+ | ytick.updateMatrix(); | ||
+ | scene.addChild(ytick); | ||
+ | |||
+ | xticklabels.push(xtick); | ||
+ | yticklabels.push(ytick); | ||
+ | } | ||
+ | |||
+ | var particle = new THREE.Particle(pointMaterial); | ||
+ | |||
+ | |||
+ | renderer.render(scene, camera); | ||
+ | }); | ||
var WIDTH = 650; | var WIDTH = 650; | ||
Line 569: | Line 1,043: | ||
- | $(document).ready(function | + | $(document).ready(function() { |
data_3d = []; | data_3d = []; | ||
errorbars_3d = []; | errorbars_3d = []; |
Revision as of 02:05, 28 October 2013