OpenSCAD User Manual/undersized circular objects

Using cylinder with difference to place holes in objects results in undersized holes. This is because circular paths are approximated with polygons inscribed within in a circle. The points of the polygon are on the circle, but straight lines between are inside. This is discussed in some detail at http://hydraraptor.blogspot.com.au/2011/02/polyholes.html

While the standard cylinder and circle generate inner (inscribed) polygons, here are modules to produce outer (circumscribed) and mid ( 1/2 way between) polygons.

cylinder
module cylinder_outer(height,radius,fn){ fudge = 1/cos(180/fn); cylinder(h=height,r=radius*fudge,$fn=fn);}

module cylinder_mid(height,radius,fn){ fudge = (1+1/cos(180/fn))/2; cylinder(h=height,r=radius*fudge,$fn=fn);} //example script to show differences cylinder_outer(5,100,6); %cylinder_mid(5.5,100,6); cylinder(6,r=100,$fn=6);       // standard #cylinder(5.75,r=100,$fn=60);  // reference

//CSG tree for this example group { group { cylinder($fn = 6, $fa = 12, $fs = 2, h = 5, r1 = 115.47, r2 = 115.47, center = false); } % group { cylinder($fn = 6, $fa = 12, $fs = 2, h = 5.5, r1 = 107.735, r2 = 107.735, center = false); }   cylinder($fn = 6, $fa = 12, $fs = 2, h = 6, r1 = 100, r2 = 100, center = false); # cylinder($fn = 60, $fa = 12, $fs = 2, h = 5.75, r1 = 100, r2 = 100, center = false); }

cone
For cylinders with different top and bottom radii

module cone_outer(height,radius1,radius2,fn){ fudge = 1/cos(180/fn); cylinder(h=height,r1=radius1*fudge,r2=radius2*fudge,$fn=fn);}

module cone_mid(height,radius1,radius2,fn){ fudge = (1+1/cos(180/fn))/2; cylinder(h=height,r1=radius1*fudge,r2=radius2*fudge,$fn=fn);}

cone_outer(5 ,10 ,5 ,6); cone_mid(5 ,10 ,5 ,6);

circle
And lastly not to forget the 2D world module circle_outer(radius,fn){ fudge = 1/cos(180/fn); circle(r=radius*fudge,$fn=fn);}

module circle_mid(radius,fn){ fudge = (1+1/cos(180/fn))/2; circle(r=radius*fudge,$fn=fn);}

circle_outer(20,6); circle_mid(20,6);