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 = [
for(a = [angles[0]:1:angles[1]]) [radius * cos(a), radius * sin(a)]
];
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[0] : step : angles[1] - 360])
[radius * cos(a), radius * sin(a)]
],
[[radius * cos(angles[1]), radius * sin(angles[1])]]
);
difference() {
circle(radius, $fn = fn);
#polygon(points);
}
}
sector(radius, angles, fn);
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;
r = radius / cos(a);
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[0] : step : angles[1] - 360])
[r * cos(a), r * sin(a)]
],
[[r * cos(angles[1]), r * sin(angles[1])]]
);
difference() {
circle(radius, $fn = fn);
polygon(points);
}
}
sector(radius, angles, fn);
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[0] : step : angles[1] - 360])
[r * cos(a), r * sin(a)]
],
[[r * cos(angles[1]), r * sin(angles[1])]]
);
difference() {
circle(radius, $fn = fn);
polygon(points);
}
}
module arc(radius, angles, width = 1, fn = 24) {
difference() {
sector(radius + width, angles, fn);
sector(radius, angles, fn);
}
}
linear_extrude(1) arc(radius, angles, width);
We obtain an arc.
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.
Writing documents always gives me opportunities to think more about those things. Are there other considerations? Are there better designs?
Writing is not only about writing.