Circle


A circle is magical when 3D modeling. If you know what a circle can be composed of, you'll get many brilliant inspirations. So, what is a circle?

$fn

According to Circle from Wikipedia, a circle is the set of all points in a plane that are at a given distance from the center.

These points are infinite, so it's impossible to draw a perfect circle. You can just make a circle almost perfect. What does it mean? When invoking the circle module of OpenSCAD, you can specify a $fn parameter. The code and figures shown below demonstrate what effects of $fn is.

radius = 100;
circle(radius, $fn = 24);
translate([radius * 2, 0, 0]) circle(radius, $fn = 12);
translate([radius * 4, 0, 0]) circle(radius, $fn = 6);

Circle

One way to draw a circle is moving forward a little, rotating a particular degree, and repeating these two steps several times. That is making a regular polygon. However, if $fn is small, such as 12 or less, it surely looks like a regular polygon. Nevertheless, if $fn is 24 or more, the regular polygon is more like a circle. The bigger $fn, the closer to a perfect circle. For human vision, $fn = 96 is basically enough to look like a circle.

Drawing a circle

Could we draw a circle without using the built-in circle module? Yes. Similarly, you have to specify how many sides the circle has.

radius = 50;
fn = 96;
thickness = 2;

module circle_ring(radius, fn, thickness) {
    PI = 3.14159;
    circumference = 2 * PI * radius;
    length = circumference / fn;
    angle_step = 360 / fn;
    for(i = [0 :  angle_step : 360 - angle_step]) {
        rotate(i)
            translate([0, radius, 0]) 
                square([length, thickness], center = true);
    }
}

circle_ring(radius, fn, thickness);

Circle

The code demonstrates a way to draw a circle. It leverages the square module to draw several thin squares which look like lines. However, if you room out the circle, you will see small gaps between lines.

The polygon module

You may leverage the polygon module to build a circle. It accepts a list of [x, y] coordinates to create a multi-sided shape.

radius = 50;

module my_circle(radius, fn) {
    PI = 3.14159;
    circumference = 2 * PI * radius;
    length = circumference / fn;
    angle_step = 360 / fn;
    polygon(
        [
            for(i = [0 :  angle_step : 360 - angle_step])  
                [radius * cos(i), radius * sin(i)]
        ]
    );
}

my_circle(radius, 24);
translate([radius * 2, 0, 0]) my_circle(radius, 12);
translate([radius * 4, 0, 0]) my_circle(radius, 6);

The code creates the same models as shown in the first figure. You can see a code fragment in it.

[
    for(i = [0 :  angle_step : 360]) 
        [radius * cos(i), radius * sin(i)]
]

The syntax is List Comprehension which is common in Functional programming. It looks kind of a loop. Every time [radius * cos(i), radius * sin(i)] is evaluated, you get a [x, y]. All [x, y] are collected so when the list comprehension finishes, you get [[50, 0], [25, 43.3013], [-25, 43.3013], [-50, 0], [-25, -43.3013], [25, -43.3013], [50, 0]]. The list is passed into the polygon module. It takes a point sequentially and draws a multiple sided shape.

Why do we use [radius * cos(i), radius * sin(i)]? It's just a simple calculation of trigonometric functions.

Circle

Using triangles

A circle ring may be composed of lines. How about a solid circle? As shown above, one way is using the polygon module. Can any other shape form a circle? Well, we can use triangles.

Circle

Now that, we can use the following code to draw a circle.

radius = 50;

module my_circle(radius, fn) {
    PI = 3.14159;
    circumference = 2 * PI * radius;
    length = circumference / fn;
    angle_step = 360 / fn;
    for(i = [0 : angle_step : 360 - angle_step]) {
        rotate(i) 
            polygon([
                [0, 0],
                [radius, 0],
                [radius * cos(angle_step), radius * sin(angle_step)],
            ]);
    }
}

my_circle(radius, 24);
translate([radius * 2, 0, 0]) my_circle(radius, 12);
translate([radius * 4, 0, 0]) my_circle(radius, 6);

$fa and $fs

Once you know triangles build a circle, you'll understand that a circle can be viewed from different perspectives.

For example, a circle needs many triangles if the vertex angle of the triangle is small. You can use $fa to control the vertex angle when invoking the circle module. Even more, if the base of the triangle is small, the circle needs many triangles. The length of the base is controlled by $fs.

Circle

In most situations, we'll use $fn. You can, however, take $fa or $fs into consideration when controlling faces precisely is necessary. For more information about this, take a look at OpenScad circle calculations.