# Circular sector and arc

Heart chain with text is one of my hot things. (I also designed Text heart chain which can coil up hearts.)

There are two small rings between hearts. The rings don't overlap so you can print it in place. Before creating these hearts, what should you prepare for such a simple ring? Different people have different thoughts. As for me, it's better to define a module which can draw an arc according to given angles.

# Sector

Before defining an `arc` module, it's better to have a module which can draw a sector. If the built-in `circle` module can provide an `angles` parameter, implementing this requirement will be easy. Unfortunately, OpenSCAD doesn't provide it, so it's time to do it yourself.

In Circle, we learned about that you can use triangles to construct a circle. Seriously speaking, this creates a regular polygon. When it comes to the polygon, we know that the built-in `polygon` module can create a multi-sided shape. If we can calculate every vertex's coordinate of the sector, the `polygon` module will be able to create a sector, right?

``````radius = 10;
angles = [45, 135];
points = [
];
polygon(concat([[0, 0]], points));
``````

As you see, we are right. We draw a sector from 45 to 135 degrees. I have more to take into consideration. The `sector` module should provide a `\$fn` parameter, maybe `\$fa` and `\$fs` as well, to be consistent with the `circle` module. Then, the users of the `sector` module can use angles to create a sector which looks like being cut from a circle with the given `\$fn`. For example, we can use 0 and 135 degrees to cut a sector from a circle of `\$fn = 12`. Do you see that? Because `\$fn` is 12, the length of the leftmost side is smaller than others. I deliberately use `\$fn = 12` to highlight this condition. You can create a circle and `difference` the unwanted part to obtain the sector. According to the above idea, we may write a rough implementation.

``````radius = 20;
angles = [45, 135];
fn = 12;

module sector(radius, angles, fn = 24) {
step = -360 / fn;

points = concat([[0, 0]],
[for(a = [angles : step : angles - 360])
],
);

difference() {
#polygon(points);
}
}

``````

But, the result is not what we want. Oh, no! The differenced part is not large enough to cover the edge of the circle. You can create a larger polygon to solve this problem, however, how large should it be? Twice the radius of the circle is surely enough. If you want to have fun with precision, let's do some calculations.

The figure below shows the worst case. One leg of the yellow triangle intersects the base of the red triangle at the middle. So, the polygon can cover the yellow circle if the radius of the red circle is `r` derived below.

``````a = 180 / fn;
``````

The modified version of the `sector` module is here.

``````radius = 20;
angles = [45, 135];
fn = 24;

module sector(radius, angles, fn = 24) {
r = radius / cos(180 / fn);
step = -360 / fn;

points = concat([[0, 0]],
[for(a = [angles : step : angles - 360])
[r * cos(a), r * sin(a)]
],
[[r * cos(angles), r * sin(angles)]]
);

difference() {
polygon(points);
}
}

``````

We get a sector now. # Arc

Once the `sector` module is ready, defining an `arc` module is easy. Just difference a smaller sector from a bigger sector.

``````radius = 20;
angles = [45, 290];
width = 2;
fn = 24;

module sector(radius, angles, fn = 24) {
r = radius / cos(180 / fn);
step = -360 / fn;

points = concat([[0, 0]],
[for(a = [angles : step : angles - 360])
[r * cos(a), r * sin(a)]
],
[[r * cos(angles), r * sin(angles)]]
);

difference() {
polygon(points);
}
}

module arc(radius, angles, width = 1, fn = 24) {
difference() {
}
} Some of my things on Thingiverse needed sectors and arcs. The implementations of `sector` and `arc` in them are different from here. That is because they are my early works, some considerations were still immature when designing them.