2021-08-22 15:21:57 +08:00
|
|
|
use <shear.scad>;
|
|
|
|
use <multi_line_text.scad>;
|
|
|
|
|
2021-08-22 17:45:54 +08:00
|
|
|
text = "順暢";
|
2021-08-22 15:21:57 +08:00
|
|
|
font = "思源黑體 Heavy";
|
|
|
|
font_size = 14;
|
|
|
|
smoothing = false; // warning: previewing is slow if it's true.
|
|
|
|
|
2021-08-22 15:33:02 +08:00
|
|
|
scale(smoothing ? 0.985 : 1)
|
2021-08-23 08:44:51 +08:00
|
|
|
daruma();
|
2021-08-22 15:33:02 +08:00
|
|
|
|
2021-08-22 20:32:47 +08:00
|
|
|
wish_decoration(text, font, font_size);
|
2021-08-22 15:21:57 +08:00
|
|
|
|
2021-08-23 08:44:51 +08:00
|
|
|
module daruma() {
|
2021-08-22 15:21:57 +08:00
|
|
|
radius = 10;
|
|
|
|
|
|
|
|
module body() {
|
|
|
|
translate([0, 0, radius * 2.75])
|
|
|
|
shear(sy = [.025, 0])
|
|
|
|
minkowski() {
|
|
|
|
linear_extrude(radius * 2, scale = 0.4)
|
|
|
|
translate([0, -radius / 4])
|
|
|
|
circle(radius);
|
|
|
|
|
|
|
|
sphere(radius * 4, $fn = 48);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
module mask_face() {
|
|
|
|
module bend_extrude(size, thickness, angle, frags = 24) {
|
|
|
|
x = size[0];
|
|
|
|
y = size[1];
|
|
|
|
frag_width = x / frags ;
|
|
|
|
frag_angle = angle / frags;
|
|
|
|
half_frag_width = 0.5 * frag_width;
|
|
|
|
half_frag_angle = 0.5 * frag_angle;
|
|
|
|
r = half_frag_width / sin(half_frag_angle);
|
|
|
|
s = (r - thickness) / r;
|
|
|
|
|
|
|
|
module get_frag(i) {
|
|
|
|
offsetX = i * frag_width;
|
|
|
|
translate([0, y / 2, 0])
|
|
|
|
linear_extrude(thickness, scale = s)
|
|
|
|
translate([-offsetX - half_frag_width, -y / 2, 0])
|
|
|
|
intersection() {
|
|
|
|
translate([x, 0, 0])
|
|
|
|
mirror([1, 0, 0])
|
|
|
|
children();
|
|
|
|
translate([offsetX, 0, 0])
|
|
|
|
square([frag_width, y]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
offsetY = -r * cos(half_frag_angle) ;
|
|
|
|
|
|
|
|
rotate(angle - 90)
|
|
|
|
mirror([0, 1, 0])
|
|
|
|
mirror([0, 0, 1])
|
|
|
|
for(i = [0 : frags - 1]) {
|
|
|
|
rotate(i * frag_angle + half_frag_angle)
|
|
|
|
translate([0, offsetY, 0])
|
|
|
|
rotate([-90, 0, 0])
|
|
|
|
get_frag(i)
|
|
|
|
children();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
translate([0, -radius, radius * 1.4])
|
|
|
|
scale([1.27, 1, 1])
|
|
|
|
rotate([-24, 0, 0])
|
|
|
|
rotate(225)
|
|
|
|
bend_extrude(size = [radius * 16, radius * 8], thickness = radius, angle = 180, frags = 36)
|
|
|
|
translate([radius * 4, radius * 2.5])
|
|
|
|
hull() {
|
|
|
|
$fn = 12;
|
|
|
|
translate([0, radius * 1.75])
|
|
|
|
circle(radius * 1.2);
|
|
|
|
|
|
|
|
translate([radius * 1.45, radius * 1.5])
|
|
|
|
circle(radius * 1.25, $fn = 24);
|
|
|
|
|
|
|
|
translate([-radius * 1.45, radius * 1.5])
|
|
|
|
circle(radius * 1.25, $fn = 24);
|
|
|
|
|
|
|
|
translate([radius * 1.85, radius * 0.25])
|
|
|
|
rotate(25)
|
|
|
|
scale([1, 1.3])
|
|
|
|
circle(radius * 1.3);
|
|
|
|
|
|
|
|
translate([-radius * 1.85, radius * 0.25])
|
|
|
|
rotate(-25)
|
|
|
|
scale([1, 1.3])
|
|
|
|
circle(radius * 1.3);
|
|
|
|
|
|
|
|
translate([radius * 2.75, -radius * 1.2])
|
|
|
|
circle(radius / 2);
|
|
|
|
|
|
|
|
translate([-radius * 2.75, -radius * 1.2])
|
|
|
|
circle(radius / 2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
module eyes_nose() {
|
|
|
|
module eye() {
|
|
|
|
translate([radius * 1.4, -3.1 * radius, radius * 5.9])
|
|
|
|
rotate([66, 0, 15])
|
|
|
|
linear_extrude(radius / 4, scale = 0.9)
|
|
|
|
circle(radius * 1.15);
|
|
|
|
}
|
|
|
|
|
|
|
|
eye();
|
|
|
|
|
|
|
|
mirror([1, 0, 0])
|
|
|
|
eye();
|
|
|
|
|
|
|
|
// nose
|
|
|
|
translate([0, -3.75 * radius, radius * 4.85])
|
|
|
|
rotate([67.5, 0, 0])
|
|
|
|
linear_extrude(radius / 4, scale = 0.9)
|
|
|
|
circle(radius * 0.4);
|
|
|
|
}
|
2021-08-22 16:04:06 +08:00
|
|
|
|
|
|
|
if(smoothing) {
|
|
|
|
minkowski() {
|
|
|
|
union() {
|
2021-08-22 15:21:57 +08:00
|
|
|
difference() {
|
|
|
|
body();
|
|
|
|
mask_face();
|
|
|
|
}
|
|
|
|
eyes_nose();
|
|
|
|
}
|
2021-08-22 16:04:06 +08:00
|
|
|
sphere(radius / 9.5, $fn = 8);
|
2021-08-22 15:21:57 +08:00
|
|
|
}
|
2021-08-22 16:04:06 +08:00
|
|
|
} else {
|
|
|
|
difference() {
|
|
|
|
body();
|
|
|
|
mask_face();
|
|
|
|
}
|
|
|
|
eyes_nose();
|
2021-08-22 15:21:57 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-08-22 20:32:47 +08:00
|
|
|
module wish_decoration(text, font, font_size) {
|
2021-08-22 15:21:57 +08:00
|
|
|
$fn = 48;
|
|
|
|
|
|
|
|
translate([0, -2, 0])
|
|
|
|
intersection() {
|
|
|
|
union() {
|
|
|
|
wish();
|
|
|
|
|
|
|
|
decoration();
|
|
|
|
mirror([1, 0, 0])
|
|
|
|
decoration();
|
|
|
|
}
|
|
|
|
|
|
|
|
translate([0, 0, 30])
|
|
|
|
sphere(52);
|
|
|
|
}
|
|
|
|
|
|
|
|
module wish() {
|
|
|
|
translate([0, -43, 29])
|
|
|
|
rotate([85, 0, 0])
|
|
|
|
linear_extrude(10)
|
|
|
|
text(
|
|
|
|
text[0],
|
|
|
|
font = font,
|
|
|
|
size = font_size,
|
|
|
|
valign = "center",
|
|
|
|
halign = "center"
|
|
|
|
);
|
|
|
|
|
|
|
|
translate([0, -42.5, 10])
|
|
|
|
rotate([105, 0, 0])
|
|
|
|
linear_extrude(10)
|
|
|
|
text(
|
|
|
|
text[1],
|
|
|
|
font = font,
|
|
|
|
size = font_size,
|
|
|
|
valign = "center",
|
|
|
|
halign = "center"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
module decoration() {
|
|
|
|
translate([18, -38, 20])
|
|
|
|
rotate([100, 0, 0])
|
|
|
|
linear_extrude(10)
|
|
|
|
scale(.85)
|
|
|
|
scale([1, 1.75])
|
|
|
|
offset(.5)
|
|
|
|
difference() {
|
|
|
|
circle(10);
|
|
|
|
translate([-9, 0])
|
|
|
|
circle(11.5);
|
|
|
|
}
|
|
|
|
|
|
|
|
translate([28, -30, 20])
|
|
|
|
rotate([100, 0, 30])
|
|
|
|
linear_extrude(10)
|
|
|
|
scale(.7)
|
|
|
|
scale([1, 1.75])
|
|
|
|
offset(.5)
|
|
|
|
difference() {
|
|
|
|
circle(10);
|
|
|
|
translate([-9, 0])
|
|
|
|
circle(11.5);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|