はじめに
シェルピンスキー曲線をLシステムを使って描きます。
環境
Processing 4
生成ルール
こちらに準拠しています。
コード
wikiから取ってきた、ルールの文字列の「-」の文字コードが違っていて、この問題になかなか気がつくことができませんでした。chatGTPにバグ取りお願いしました。
SVGで出力していますが、depthを1段階上げると15倍にデータサイズが増えます。
5で246MB
import processing.svg.*;
int depth = 4; // 再帰の深さ
float length = 200; // 初期の線の長さ
String axiom = "F--XF--F--XF";
String ruleA = "XF+G+XF--F--XF+G+X";
String current;
float angle = radians(45);
void setup() {
size(500, 500);
background(255);
beginRecord(SVG, "filename.svg");
stroke(0);
current = axiom;
for (int i = 0; i < depth; i++) {
current = generate(current);
}
translate(20, 10);
rotate(angle*3);
drawLSystem(current, length / pow(2, depth));
endRecord();
}
String generate(String str) {
String result = "";
for (char c : str.toCharArray()) {
if (c == 'X') {
result += ruleA;
} else {
result += c;
}
}
return result;
}
void drawLSystem(String str, float len) {
for (char c : str.toCharArray()) {
if (c == 'F' || c == 'G') {
line(0, 0, len, 0);
translate(len, 0);
} else if (c == '+') {
rotate(angle);
} else if (c == '-') {
rotate(-angle);
}
}
}
90度のルール
wikiにある以下のルールだと、このような図になります。
axiom = "F+XF+F+XF";
ruleA = "XF-F+F-XF+F+XF-F+F-X";
angle = radians(90);
Sierpinski Gasketになるルール
ルール文字が2種類
axiom = "A";
ruleA = "B-A-B";
ruleB = "A+B+A";
angle = radians(60);
int depth = 6; // 再帰の深さ
float length = 500; // 初期の線の長さ
String axiom = "A";
String ruleA = "B-A-B";
String ruleB = "A+B+A";
String current;
float angle = radians(60);
void setup() {
size(550, 500);
background(255);
stroke(0);
current = axiom;
for (int i = 0; i < depth; i++) {
current = generate(current);
}
translate(20, 10);
drawLSystem(current, length / pow(2, depth));
}
String generate(String str) {
String result = "";
for (char c : str.toCharArray()) {
if (c == 'A') {
result += ruleA;
} else if (c == 'B') {
result += ruleB;
} else {
result += c;
}
}
return result;
}
void drawLSystem(String str, float len) {
for (char c : str.toCharArray()) {
if (c == 'A' || c == 'B') {
line(0, 0, len, 0);
translate(len, 0);
} else if (c == '+') {
rotate(angle);
} else if (c == '-') {
rotate(-angle);
}
}
}