# 你也會碎形

``````\$fn = 48;
width = 1;

module frame(thickness) {
difference() {
children();
offset(r = -thickness) children();
}
}

frame(width) circle(40);
frame(width) circle(20);
frame(width) circle(10);
frame(width) circle(5);
``````

``````radius = 40;
r_limit = 4;
width = 1;

module frame(thickness) {
difference() {
children();
offset(r = -thickness) children();
}
}

\$fn = 48;
}
}

``````

# 運用海龜繪圖

``````// …要用到海龜繪圖的程式碼...自己在〈實作海龜繪圖〉中找吧！

module triangle(t, side_leng, width) {
angle = 120;
t_p1 = forward(t, side_leng);                   // 前進 side_leng
polyline([get_xy(t), get_xy(t_p1)], width);     // 畫線

t_p2 = forward(turn(t_p1, angle), side_leng);   // 轉 angle 並前進 side_leng
polyline([get_xy(t_p1), get_xy(t_p2)], width);  // 畫線

t_p3 = forward(turn(t_p2, angle), side_leng);   // 轉 angle 並前進 side_leng
polyline([get_xy(t_p2), get_xy(t_p3)], width);  // 畫線
}
``````

``````module concentric_triangles(t, side_len, len_limit, width) {
if(side_len >= len_limit) {
triangle(t, side_len, width);
// 前進一半邊長，並轉動 60 度
next_t = turn(forward(t, side_len / 2), 60);
// 進行下一次的同心三角形
concentric_triangles(next_t, side_len / 2, len_limit, width);
}
}

side_len = 50;
len_limit = 4;
width = 1;
t = turtle(0, 0, 0);

concentric_triangles(t, side_len, len_limit, width);
``````

# 開始變化！

``````module triangle(t, side_leng, width) {
angle = 120;
t_p1 = forward(t, side_leng);                   // 前進 side_leng
polyline([get_xy(t), get_xy(t_p1)], width);     // 畫線

t_p2 = forward(turn(t_p1, angle), side_leng);   // 轉 angle 並前進 side_leng
polyline([get_xy(t_p1), get_xy(t_p2)], width);  // 畫線

t_p3 = forward(turn(t_p2, angle), side_leng);   // 轉 angle 並前進 side_leng
polyline([get_xy(t_p2), get_xy(t_p3)], width);  // 畫線
}

module two_triangles(t, side_len, len_limit, width) {
angle = 60;
triangle(t, side_len, width);
// 前進一半邊長，並轉動 60 度
next_t = turn(forward(t, side_len / 2), angle);
// 轉 60 度的小三角
triangle(next_t, side_len / 2, width);
}

module concentric_triangles(t, side_len, len_limit, width) {
if(side_len >= len_limit) {
two_triangles(t, side_len, len_limit, width);

next_t = turn(forward(t, side_len / 2), 60);

concentric_triangles(next_t, side_len / 2, len_limit, width);
}
}

side_len = 50;
len_limit = 4;
width = 1;
t = turtle(0, 0, 0);

concentric_triangles(t, side_len, len_limit, width);
``````

``````module concentric_triangles(t, side_len, len_limit, width) {
if(side_len >= len_limit) {
two_triangles(t, side_len, len_limit, width);

// 左下同心三角形
concentric_triangles(t, side_len / 2, len_limit, width);

next_t = turn(forward(t, side_len / 2), 60);

concentric_triangles(next_t, side_len / 2, len_limit, width);
}
}
``````

``````module concentric_triangles(t, side_len, len_limit, width) {
if(side_len >= len_limit) {
two_triangles(t, side_len, len_limit, width);

// 左下同心三角形
concentric_triangles(t, side_len / 2, len_limit, width);

// 右下同心三角形
concentric_triangles(forward(t, side_len / 2), side_len / 2, len_limit, width);

next_t = turn(forward(t, side_len / 2), 60);

concentric_triangles(next_t, side_len / 2, len_limit, width);
}
}
``````

