discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

Re: [OpenSCAD] Creating pie (pizza slice) shape (need a dynamic length array)

D
DarioPellegrini
Sat, Sep 15, 2018 5:18 PM

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/

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],[2*r,0],[2*r*cos(a),2*r*sin(a)]]); } } -- Sent from: http://forum.openscad.org/
JB
Jordan Brown
Mon, Sep 17, 2018 3:32 AM

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 = r
2;
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);
}
}
}

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 r*sqrt(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 = r*2; 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); } } }