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)&&(mouseY y-10)&&(my x+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)); } }