Create gear wheel 'cogs'

Let us know if you have a nice R.U.B.E script to share!
Post Reply
iforce2d
Site Admin
Posts: 860
Joined: Sat Dec 22, 2012 7:20 pm

Create gear wheel 'cogs'

Post by iforce2d » Wed May 27, 2015 6:40 am

The script below creates a circle fixture with multiple polygon fixtures around the outside, which can be useful for creating gear wheel shapes. It will add those fixtures to each selected body. You can adjust the variables at the beginning of the script to tweak the shape of the gears.

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 );
	}
}
Here are some examples:
Selection_012.png
Selection_012.png (130.69 KiB) Viewed 29099 times
innerFraction is the width of the base of each tooth, as a fraction of the angle of the tooth, eg. innerFraction = 1 will cause the tooth to completely cover the edge of the inner circle fixture. outerFraction is the width of the tip of each tooth, similarly as a fraction of the angle of the tooth.

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
Selection_018.png
Selection_018.png (53.83 KiB) Viewed 29099 times
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):
Selection_023.png
Selection_023.png (47.45 KiB) Viewed 29099 times
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.

Post Reply