/* built with Studio Sketchpad:
* https://sketchpad.cc
*
* observe the evolution of this sketch:
* https://studio.sketchpad.cc/sp/pad/view/ro.eC03SBGtZfQ/rev.10
*
* authors:
* GoToLoop
* license (unless otherwise specified):
* creative commons attribution-share alike 3.0 license.
* https://creativecommons.org/licenses/by-sa/3.0/
*/
/**
* Simple Gears (v2.04)
* by Adrian Fernandez aKa Processor65
* Miami, FL. USA (Jul-31-2014)
* mod GoToLoop (Aug-01-2014)
*
* forum.processing.org/two/discussion/6576/simple-gears
* studio.processingtogether.com/sp/pad/export/ro.9WrTp2GiTlnLW/latest
*/
static final color[] INKS = {
#008000, #0000FF, #FF0000
};
final Gear[] gears = new Gear[INKS.length];
static final boolean online = 1/2 == 1/2.;
PImage bg;
void setup() {
size(1000, 600, JAVA2D);
noLoop();
frameRate(20);
noStroke();
strokeWeight(1);
rectMode(CENTER);
ellipseMode(CENTER);
createGears();
println(gears);
bg = createBG();
}
void mouseMoved() {
redraw();
}
void draw() {
if (online) set(0, 0, bg);
else background(bg);
for (Gear gear: gears) gear.renderDynamic();
}
void createGears() {
int offSetX = width*3>>2;
int offSetY = height>>1;
int rad = 100;
int spd = 1;
int cx = offSetX - rad - Gear.TOOTH_HEIGHT/2;
int cy = offSetY;
gears[0] = new Gear(cx, cy, rad, spd, 1);
rad = 50;
spd = 2;
cx = offSetX + rad + Gear.TOOTH_HEIGHT/2;
cy = offSetY - Gear.TOOTH_HEIGHT/2/spd;
gears[1] = new Gear(cx, cy, rad, spd, -1);
rad = 200;
float vel = .5;
cx = offSetX - rad*2 - Gear.TOOTH_HEIGHT*4/3;
cy = offSetY + round(Gear.TOOTH_HEIGHT*3/2/vel);
gears[2] = new Gear(cx, cy, rad, vel, -1);
}
PImage createBG() {
PGraphics pg = createGraphics(width, height, JAVA2D);
pg.beginDraw();
pg.smooth(4);
pg.ellipseMode(CENTER);
pg.textAlign(CENTER, CENTER);
pg.textSize(030);
pg.background(0);
pg.fill(-1);
pg.text("Move mouse sideways to see rotation", width>>1, height>>3);
int c = 0;
for (Gear gear: gears) gear.renderStatic(pg, INKS[c++]);
pg.endDraw();
return pg.get();
}
final class Gear {
static final int MIN_TEETH = 3, MAX_TEETH = 0200 - 1;
static final int TOOTH_HEIGHT = 18;
final short centerX, centerY, rad;
final byte teeth, toothWidth;
final float vel, toothAngle;
final short lineY, toothHY;
Gear(int cx, int cy, int dim, float spd, int dir) {
centerX = (short) cx;
centerY = (short) cy;
rad = (short) dim;
vel = spd*dir;
teeth = (byte) constrain(dim/5, MIN_TEETH, MAX_TEETH);
toothAngle = TWO_PI/teeth;
toothWidth = (byte) round(sin(toothAngle/2.0)*dim);
lineY = (short) (TOOTH_HEIGHT + round(cos(toothAngle/2.0)*dim));
toothHY = (short) (TOOTH_HEIGHT - lineY);
}
void renderStatic(PGraphics pg, color c) {
pg.stroke(100);
pg.strokeWeight(2);
pg.fill(0250);
pg.ellipse(centerX, centerY, -toothHY<<1, -toothHY<<1);
pg.fill(c);
pg.ellipse(centerX, centerY, rad*1.5, rad*1.5);
pg.noStroke();
pg.fill(0);
pg.ellipse(centerX, centerY, rad/5, rad/5);
}
void renderDynamic() {
translate(centerX, centerY);
rotate(mouseX*TWO_PI/width*vel);
noSmooth();
fill(0250);
drawDents();
smooth(2);
fill(0);
drawHoles();
resetMatrix();
}
protected void drawDents() {
int toothRad = toothWidth>>1, toothQuarter = toothRad>>1;
float toothAdjust = toothWidth*-.7;
for (int i = 0; i++ != teeth; rotate(toothAngle)) {
triangle(toothAdjust, toothHY
, toothRad, toothHY
, -toothRad, -lineY);
triangle(toothQuarter, -lineY
, -toothRad, -lineY
, toothRad, toothHY);
if (online) drawGapFill(toothRad);
}
}
protected void drawGapFill(int rad) {
stroke(0250);
line(-rad, -lineY, rad, toothHY);
noStroke();
}
protected void drawHoles() {
int d = rad>>4;
rect(0, -rad/10, rad/20, d);
float y = .85*rad;
for (int i = 0; i++ != 3; rotate(PI/20.0)) ellipse(0, y, d, d);
}
String toString() {
return "Dents: #" + teeth + " \tDiam: " + (rad<<1)
+ " \tSpeed: " + vel;
}
}