I wrote this code a while ago. It works with any angle by dynamically adding
the necessary (small) number of subtracting triangles.
module circular_sector(r, theta) {
overlap = 10;
dtheta = 360 - theta;
n = ceil(dtheta/90);
a = (dtheta+overlap*(n-1))/n;
difference() {
circle(r);
for (i=[0:1:n-1]) rotate([0,0,theta+i*(a-overlap)])
polygon([[0,0],[2r,0],[2rcos(a),2r*sin(a)]]);
}
}
--
Sent from: http://forum.openscad.org/
While we're tossing around implementations...
I honestly don't know whether I originally wrote this, or if I picked it
up somewhere and modified it. I don't find any Google hits on any of
the comments, so maybe I wrote it.
It's longer than the other answers suggested, but part of that is a
couple of general-purpose functions.
It's only two objects (a circle and a quadrilateral) and one boolean
(either intersection or difference).
// polar to rectangular (default: map-style, a=0 north, a=90 east)
// p2r([rho, theta]) = [ x, y ]
// axis is the angle of the axis, math-style (axis=0 east)
// clockwise tells orientation of angle: true is, well, clockwise (map-style)
// while false is counter-clockwise (math-style)
function p2r(p, axis=90, clockwise=true) =
let (r = p[0])
let (a = (clockwise ? -p[1] : p[1]) + axis)
[ r * cos(a), r * sin(a) ];
// positive modulus: all results are positive
function posmod(a, b) = a - (floor(a/b)*b);
// A quadrilateral that encloses an arc of the specified radius and angle, for angle
// less or equal to 180.
// The theoretical minimum is rsqrt(2), but since larger doesn't hurt why not avoid
// the sqrt and any possibility of zero-thickness surfaces?
// Set $_arcpoly_show to display the polygon.
module _arcpoly(r, a) {
r2 = r2;
poly = [ [0,0], p2r([r2, a/2], axis=0, clockwise=false), [r2, 0], p2r([r2, -a/2], axis=0, clockwise=false) ];
if ($_arcpoly_show) #polygon(poly);
else polygon(poly);
}
// A sector of a circle, of the specified radius and angle.
// Centered around the X axis.
module sector(r, a) {
norma = posmod(a, 360);
if (norma <= 180) {
intersection() {
circle(r);
_arcpoly(r, norma);
}
} else {
difference() {
circle(r);
mirror([1, 0, 0]) _arcpoly(r, 360-norma);
}
}
}