No description provided
Chemistry
The showcase player uses a modified version of Processing.js in combination with jsweet to let students program their apps in Java code while still allowing for browser support.
Content created by students is scaled to fit the showcase frame while maintaining aspect ratio and cursor position. This is why some projects may appear blurry in fullscreen, or why some small details may not be visible on a small screen
<iframe width='500px' height='400px' src='https://nest.ktbyte.com/nest#98111' allowfullscreen></iframe>
int[] centerOfAtom = new int[]{250, 250}; String[] elementNames = {"Hydrogen", "Helium", "Lithium", "Beryllium", "Boron", "Carbon", "Nitrogen", "Oxygen", "Flourine", "Neon", "Sodium", "Magnesium", "Aluminium", "Silicon", "Phosphorous", "Sulfur", "Chlorine", "Argon", "Potassium", "Calcium"}; String[] elementAbbr = {"H", "He", "Li", "Be", "B", "C", "N", "O", "F", "Ne", "Na", "Mg", "Al", "Si", "P", "S", "Cl", "Ar", "K", "Ca"}; float[][] teardrop = {{0, 0}, {-38.04226065180614, -137.63932022500208}, {-39.78087581473093, -145.81886146929386}, {-39.94518139018296, -152.09343824971774}, {-38.63703305156274, -160.3527618041008}, {-35.640260967534736, -168.15961998958184}, {-29.72579301909583, -176.76522425435428}, {-21.785561400601175, -183.54682271781692}, {-14.33471798181214, -187.34321705988805}, {-8.316467632710538, -189.12590402935223}, {-2.093438249717951, -189.94518139018297}, {4.181138530705902, -189.780875814731}, {10.352761804100583, -188.6370330515628}, {18.159619989581643, -185.64026096753483}, {25.172815641993296, -181.08583845827897}, {31.085838458278662, -175.17281564199365}, {35.640260967534566, -168.15961998958204}, {38.63703305156261, -160.35276180410105}, {39.94518139018288, -152.09343824971802}, {39.780875814730905, -145.81886146929412}, {38.04226065180617, -137.63932022500236}}; PVector[] teardropVertices = new PVector[teardrop.length]; PVector[] oppTeardropVertices = new PVector[teardrop.length]; int electrons = 0; int nucleusSize = 7; boolean sparaticMotion = false; boolean labelSubshells = false; ArrayList<Float[]> protons = new ArrayList<Float[]>(); ArrayList<Float[]> neutrons = new ArrayList<Float[]>(); void setup() { size(640, 500); for (int i = 0; i < teardrop.length; i ++) { teardropVertices[i] = (new PVector(teardrop[i][0], teardrop[i][1])); oppTeardropVertices[i] = (new PVector(teardrop[i][0], -1 * teardrop[i][1])); } //angleMode(DEGREES); increaseElectrons(); frameRate(10); } void decreaseElectrons() { electrons = constrain(electrons - 1, 0, 18); protons.remove(protons.size()-1); neutrons.remove(neutrons.size()-1); } void increaseElectrons() { if (electrons < 18) { Float[] pLoc = {random(centerOfAtom[0] - nucleusSize, centerOfAtom[0] + nucleusSize), random(centerOfAtom[1] - nucleusSize, centerOfAtom[1] + nucleusSize)}; Float[] nLoc = {random(centerOfAtom[0] - nucleusSize, centerOfAtom[0] + nucleusSize), random(centerOfAtom[1] - nucleusSize, centerOfAtom[1] + nucleusSize)}; while (!(dist(pLoc[0], pLoc[1], nLoc[0], nLoc[1]) < 10)) { pLoc = new Float[]{random(centerOfAtom[0] - nucleusSize, centerOfAtom[0] + nucleusSize), random(centerOfAtom[1] - nucleusSize, centerOfAtom[1] + nucleusSize)}; nLoc = new Float[]{random(centerOfAtom[0] - nucleusSize, centerOfAtom[0] + nucleusSize), random(centerOfAtom[1] - nucleusSize, centerOfAtom[1] + nucleusSize)}; } protons.add(pLoc); neutrons.add(nLoc); } electrons = constrain(electrons + 1, 0, 18); } void keyPressed() { if (keyCode == LEFT || keyCode == DOWN) { decreaseElectrons(); } if (keyCode == RIGHT || keyCode == UP) { increaseElectrons(); } if (key==' ') { sparaticMotion = !sparaticMotion; } } void dispNucleus() { stroke(0); for (int i = 0; i < protons.size(); i ++) { fill(80); ellipse(neutrons.get(i)[0], neutrons.get(i)[1], 10, 10); fill(230); ellipse(protons.get(i)[0], neutrons.get(i)[1], 10, 10); } } void drawAtom() { if (electrons >= 1) { dispCircle(50); dispElectron(35, -45, "circle", 50); if (electrons >= 2)dispElectron(35, -225, "circle", 50); } //1s; electrondistance = 35; if (electrons >= 3) { dispCircle(70); dispElectron(60, -45, "circle", 70); if (electrons >= 4)dispElectron(60, -225, "circle", 70); } //2s; electrondistance = 60; if (electrons >= 5) { dispTearDrop(90, 1); dispTearDrop(270, 1); dispElectron(150, 90, "tear", 1); //2px1 if (electrons >= 6) { dispTearDrop(0, 1); dispTearDrop(180, 1); dispElectron(150, 0, "tear", 1); } //2py1 if (electrons >= 7) { dispTearDrop(45, 1); dispTearDrop(225, 1); dispElectron(150, 45, "tear", 1); } //2pz1 if (electrons >= 8)dispElectron(150, 270, "tear", 1); if (electrons >= 9)dispElectron(150, 180, "tear", 1); if (electrons >= 10)dispElectron(150, 225, "tear", 1); } //2p; electrondistance = 150 if (electrons >= 11) { dispCircle(110); dispElectron(95, -45, "circle", 110); if (electrons >= 12)dispElectron(95, -225, "circle", 110); } //3s; electrondistance = 95; if (electrons >= 13) { dispTearDrop(90, 1.3); dispTearDrop(270, 1.3); dispElectron(220, 90, "tear", 1.3); //3px1 if (electrons >= 14) { dispTearDrop(0, 1.3); dispTearDrop(180, 1.3); dispElectron(220, 0, "tear", 1.3); } //3py1 if (electrons >= 15) { dispTearDrop(45, 1.3); dispTearDrop(225, 1.3); dispElectron(220, 45, "tear", 1.3); } //3pz1 if (electrons >= 16)dispElectron(220, 270, "tear", 1.3); if (electrons >= 17)dispElectron(220, 180, "tear", 1.3); if (electrons >= 18)dispElectron(220, 225, "tear", 1.3); } //3p /*if(electrons > 4){ dispTearDrop(90, 1) dispTearDrop(270, 1) //2px dispElectron(150, 90, "tear", 1) if(electrons >= 6)dispElectron(150, 270, "tear", 1); if(electrons > 6){ dispTearDrop(0, 1) dispTearDrop(180, 1) dispElectron(150, 0, "tear", 1) if(electrons >= 8)dispElectron(150, 180, "tear", 1); } //2py if(electrons > 8){ dispTearDrop(45, 1) dispTearDrop(225, 1) dispElectron(150, 45, "tear", 1) if(electrons >= 10)dispElectron(150, 225, "tear", 1); } //2pz } //2p; electrondistance = 150 */ /*if(electrons > 10){ dispCircle(110) dispElectron(95, -45, "circle", 110) if(electrons >= 12)dispElectron(95, -225, "circle", 110); } //3s; electrondistance = 95; */ /*if(electrons > 12){ dispTearDrop(90, 1.3) dispTearDrop(270, 1.3) dispElectron(220, 90, "tear", 1.3) if(electrons >= 14)dispElectron(220, 270, "tear", 1.3); //3px if(electrons > 14){ dispTearDrop(0, 1.3) dispTearDrop(180, 1.3) dispElectron(220, 0, "tear", 1.3) if(electrons >= 16)dispElectron(220, 180, "tear", 1.3); } //3py if(electrons > 16){ dispTearDrop(45, 1.3) dispTearDrop(225, 1.3) dispElectron(220, 45, "tear", 1.3) if(electrons >= 18)dispElectron(220, 225, "tear", 1.3); } //3pz } //3p; electrondistance = 220; */ pushMatrix(); fill(255); translate(centerOfAtom[0], centerOfAtom[1]); if (labelSubshells) { if (electrons > 0)text("1s", 30, 4); if (electrons > 2)text("2s", 55, 4); if (electrons > 4)text("2px", 160, 4); if (electrons > 5)text("2py", -10, -165); if (electrons > 6)text("2pz", 113, -113); if (electrons > 10)text("3s", 80, 4); if (electrons > 12)text("3px", 226, 4); if (electrons > 13)text("3py", -10, -230); if (electrons > 14)text("3pz", 160, -160); } popMatrix(); dispNucleus(); } void draw() { background(0); drawAtom(); stroke(255); line(510, 20, 510, 480); noStroke(); fill(255); text("Sporadic Motion", 535, 49); text("Label Subshells", 535, 75); text(electrons + " Electrons", 538, 118); rect(520, 40, 10, 10); rect(520, 66, 10, 10); if (sparaticMotion) { fill(100, 100, 255); rect(522, 42, 6, 6); } if (labelSubshells) { fill(100, 100, 255); rect(522, 68, 6, 6); } fill(130, 130, 255); pushMatrix(); translate(525, 113); triangle(-7.5, -3, 0, -13, 7.5, -3); triangle(7.5, 3, 0, 13, -7.5, 3); popMatrix(); if (electrons > 0) { fill(247, 236, 210); rect(520, 360, 111, 111); fill(0); textSize(50); textAlign(CENTER); text(elementAbbr[electrons -1], 577, 419); textSize(15); text(elementNames[electrons - 1], 577, 445); textSize(20); text(electrons, 577, 465); textAlign(LEFT); textSize(12); } noFill(); stroke(255); rect(0, 0, width - 1, height - 1); } void mousePressed() { if (collidePointRect(mouseX, mouseY, 520, 40, 10, 10)) { sparaticMotion = !sparaticMotion; } if (collidePointRect(mouseX, mouseY, 520, 66, 10, 10)) { labelSubshells = !labelSubshells; } if (collidePointRect(mouseX, mouseY, 516, 98, 20, 20)) { increaseElectrons(); } if (collidePointRect(mouseX, mouseY, 516, 113, 20, 20)) { decreaseElectrons(); } } void dispElectron(float distance, float angle, String shapeArg, float scaleArg) { pushMatrix(); translate(centerOfAtom[0], centerOfAtom[1]); rotate(radians(angle)); fill(255, 255, 0); noStroke(); if (!sparaticMotion) { ellipse(0, -1 * distance, 8, 8); } if (sparaticMotion) { float[] chosenLoc = {random(-70, 70), random(-360, 360)}; while (shapeArg.equals( "tear") && !(collidePointPoly(chosenLoc[0], chosenLoc[1], teardropVertices) || collidePointPoly(chosenLoc[0], chosenLoc[1], oppTeardropVertices))) { chosenLoc = new float[]{random(-70, 70), random(-360, 360)}; } while (shapeArg.equals("circle") && dist(chosenLoc[0], chosenLoc[1], 0, 0) >= scaleArg) { chosenLoc = new float[]{random(-80, 80), random(-80, 80)}; } float circleSize = 8; if (shapeArg == "tear") { scale(scaleArg); circleSize = 8/scaleArg; } ellipse(chosenLoc[0], chosenLoc[1], circleSize, circleSize); } popMatrix(); } void dispCircle(float size) { fill(255, 0, 0, 120); noStroke(); ellipse(centerOfAtom[0], centerOfAtom[1], size*2, size*2); } void dispTearDrop(float angle, float scaleArg) { pushMatrix(); translate(centerOfAtom[0], centerOfAtom[1]); rotate(radians(angle)); scale(scaleArg); noStroke(); fill(255, 0, 0, 120); beginShape(); for (int j = 0; j < teardrop.length; j ++) { vertex(teardrop[j][0], teardrop[j][1]); } endShape(CLOSE); popMatrix(); } boolean collidePointPoly(float px, float py, PVector[] vertices) { boolean collision = false; // go through each of the vertices, plus the next vertex in the list int next = 0; for (int current=0; current<vertices.length; current++) { // get next vertex in list if we've hit the end, wrap around to 0 next = current+1; if (next == vertices.length) next = 0; // get the PVectors at our current position this makes our if statement a little cleaner PVector vc = vertices[current]; // c for "current" PVector vn = vertices[next]; // n for "next" // compare position, flip 'collision' variable back and forth if (((vc.y > py && vn.y < py) || (vc.y < py && vn.y > py)) && (px < (vn.x-vc.x)*(py-vc.y) / (vn.y-vc.y)+vc.x)) { collision = !collision; } } return collision; } boolean collidePointRect (float pointX, float pointY, float x, float y, float xW, float yW) { //2d if (pointX >= x && // right of the left edge AND pointX <= x + xW && // left of the right edge AND pointY >= y && // below the top AND pointY <= y + yW) { // above the bottom return true; } return false; };