// This began as... // Spring // by REAS // and became... // testMOD99 // mangled by oz // Updated 03 NOV 03 // to become a demonstration of secondary emission of electrons // as background history for The RCA Selectron digital memory tube // Click and drag the storage eyelet to change its potential // Spring drawing constants for eyelet int max = 250; // Maximum Y value int min = 150; // Minimum Y value boolean over0 = false; // If mouse over clear boolean over1 = false; // If mouse over set boolean move = false; // If mouse down and over int charge = 20; // Initial charge on eyelet int size = 5; // Width of the shape int ypos; // Position of electrons int ringer; // Position of the electron which can succeed int yspeed = 10; // Speed of the electrons int ydirection = 1; // Top to Bottom int ringerdir = 1; // Top to Bottom of the lone electron int drift = 0; // Deflected electron lateral movement float level = 0; // Top of the heap float twins = 1; // secondary electron display enable float dl = 0; //drift * level float dlt = 0; // drift * level * twins // Spring simulation constants float M = 0.8; // Mass float K = 0.2; // Spring constant float D = 0.07; // Damping float R = 200; // Rest position // Spring simulation variables float ps = 200.0; // Position float vs = 0.0; // Velocity float as = 0; // Acceleration float f = 0; // Force BFont metaItalic; // The font "Meta-Italic.vlw.gz" must be located in the // current sketch's "data" directory to load successfully void setup() { size(500, 380); rectMode(CORNERS); noStroke(); colorMode(RGB); framerate(10); metaItalic = loadFont("Meta-Italic.vlw.gz"); // Set the starting position of the electron beam ypos = 40; ringer = 40; textFont(metaItalic, 20); } void loop() { background(102); updateEyelet(); drawEyelet(); // border fill (0); rect (0,0,2,380); rect (0,0,500,2); rect (500,380,0,378); rect (500,380,498,0); // buttons if ( over0 ){ fill(255); } rect (400,240,420,260); fill (0); if ( over1 ){ fill(255); } rect (400,300,420,320); // Cathodes are red fill(200,75,30); rect(180, 44, 122, 36); // Collectors are gray fill(70,70,70); rect(195, 45, 440, 35); fill(255,255,255); text("region where electrons are repelled",205, 140); text("region where electrons are collected",205, 170); text("region where electrons are ejected",205, 200); text("cathode",125, 30); text("phosphor",120 , 345); text("Secondary Electron Emission", 250, 373); text("collector",278, 30); text("pulse eyelet low",290, 255); text("pulse eyelet high",287, 315); // Electrons are blue...right? fill(20,200,200); // Above this level, lower potential, electrons are repelled rect(205, 150, 215, 151); // Below this level, higher potential, secondary electrons are ejected rect(205, 180, 215, 181); // Update the position of the electron beam ypos = ypos + (yspeed * ydirection); ringer = ringer + (yspeed * ringerdir); level = (ps + 5 - charge - ypos); // Blast out secondaries if charge is low (delta potential high) if (ps - charge > 180 && ypos > ps - 5 - charge) { ydirection = -1; ringerdir = -1; charge = charge - 9; yspeed = 15; drift = -1; twins = 0.5; } // Let the lone electron pass if ((charge < 2) && (ypos > 180)) { ringerdir = 1; } // Hey, this ain't a Van de Graaff -- leakage exists if (charge < 0) { charge = 0; } // repel if fully charged // (charge) && (touch: where repelled) if ( ((ps - charge ) <155) && ypos > ps - 15 - charge) { ydirection = -1; ringerdir = -1; charge = charge - 3; drift = -1; yspeed = 15; } //emit some electrons from the cathode, if none in play if (ypos > ps + 5 - charge || ypos < 30) { ypos = 37; ringer = 37; drift = 0; yspeed = 10; twins = 1; ydirection = 1; ringerdir = 1; charge = charge + 3; } // Let the lone electron pass if ((charge < 2) && (ypos > 180)) { ringerdir = 1; } // Draw the primary electrons dl = drift * level; dlt = dl * twins; ellipse(130 - dl * 1.3, ypos, 5, 5); ellipse(170 - dl * 1.3, ypos, 5, 5); ellipse(140 - dl, ypos, 5, 5); ellipse(160 - dl, ypos, 5, 5); // And draw the secondaries -- coincident if they don't exist ellipse(130 - dlt * 1.3, ypos, 5, 5); ellipse(170 - dlt * 1.3, ypos, 5, 5); ellipse(140 - dlt, ypos, 5, 5); ellipse(160 - dlt, ypos, 5, 5); // Draw our lone secondary electron ellipse(150 + (dl * .3 * (ringerdir - 1)) , ringer, 5, 5); // Draw a phosphor grain. fill(20,250 - 2 * (ringer - 305),20); if (ringer <305 ){ fill(20,100,20); } ellipse(140, 300, 20, 20); } // Hey, this ain't FORTRAN ... there's no GOTO void drawEyelet() { // Set color and draw eyelet and electrons if( ( (over0 || over1) && move ) || (key == 'n' && keyPressed == true) || (key == 'p' && keyPressed == true) ) { fill(255); } else { fill(0); } rect(100, ps, 146, ps + 10); rect(156, ps, 200, ps + 10); rect(100, ps - 50, 105, ps); rect(200, ps - 50, 195, ps); fill(20,200,200); rect(105, ps, 195, ps - charge); fill(255,255,255); text("eyelet",53, ps - 25); // Draw voltage divider stroke(255); // line(100, ps -10, 35, ps - 10 ); // line(60, ps, 35, ps ); line(100, ps - 10, 50, ps - 10 ); line(45, ps - 10, 35, ps - 10 ); line(45, ps - 4, 45, ps - 16 ); line(50, ps - 4, 50, ps - 16 ); line(38, ps -7, 35, ps - 10 ); line(38, ps - 13, 35, ps - 10 ); line(32, 40, 122, 40); line (135, 325, 33, 325); line (33, 350, 33, 280); point(140, 325); point(144, 325); point(148, 325); point(152, 325); point(156, 325); point(160, 325); beginShape(LINE_STRIP); vertex(32, 30); vertex(32, 73); vertex(30, 75); vertex(35, 80); vertex(30, 85); vertex(35, 90); vertex(30, 95); vertex(35, 100); vertex(32, 103); vertex(32, 110); vertex(32, 137); vertex(30, 140); vertex(35, 145); vertex(30, 150); vertex(35, 155); vertex(30, 160); vertex(35, 165); vertex(30, 170); vertex(35, 175); vertex(30, 180); vertex(35, 185); vertex(30, 190); vertex(35, 195); vertex(30, 200); vertex(35, 205); vertex(30, 210); vertex(35, 215); vertex(30, 220); vertex(35, 225); vertex(30, 230); vertex(35, 235); vertex(30, 240); vertex(35, 245); vertex(33, 247); vertex(33, 280); endShape(); text("+V", 25, 370); text("-V", 25, 15); noStroke(); } void updateEyelet() { // Update the eyelet position if(!move) { f = -K * (ps - R); // f=-ky as = f / M; // Set the acceleration, f=ma == a=f/m vs = D * (vs + as); // Set the velocity ps = ps + vs; // Updated position } if(abs(vs) < 0.1) { vs = 0.0; } // Test if mouse is over if( mouseY > 300 && mouseY < 320 && mouseX > 400 && mouseX < 420 ) { over1 = true; } else { over1 = false; } if( mouseY > 240 && mouseY < 260 && mouseX > 400 && mouseX < 420 ) { over0 = true; } else { over0 = false; } // Set and constrain the position of eyelet if( (move && over0) || (key == 'n' && keyPressed == true) ){ ps = 150; } if( (move && over1) || (key == 'p' && keyPressed == true) ){ ps = 250; } } void mousePressed() { if(over1 || over0) { move = true; } } void mouseReleased() { move = false; }