A gear simulation, written in Processing. Click the image to see the working version.
See the source-code below.
Source code
PFont f;
Slider s1,s2,s3,s4,s5,s6;
int s1v,s2v,s3v,s4v,s5v,s6v;
int x1=200;
int y1=300;
int x2=200;
int y2=400;
int x3=x2;
int y3=y2;
int x4=200;
int y4=500;
int startx=200;
int starty=20;
float a1=0;
float a2=0;
float a3=0;
float a4=0;
float speed=0.05;// =1/20
float inputSpeed=round(speed*400/11*10.0f)/10.0f;
float outputSpeed;
int n;
int gear1teeth=40;
int gear2teeth=15;
int gear3teeth=40;
int gear4teeth=15;
int gear5teeth=40;
int gear6teeth=15;
int col=150;
float canvasY=100;
int sliderXstart=500;
int switchXstart=450;
boolean cog1on=true;
boolean cog2on=true;
boolean cog3on=true;
boolean cog4on=true;
boolean cog5on=true;
boolean cog6on=true;
float ma1;
float ma2;
float ma3;
float ma4;
float ma5;
float ma6;
int lastCog=6;
float finalma;
String shared="shared";
String driven="driven";
String starter="starter";
Gear gear1,g1;
Gear gear2,g2;
Gear gear3,g3;
Gear gear4,g4;
Gear gear5,g5;
Gear gear6,g6;
int gMin=8;
int gMax=60;
//gMin,gMax
//look at how rotating images were done in DJ Tube
void setup () {
f = createFont("Arial",24,true); // Arial, 16 point, anti-aliasing on
textFont(f,24);
size (750,600,P2D);
// size (400,800);
//rectMode(CENTER);
noFill();
stroke(255);
s1v=(int)(map(gear1teeth,gMin,gMax,0,100));
s2v=(int)(map(gear2teeth,gMin,gMax,0,100));
s3v=(int)(map(gear3teeth,gMin,gMax,0,100));
s4v=(int)(map(gear4teeth,gMin,gMax,0,100));
s5v=(int)(map(gear5teeth,gMin,gMax,0,100));
s6v=(int)(map(gear6teeth,gMin,gMax,0,100));
g1=new Gear(switchXstart,50,8,6,0,null,starter,#33CC66);
g2=new Gear(switchXstart,100,8,6,0,null,starter,#33CC66);
g3=new Gear(switchXstart,150,8,6,0,null,starter,#00CCFF);
g4=new Gear(switchXstart,200,8,6,0,null,starter,#00CCFF);
g5=new Gear(switchXstart,250,8,6,0,null,starter,#3399FF);
g6=new Gear(switchXstart,300,8,6,0,null,starter,#3399FF);
setup2();
}
void setup2(){
int gx=startx;
int gy=starty;
outSpeed();
s1=new Slider(sliderXstart,50,200,5,#33CC66);
s1.sliderSet(s1v);
gear1=new Gear(gx,gy,gear1teeth,10,ma1,null,starter,#33CC66);
s2=new Slider(sliderXstart,100,200,5,#33CC66);
s2.sliderSet(s2v);
gear2=new Gear(gx,gy,gear2teeth,10,ma2,gear1,driven,#33CC66);
s3=new Slider(sliderXstart,150,200,5,#00CCFF);
s3.sliderSet(s3v);
gear3=new Gear(gx,gy,gear3teeth,10,ma3,gear2,shared,#00CCFF);
s4=new Slider(sliderXstart,200,200,5,#00CCFF);
s4.sliderSet(s4v);
gear4=new Gear(gx,gy,gear4teeth,10,ma4,gear3,driven,#00CCFF);
s5=new Slider(sliderXstart,250,200,5,#3399FF);
s5.sliderSet(s5v);
gear5=new Gear(gx,gy,gear5teeth,10,ma5,gear4,shared,#3399FF);
s6=new Slider(sliderXstart,300,200,5,#3399FF);
s6.sliderSet(s6v);
gear6=new Gear(gx,gy,gear6teeth,10,ma6,gear5,driven,#3399FF);
}
void outSpeed(){
if (!cog1on){ma1=0; finalma=ma1;cog2on=cog3on=cog4on=cog5on=cog6on=false;}else{
ma1=1;
if(!cog2on){ma2=0; finalma=ma1;cog3on=cog4on=cog5on=cog6on=false;}else{
ma2=-gear1teeth/gear2teeth;
if(!cog3on){ma3=0; finalma=ma2;cog4on=cog5on=cog6on=false;}else{
ma3=ma2;
if(!cog4on){ma4=0; finalma=ma3;cog5on=cog6on=false;}else{
ma4=-gear3teeth/gear4teeth*ma2;
if(!cog5on){ma5=0; finalma=ma4;cog6on=false;}else{
ma5=ma4;
if(!cog6on){ma6=0;finalma=ma5;}else{
//ma6=float(-gear5teeth/gear6teeth*ma4);
ma6=(float)(-gear5teeth/gear6teeth*ma4);
finalma=ma6;
}}}}}}
outputSpeed=round(inputSpeed*finalma*10.0f)/10.0f;
}
void draw () {
//scale(height/canvasY);
background (20);
//fill(255);
//noFill();
//gear1
text("Input Speed: "+inputSpeed+" rpm",switchXstart,25);
s1.sliderDraw();
s2.sliderDraw();
s3.sliderDraw();
s4.sliderDraw();
s5.sliderDraw();
s6.sliderDraw();
fill(255);
text("Output Speed: "+abs(outputSpeed)+" rpm",switchXstart,375);
if(cog1on){gear1.gRotate(speed);}
gear1.gDraw(cog1on);
if(cog2on){gear2.gRotate(speed);}
gear2.gDraw(cog2on);
if(cog3on){gear3.gRotate(speed);}
gear3.gDraw(cog3on);
if(cog4on){gear4.gRotate(speed);}
gear4.gDraw(cog4on);
if(cog5on){gear5.gRotate(speed);}
gear5.gDraw(cog5on);
if(cog6on){gear6.gRotate(speed);}
gear6.gDraw(cog6on);
s1.sliderLabel(gear1teeth);
s2.sliderLabel(gear2teeth);
s3.sliderLabel(gear3teeth);
s4.sliderLabel(gear4teeth);
s5.sliderLabel(gear5teeth);
s6.sliderLabel(gear6teeth);
g1.gDraw(cog1on);
g2.gDraw(cog2on);
g3.gDraw(cog3on);
g4.gDraw(cog4on);
g5.gDraw(cog5on);
g6.gDraw(cog6on);
}
void mouseDragged(){
s1v=s1.sliderNow(mouseX,mouseY);
s2v=s2.sliderNow(mouseX,mouseY);
s3v=s3.sliderNow(mouseX,mouseY);
s4v=s4.sliderNow(mouseX,mouseY);
s5v=s5.sliderNow(mouseX,mouseY);
s6v=s6.sliderNow(mouseX,mouseY);
gear1teeth=(int)(map(s1v,0,100,gMin,gMax));
gear2teeth=(int)(map(s2v,0,100,gMin,gMax));
gear3teeth=(int)(map(s3v,0,100,gMin,gMax));
gear4teeth=(int)(map(s4v,0,100,gMin,gMax));
gear5teeth=(int)(map(s5v,0,100,gMin,gMax));
gear6teeth=(int)(map(s6v,0,100,gMin,gMax));
}
void mouseReleased(){
outSpeed();
if(mouseX>sliderXstart){
setup2();
}
}
void mouseClicked(){
if(g1.gMouse()){
cog1on=!cog1on;
}else if(g2.gMouse()){
cog2on=!cog2on;
}else if(g3.gMouse()){
cog3on=!cog3on;
}else if(g4.gMouse()){
cog4on=!cog4on;
}else if(g5.gMouse()){
cog5on=!cog5on;
}else if(g6.gMouse()){
cog6on=!cog6on;
}
}
void mouseMoved(){
}
class Gear {
float x;
float y;
float a;
float size;
int teeth;
float ma;
Gear driver;
String type;
PShape cog;
int col;
int pitch;
Gear(int xpos, int ypos, int numteeth, int pitch_, float mechadv, Gear drive, String t, int col_){
x=xpos;
y=ypos;
teeth=numteeth;
a=0;
ma=mechadv;
size=teeth/PI*15;
type=t;
col=col_;
pitch=pitch_;
// y+=size/2;
driver=drive;
if (driver==null){y=y+this.gRadius();}
else if (type==shared){y=driver.y;}
else if (type==driven){y=driver.y+driver.gRadius()+this.gRadius();}
n++;
canvasY=y+this.gRadius();
// println("gear "+n+" y position= "+y+" ma= "+mechadv);
gBuild();
}
void gBuild(){/*
float p;
float a2=0;
//smooth();
cog = createShape();
//cog=new PShape();
//cog.noFill();
cog.fill(col,100);
cog.stroke(col);
//col+=10;
cog.strokeWeight(2);
//float x = 0;
// Calculate the path as a sine wave
float clicks=TWO_PI*100/teeth;
for (float a = 0; a < TWO_PI; a+=0.01) {
a2+=TWO_PI/clicks;
//teeth/1;
//a2+=(2*PI)/(teeth*100);
p=sin(a2)*pitch/2;
cog.vertex(cos(a)*(size/2+p-2),sin(a)*(size/2+p-2));
//x+= 5;
}
cog.endShape(); */
}
void cog(boolean isOn){
float p;
float a;
float a2=0;
beginShape();
//smooth();
if(isOn){
fill(col,100);
stroke(col);
}
else{
fill(255,100);
stroke(100,100);
}
//fill(color(col,100));
//stroke(col);
strokeWeight(2);
float clicks;
clicks=TWO_PI*100/teeth;
for (a = 0; a < TWO_PI; a+=0.01) {
a2+=TWO_PI/clicks;
p=sin(a2)*pitch/2;
vertex(cos(a)*(size/2+p-2),sin(a)*(size/2+p-2));
}
endShape();
}
float gRadius(){
return size/2;
}
void gRotate(float thespeed){
a+=2*(PI/100)*thespeed*ma;
}
void gDraw(boolean on){
pushMatrix();
translate(x,y);
rotate(a);
int iCol;
int aCol;
/* if(on){
cog.setFill(color(col,100));
cog.setStroke(color(col));
}
else{
cog.setFill(color(255,100));
cog.setStroke(color(100,100));
}
*/
//shape(cog);
if(on){
iCol=#FF0000;
aCol=col;
}
else{
iCol=100;
aCol=100;
}
cog(on);
fill(iCol,100);
stroke(iCol);
ellipse(0,0+size/2-10,5,5);
fill(aCol,100);
stroke(aCol);
ellipse(0,0,10,10);
popMatrix();
}
boolean gMouse(){
if((mouseX>x-size/2)&&(mouseXy-size/2)&&(mouseYy-10)&&(myx+len){knobX=x+len;}
}
sliderVal=(int)(map(knobX,x,x+len,0,100));
return sliderVal;
}
void sliderLabel(int teeth){
stroke(col);
fill(col);
textFont(f,24);
text(teeth+" teeth",x+15,y+30);
}
void sliderSet(int val){
knobX=(int)(map(val,0,100,x,x+len));
}
}

