Code: Select all
float innerRadius = 1;
float outerRadius = 1.2;
int numTeeth = 21;
float innerFraction = 0.7;
float outerFraction = 0.3;
body[] bs = getSelectedBodies();
for (uint bi = 0; bi < bs.length; bi++) {
body b = bs[bi];
// central circle fixture
b.addFixture(-1, '{"density":1,"shapes":[{"radius":'+innerRadius+',"type":"circle"}],"friction":0.2,"vertices":{"x":[0],"y":[0]}}');
float PI = 3.14159265359;
float oneToothAngle = 2*PI / numTeeth;
vec2[] vs;
vs.insertLast( mv(innerRadius, 0).rotatedBy( oneToothAngle * 0.5 * (1-innerFraction)) );
vs.insertLast( mv(outerRadius, 0).rotatedBy( oneToothAngle * 0.5 * (1-outerFraction)) );
vs.insertLast( mv(outerRadius, 0).rotatedBy( oneToothAngle * (1 - (0.5 * (1-outerFraction)))) );
vs.insertLast( mv(innerRadius, 0).rotatedBy( oneToothAngle * (1 - (0.5 * (1-innerFraction)))) );
for (int i = 0; i < numTeeth; i++) {
// make circle at first
fixture f = b.addFixture(-1, '{"density":1,"shapes":[{"radius":1,"type":"circle"}],"friction":0.2,"vertices":{"x":[0],"y":[0]}}');
// replace vertices
f.setVertices( vs );
// change to polygon
f.getShape(0).setType( 1 );
// set radius to zero
f.getShape(0).setRadius( 0 );
// rotate vertices for next tooth
for (uint k = 0; k < vs.length; k++)
vs[k] = vs[k].rotatedBy( oneToothAngle );
}
}
To create gears that will actually function (mesh with each other without getting stuck), generally outerFraction will be around (1-innerFraction), and innerFraction will be somewhere around 0.6 to 0.8 If you want teeth with only a single vertex at their tip, you will find that this script does not quite work (setting outerFraction to zero causes the two outer vertices to be in the same place, and the polygon decomposition will fail resulting in a line shape instead of a polygon). To get around this, you can comment out either the second or third line of the "vs.insertLast" section of the script to make the teeth from triangles instead of four-sided polygons (as shown on line 29 here): Finally, please note that gears created like this will only function when the speed and forces they are subjected to is very low. Strong forces and high speeds will easily cause the teeth to skip over each other. If you need a gear that can be relied on to never slip, you should use a b2GearJoint which enforces gear constraints in the physics engine itself.
Another thing to keep in mind is that the gear teeth fixtures can become quite small. In the examples above, the inner circle of the gear is radius 1 and the teeth fixtures are around 0.1 in size. This is about as small as you would want to let them get.