...implemented with the help of Processing.js. Click and drag on the molecule to rotate, zoom and translate.
float[][] atoms = {{ 0.710900, 0.037800, 0.156700 }, { 2.503200, 0.016200, -0.016200 }, { 2.891000, -0.757600, -1.285100 }, { 2.464200, -2.218700, -1.241500 }, { 3.023400, 1.457700, -0.000800 }, { 2.284300, 2.444200, -0.015900 }, { 4.501400, 1.700400, 0.054300 }, { 5.440400, 0.664600, 0.139400 }, { 6.807300, 0.939900, 0.086400 }, { 7.250400, 2.257200, 0.023400 }, { 6.328300, 3.301100, 0.002600 }, { 4.959700, 3.024900, 0.004100 }, { 2.868300, -0.484600, 0.886500 }, { 3.973200, -0.754200, -1.439100 }, { 2.481000, -0.267500, -2.175500 }, { 2.843500, -2.709100, -0.338600 }, { 2.864400, -2.753100, -2.108600 }, { 1.376200, -2.320800, -1.261800 }, { 5.150800, -0.375700, 0.237800 }, { 7.524100, 0.122200, 0.097500 }, { 8.315900, 2.470000, 0.000500 }, { 6.672500, 4.332000, -0.022800 }, { 4.252400, 3.852800, -0.032800 }}; bonds = {{ 0, 1 }, { 1, 4 }, { 1, 2 }, { 1, 12 }, { 2, 3 }, { 2, 13 }, { 2, 14 }, { 3, 15 }, { 3, 16 }, { 3, 17 }, { 4, 6 }, { 4, 5 }, { 6, 11 }, { 6, 7 }, { 7, 8 }, { 7, 18 }, { 8, 9 }, { 8, 19 }, { 9, 10 }, { 9, 20 }, { 10, 11 }, { 10, 21 }, { 11, 22 }}; elements = [17, 6, 6, 6, 7, 1, 6, 6, 6, 6, 6, 6, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]; color[] CPK = new color[17]; CPK[1] = color(255, 255, 255); CPK[7] = color(0, 0, 255); CPK[6] = color(150, 150, 150); CPK[17] = color(0, 255, 0); float[] angles = {0, 0, 0}; // Angles around x,y,z axes float[][] coords = new float[atoms.length][3]; int myredraw = 1; float zoom = 20; float[] dragorigin = [0, 0]; float[] anglesorigin = [0, 0]; float zoomorigin; float[] trans = [width/2, height/2]; float[] transorigin; void setup() { size(320, 240); noStroke(); centremol(); for(i=0;i<atoms.length;i++) { coords[i] = {atoms[i][0], atoms[i][1], atoms[i][2]}; } } void centremol() { for(int i=0; i < atoms.length; i++) { atoms[i][0] = atoms[i][0]; atoms[i][1] = atoms[i][1]; atoms[i][2] = atoms[i][2]; } float totx = 0; float toty = 0; float totz = 0; for(i=0; i < atoms.length; i++) { totx += atoms[i][0]; toty += atoms[i][1]; totz += atoms[i][2]; } meanx = totx / atoms.length; meany = toty / atoms.length; meanz = totz / atoms.length; for(i=0; i < atoms.length; i++) { atoms[i][0] = atoms[i][0] - meanx; atoms[i][1] = atoms[i][1] - meany; atoms[i][2] = atoms[i][2] - meanz; } } void draw_atoms() { // A poor man's z-order sort (not worth spending much time // on as you can sort using a function in javascript) float[] depth = new float[atoms.length]; for(int i=0;i<atoms.length;i++) depth[i] = coords[i][2]; for(int i=0; i < atoms.length; i++) { max = 0; for(int j=0; j < atoms.length; j++) { if(depth[j] < depth[max]) { max = j; } } depth[max] = +9999; x = coords[max][0]; y = coords[max][1]; z = coords[max][2]; // fill(color(0, 0, 0)); fill(CPK[elements[max]]); radius = 1; if (elements[max]==1) radius=0.5; ellipse(x, y, radius, radius); fill(color(255, 255, 255)); ellipse(x - 0.05, y - 0.2, 0.1, 0.1); fill(color(180, 180, 180, 150)); ellipse(x, z/5 + 5, 1, 0.3); } } void mousePressed() { dragorigin = [mouseX, mouseY]; // Can't just say anglesorigin = angles (doesn't make a copy) anglesorigin = [angles[0], angles[1], angles[2]]; zoomorigin = zoom; transorigin = [trans[0], trans[1]]; } void mouseDragged() { if (mouseButton == LEFT) { angles[0] = anglesorigin[0] + (dragorigin[1] - mouseY)/50; angles[1] = anglesorigin[1] + (dragorigin[0] - mouseX)/50; } else if (mouseButton == RIGHT) { zoom = zoomorigin + (dragorigin[1] - mouseY)/10; angles[2] = anglesorigin[2] + (dragorigin[0] - mouseX)/50; } else if (mouseButton == CENTER) { trans[0] = transorigin[0] - (dragorigin[0] - mouseX); trans[1] = transorigin[1] - (dragorigin[1] - mouseY); } myredraw = 1; } void rotateAround() { // Rotate around X float c = cos(angles[0]); float s = sin(angles[0]); for (i=0;i<atoms.length;i++) { coords[i][0] = atoms[i][0]; coords[i][1] = atoms[i][1] * c - atoms[i][2] * s; coords[i][2] = atoms[i][1] * s + atoms[i][2] * c; } // Rotate around Y float c = cos(angles[1]); float s = sin(angles[1]); for (i=0;i<atoms.length;i++) { t = coords[i][0] * c - coords[i][2] * s; u = coords[i][0] * s + coords[i][2] * c; coords[i][0] = t; coords[i][2] = u; } // Rotate around Z float c = cos(angles[2]); float s = sin(angles[2]); for (i=0;i<atoms.length;i++) { t = coords[i][0] * c - coords[i][1] * s; u = coords[i][0] * s + coords[i][1] * c; coords[i][0] = t; coords[i][1] = u; } } void draw_bonds() { strokeWeight(0.1); for(i=0; i< bonds.length; i++) { start = bonds[i][0]; end = bonds[i][1]; line(coords[start][0], coords[start][1], coords[end][0], coords[end][1]); } } void draw() { if (myredraw) { background(226); //translate(width/2, height/2); translate(trans[0], trans[1]); scale(zoom); rotateAround(); draw_bonds(); draw_atoms(); myredraw = 0; } }