Text and sphere


You've known how to design Character tower generator. Would you like to challenge Text Sphere?

Text Sphere

It's hard to print; however, some people still printed it beautifully. I used supports while printing and the make seem acceptable.

π Sphere

Getting started basics

Wrapping text around a sphere requires more mathematics. Let's get started from basics. First, you have to rotate a list of cubes around the z-axis from 0 to 180 degrees.

radius = 40;
step_angle = 10;
length = 5;
for(a = [0:step_angle:180]) {
    rotate([0, 0, a]) translate([radius, 0, 0]) 
        cube([length, length, length], center = true);
}

It's a very simple program. We create the model below.

Text and sphere

If the cubes rotate not only around the z-axis but also the y-axis, what will it be? For example, rotate -45 degrees around the y-axis at the same time.

radius = 40;
step_angle = 10;
length = 5;
for(a = [0:step_angle:180]) {
    rotate([0, -45, a]) translate([radius, 0, 0]) 
        cube([length, length, length], center = true);
}
%sphere(radius);

The arc now appears at the place where the vector is 45 degrees to the x-y plane. I add a transparent sphere to highlight this situation.

Text and sphere

You can try numbers other than 45, such as 30 or 60, to move the arc to the place where the vector is 30 or 60 degrees to the x-y plane respectively.

When rotating around the y-axis, if you increase angle from -90 to 90 degrees, the cubes will be wrapped around the sphere.

radius = 40;
radius = 40;
step_angle = 10;
length = 5;
for(a = [0:step_angle:180]) {
    rotate([0, -90 + a, a]) translate([radius, 0, 0]) 
        cube([length, length, length], center = true);
}
%sphere(radius);

Text and sphere

If the step_angle parameter has a smaller value, what will happen?

radius = 40;
step_angle = 0.25;
length = 5;
for(a = [0:step_angle:180]) {
    rotate([0, -90 + a, a]) translate([radius, 0, 0]) 
        cube([length, length, length], center = true);
}
%sphere(radius);

We have a spiral.

Text and sphere

Try to repeat the spiral eight times and rotate them around the z-axis 45, 90, 135, 180 and so on. You'll know how to create the spirals of Spinning picture ornament.

Text and sphere

As mentioned in 3D line, we have an elegant way to create these spirals. If you forget, review the document again.

Wrapping text around a sphere

Now it's time to replace cubes by characters. The font size is set to 10 temporarily. Let's see how it looks.

radius = 40;
step_angle = 10;
font_size = 10;
thickness = 1;

for(a = [0:step_angle:180]) {
    rotate([0, -90 + a, a]) translate([radius, 0, 0]) 
        rotate([90, 0, 90]) 
            linear_extrude(thickness) 
                 text("A", size = font_size, valign = "center", halign = "center");
}
%sphere(radius);

Wow, we have characters around a sphere.

Text and sphere

But, it seems still different from Text sphere. One reason is that the characters drop too quickly. The other reason is that the characters only rotate 180 degrees around the z-axis. The characters of Text sphere turns many circles around the z-axis.

We can't only decrease the step_angle value because it only slows down the speed around the y-axis and the total degrees the characters rotate around the z-axis is still 180.

If the whole degrees around the z-axis remain 180 first and the degrees around the y-axis are from -90 to 90, what will it be?

Text and sphere

Umm, the characters stop on the x-y plane. That's because we only rotate 180 degrees around the z-axis. If we want to stop at the bottom of the sphere, we just have to increase 180 to 360 degrees. If we only increase 45, that's 180 / 4, from -90 degrees around the y-axis, we have to rotate 180 * 4 degrees around the z-axis to make the characters stop at the bottom of the sphere. You might have noticed that there's an inversely proportional relationship here so that we can write down the code below.

radius = 40;
step_angle = 10;
font_size = 10;
thickness = 1;

total_semi_circles = 15;

