拼圖


在我的作品中,有一系列的 拼 圖 設計,這一系列的拼圖,都是從 Puzzle generator 衍生而來:

Puzzle generator

一個拼圖片

如果只是要做個拼圖片,確實沒什麼難的,只要正方形與圓,加上一些交集或減集就可以了:

length = 20;
spacing = 0.5;

p_offset = length * 9 / 16 + spacing / 2;
n_offset = -length * 7 / 16 - spacing / 2;
convex_radius = length / 8 - spacing / 2;
concave_radius = length / 8 + spacing / 2;

$fn = 24;

difference() {
    union() {
        square(length, center = true);
        translate([p_offset, 0]) 
            circle(convex_radius);
        translate([0, p_offset]) 
            circle(convex_radius);
    }

    translate([n_offset, 0]) 
        circle(concave_radius);
    translate([0, n_offset]) 
        circle(concave_radius);
}

為了能讓拼圖片卡住,圓形凹凸與正方形的邊並不是交在半圓處,我這邊設計交在四分之三圓處,另一個要注意的是,凹凸以及拼圖片之間的接合,必須 留足夠的間隙,這樣才能卡進去,這間隙視使用的 3DP 使用的線材,以及列印時的參數而定,基本上,0.5 應該是可以的,不過,還是留個參數會比較好,方便隨時調整。

為了簡化範例,這裡每邊只設計了一個凹凸:

拼圖

很多拼圖片

如果想要很多拼圖片呢?在切片軟體中多複製幾個就可以了,對吧!是沒錯,不過這也是程式建模的優勢之處,直接用程式產生的話,跑個迴圈就可以 了:

length = 20;
spacing = 0.5;
x_puzzles = 11;
y_puzzles = 6;

module puzzle_piece(length, spacing = 0.5) {
    p_offset = length * 9 / 16 + spacing / 2;
    n_offset = -length * 7 / 16 - spacing / 2;

    convex_radius = length / 8 - spacing / 2;
    concave_radius = length / 8 + spacing / 2;

    $fn = 24;

    translate([length / 2, length / 2]) difference() {
        union() {
            square(length, center = true);
            translate([p_offset, 0]) 
                circle(convex_radius);
            translate([0, p_offset]) 
                circle(convex_radius);
        }

        translate([n_offset, 0]) 
            circle(concave_radius);
        translate([0, n_offset]) 
            circle(concave_radius);
    }
}

for(x = [0:x_puzzles - 1]) {
    for(y = [0:y_puzzles - 1]) {
        translate([x * (length + spacing), y * (length + spacing)]) 
            puzzle_piece(length, spacing = 0.5);
    }
}

拼圖

修邊

基本上到這邊就可以結束了,只不過,如果想要再龜毛一點,邊邊不要有凹凸的話:

拼圖

特別設計出邊緣與角落的拼圖片是也可以,不過這個需求可以投機取巧一些,將前一次程式碼的成果,先用一些小圓把邊邊的凹填住:

拼圖

然後,建立一個長方形,跟上面的圖取交集就可以了:

拼圖

依照以上的想法,可以完成以下的程式碼:

length = 20;
spacing = 0.5;
x_puzzles = 10;
y_puzzles = 5;

module puzzle_piece(length, spacing = 0.5) {
    p_offset = length * 9 / 16 + spacing / 2;
    n_offset = -length * 7 / 16 - spacing / 2;

    convex_radius = length / 8 - spacing / 2;
    concave_radius = length / 8 + spacing / 2;

    $fn = 24;

    translate([length / 2, length / 2]) difference() {
        union() {
            square(length, center = true);
            translate([p_offset, 0]) 
                circle(convex_radius);
            translate([0, p_offset]) 
                circle(convex_radius);
        }

        translate([n_offset, 0]) 
            circle(concave_radius);
        translate([0, n_offset]) 
            circle(concave_radius);
    }
}


module puzzle(x_puzzles, y_puzzles, length, spacing = 0.5) {
    intersection() {
        square([
            x_puzzles * (length + spacing) - spacing, 
            y_puzzles * (length + spacing) - spacing]
        );

        for(x = [0:x_puzzles - 1]) {
            for(y = [0:y_puzzles - 1]) {
                translate([x * (length + spacing), y * (length + spacing)])
                union() {
                    puzzle_piece(length, spacing = 0.5);
                    if(x == 0) {
                        translate([0, length / 2]) 
                            circle(length / 4, $fn = 24);
                    }
                    if(y == 0) {
                        translate([length / 2, 0]) 
                            circle(length / 4, $fn = 24);
                    }           
                }
            }
        }
    }
}

puzzle(x_puzzles, y_puzzles, length, spacing);

接下來就是發揮巧思的時候了,你的拼圖上想什麼呢?從底下這個簡單的九九乘法表開始作為練習,會是個不錯的選擇:

Multiplication puzzle generator