``````module concentric_triangles(t, side_len, len_limit, width) {
if(side_len >= len_limit) {
two_triangles(t, side_len, len_limit, width);

// 左下同心三角形
concentric_triangles(t, side_len / 2, len_limit, width);

// 右下同心三角形
concentric_triangles(forward(t, side_len / 2), side_len / 2, len_limit, width);

// 最上面的同心三角形
concentric_triangles(turn(forward(turn(t, 60), side_len / 2), -60), side_len / 2, len_limit, width);

next_t = turn(forward(t, side_len / 2), 60);

concentric_triangles(next_t, side_len / 2, len_limit, width);
}
}
``````

``````module concentric_triangles(t, side_len, len_limit, width) {
if(side_len >= len_limit) {
two_triangles(t, side_len, len_limit, width);

// 左下同心三角形
concentric_triangles(t, side_len / 2, len_limit, width);

// 右下同心三角形
concentric_triangles(forward(t, side_len / 2), side_len / 2, len_limit, width);

// 最上面的同心三角形
concentric_triangles(turn(forward(turn(t, 60), side_len / 2), -60), side_len / 2, len_limit, width);

// 正中的同心三角形
// next_t = turn(forward(t, side_len / 2), 60);
// concentric_triangles(next_t, side_len / 2, len_limit, width);
}
}
``````

``````function turtle(x, y, angle) = [[x, y], angle];

function get_x(turtle) = turtle[0][0];
function get_y(turtle) = turtle[0][1];
function get_xy(turtle) = turtle[0];
function get_angle(turtle) = turtle[1];

function set_point(turtle, point) = [point, get_angle(turtle)];

function set_x(turtle, x) = [[x, get_y(turtle)], get_angle(turtle)];
function set_y(turtle, y) = [[get_x(turtle), y], get_angle(turtle)];
function set_angle(turtle, angle) = [get_xy(turtle), angle];

function forward(turtle, leng) =
turtle(
get_x(turtle) + leng * cos(get_angle(turtle)),
get_y(turtle) + leng * sin(get_angle(turtle)),
get_angle(turtle)
);

function turn(turtle, angle) = [get_xy(turtle), get_angle(turtle) + angle];

module line(point1, point2, width = 1, cap_round = true) {
angle = 90 - atan((point2[1] - point1[1]) / (point2[0] - point1[0]));
offset_x = 0.5 * width * cos(angle);
offset_y = 0.5 * width * sin(angle);

offset1 = [-offset_x, offset_y];
offset2 = [offset_x, -offset_y];

if(cap_round) {
translate(point1) circle(d = width, \$fn = 24);
translate(point2) circle(d = width, \$fn = 24);
}

polygon(points=[
point1 + offset1, point2 + offset1,
point2 + offset2, point1 + offset2
]);
}

module polyline(points, width = 1) {
module polyline_inner(points, index) {
if(index < len(points)) {
line(points[index - 1], points[index], width);
polyline_inner(points, index + 1);
}
}

polyline_inner(points, 1);
}

module triangle(t, side_leng, width) {
angle = 120;
t_p1 = forward(t, side_leng);                   // 前進 side_leng
polyline([get_xy(t), get_xy(t_p1)], width);     // 畫線

t_p2 = forward(turn(t_p1, angle), side_leng);   // 轉 angle 並前進 side_leng
polyline([get_xy(t_p1), get_xy(t_p2)], width);  // 畫線

t_p3 = forward(turn(t_p2, angle), side_leng);   // 轉 angle 並前進 side_leng
polyline([get_xy(t_p2), get_xy(t_p3)], width);  // 畫線
}

module two_triangles(t, side_len, len_limit, width) {
angle = 60;
triangle(t, side_len, width);
// 前進一半邊長，並轉動 60 度
next_t = turn(forward(t, side_len / 2), angle);
// 轉 60 度的小三角
triangle(next_t, side_len / 2, width);
}

module sierpinski_triangle(t, side_len, len_limit, width) {
if(side_len >= len_limit) {
two_triangles(t, side_len, len_limit, width);

// 左下同心三角形
sierpinski_triangle(t, side_len / 2, len_limit, width);

// 右下同心三角形
sierpinski_triangle(forward(t, side_len / 2), side_len / 2, len_limit, width);

// 最上面的同心三角形
sierpinski_triangle(turn(forward(turn(t, 60), side_len / 2), -60),
side_len / 2, len_limit, width);
}
}

side_len = 150;
len_limit = 4;
width = 0.5;
t = turtle(0, 0, 0);

sierpinski_triangle(t, side_len, len_limit, width);
``````