for(a = [0:step_angle:180 * total_semi_circles]) {
    rotate([0, -90 + a / total_semi_circles, a]) translate([radius, 0, 0]) 
        rotate([90, 0, 90]) 
            linear_extrude(thickness) 
                text("A", size = font_size, valign = "center", halign = "center");
}
%sphere(radius);

Ya! A sphere wrapped by characters is out.

Text and sphere

You can change the total_semi_circles value. The bigger it is, the more intensive characters are. Text sphere has an open rim. We can adjust the initial value of a to decide its radius.

radius = 40;
step_angle = 10;
font_size = 10;
thickness = 1;

total_semi_circles = 15;
open_begin = 500;

for(a = [open_begin:step_angle:180 * total_semi_circles]) {
    rotate([0, -90 + a / total_semi_circles, a]) translate([radius, 0, 0]) 
        rotate([90, 0, 90]) 
            linear_extrude(thickness) 
                text("A", size = font_size, valign = "center", halign = "center");
}
%sphere(radius);

The result is as below.

Text and sphere

You may choose suitable parameters until the characters have acceptable intensity. Then, you'll have your text sphere.

Advanced control

I can close this case here, and that's what I did for my work on Thingiverse. But, how to choose suitable parameters? Hmm, just try and error until the model looks good.

A good look here means that the characters don't overlap and the height between the upper layer and the lower layer is the size of a character. Moreover, we have an acceptable radius of the open rim. Isn't there a way to calculate these values automatically? In fact, there's a way to do that, but I was just too lazy to go further at that time :p

Let's try to realize the first requirement. We hope that the characters don't overlap. First, we should decide that how many characters a circle has and what the angle of the rim is. After that, we can calculate the circumference of the rim.

Text and sphere

Suppose angle has the relationship.

angle = 180 * open_begin_ratio;

The circumference of the rim is 2 * PI * (radius * sin(angle)). If each circle has chars_per_circle characters, the font_size has the relationship.

font_size = 2 * PI * radius * sin(angle) / chars_per_circle;

The angle between two characters is:

step_angle = 360 / chars_per_circle;

Now we have to decide the first value of a. Still remember the figure below?

Text and sphere

Suppose we want to start from 45 degrees. That is, we want -90 + a / total_semi_circles = -45, so a / total_semi_circles = 45. If we use angle to replace the value 45, we have a / total_semi_circles = angle, so a = angle * total_semi_circles. The first value of a is …

begin_angle = angle * total_semi_circles;

How about the total_semi_circles? After rotating a circle, the character of the upper layer should be on the top of the character of the lower layer. So, the total layers are 2 * PI * radius / font_size.

total_semi_circles = 2 * PI * radius / font_size;

Based on the above, we can rewrite the code below.

radius = 40;
thickness = 1;
chars_per_circle = 20;
open_begin_ratio = 0.25;

angle = 180 * open_begin_ratio;
font_size = 2 * PI * radius * sin(angle) / chars_per_circle;
step_angle = 360 / chars_per_circle;
total_semi_circles = 2 * PI * radius / font_size;
begin_angle = angle * total_semi_circles;

for(a = [begin_angle:step_angle:180 * total_semi_circles]) {
    rotate([0, -90 + a / total_semi_circles, a]) translate([radius, 0, 0]) 
        rotate([90, 0, 90]) 
            linear_extrude(thickness) 
                text("A", size = font_size, valign = "center", halign = "center");
}
%sphere(radius);

Finally, we have the text sphere.

Text and sphere

Now that, you just have to decide the values of radius, thickness, chars_per_circle and open_begin_ratio. Other required values will be calculated automatically. It's friendly for normal users.

Of course, mathematics is the challenge; however, it's also the joy of modeling. You have to observe, think, look for the relationship and solve them respectively. Not only mathematics needs this process but also modeling needs this process, so does programming. What you are playing all need this process.

If this process happens, you design will carry an in-depth meaning. The design will have a soul!