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;
};