L-시스템(L-system)은 1986년
린덴마이어(Lindenmayer)가 생태계의 성장 모형, 특히 나무의 분기 모형을 연구하는 목적으로 고안하였다. L-시스템은 세가지
요소
는 시스템을 구성하는 문장들의 집합, (이를 다시 세분화 하여 매 단계마다 치환규칙에 의해 변하는 변수들의 집합과, 변하지 않는 상수들의 집합으로 나누기도 한다), 는 의 문장들로 구성된 시스템의 초기 상태, 는 시스템의 현 단계에서 다음 단계로 변환시키는 치환 규칙
을 나타낸다. 예를 들어 어떤 L-시스템이 다음와 같은 규칙으로 생성된다고 하자.
그러면 각 단계별 시스템의 상태는 다음과 같다.
이 L-시스템은 특히 프랙탈 구조를 그리는데 효과적인데,
아래 두 그림은 L-시스템을 이용하여 만든 시어핀스키 삼각형(Sierpinski triangle)과 시어핀스키 곡선(Sierpinski curve)이다.
시어핀스키 삼각형(Sierpinski triangle)
시어핀스키 삼각형을 그리는 L-시스템은 다음과 같이 주어진다.
이제
p5.js
코드 보기
var Start = "F-G-G";
var Rules = [];
var Result = Start;
var lineLength = 1000;
var n = 0;
Rules[0] = {
input: "F",
output: "F-G+F+G-F"
}
Rules[1] = {
input: "G",
output: "GG"
}
function Generate() {
var nextResult = "";
for (var i = 0; i < Result.length; i++) {
var check = Result.charAt(i);
for (var j = 0; j < Rules.length; j++) {
var found = false;
if (check == Rules[j].input) {
nextResult += Rules[j].output;
var found = true;
break;
}
}
if (!found) {
nextResult += check;
}
}
return nextResult;
}
function Turtle() {
for (var i = 0; i < Result.length; i++) {
var check = Result.charAt(i);
if (check == "F") {
line(0, 0, 0, -lineLength);
translate(0, -lineLength);
} else if (check == "G") {
line(0, 0, 0, -lineLength);
translate(0, -lineLength);
} else if (check == "+") {
rotate(+TWO_PI/3);
} else if (check == "-") {
rotate(-TWO_PI/3);
}
}
}
function setup() {
createCanvas(640, 600);
background(255);
textSize(15);
text("n = " + n, 110, 565);
var button = createButton("Generate")
button.mousePressed(Button);
button.position(30, 550);
}
function draw() {
}
function Button() {
background(255);
n += 1;
if (n > 8) {
background(255);
Result = "F-G-G";
lineLength = 1000;
n = 0;
text("n = " + n, 110, 565);
} else {
lineLength /= 2;
text("n = " + n, 110, 565);
push();
translate(500, 550);
Turtle();
pop();
Result = Generate();
}
}
시어핀스키 곡선(Sierpinski curve)
시어핀스키 곡선을 그리는 L-시스템은 다음과 같이 주어진다.
이제
p5.js
코드 보기
var Start = "F";
var Rules = [];
var Result = Start;
var lineLength = 1000;
var n = 0;
Rules[0] = {
input: "F",
output: "-G+F+G-"
}
Rules[1] = {
input: "G",
output: "+F-G-F+"
}
function Generate() {
var nextResult = "";
for (var i = 0; i < Result.length; i++) {
var check = Result.charAt(i);
for (var j = 0; j < Rules.length; j++) {
var found = false;
if (check == Rules[j].input) {
nextResult += Rules[j].output;
var found = true;
break;
}
}
if (!found) {
nextResult += check;
}
}
return nextResult;
}
function Turtle() {
for (var i = 0; i < Result.length; i++) {
var check = Result.charAt(i);
if (check == "F") {
line(0, 0, 0, -lineLength);
translate(0, -lineLength);
} else if (check == "G") {
line(0, 0, 0, -lineLength);
translate(0, -lineLength);
} else if (check == "+") {
rotate(+PI/3);
} else if (check == "-") {
rotate(-PI/3);
}
}
}
function setup() {
createCanvas(640, 600);
background(255);
textSize(15);
text("n = " + n, 110, 565);
var button = createButton("Generate")
button.mousePressed(Button);
button.position(30, 550);
}
function draw() {
}
function Button() {
background(255);
n += 1;
if (n > 9) {
background(255);
Result = "F";
lineLength = 1000;
n = 0;
text("n = " + n, 110, 565);
} else {
lineLength /= 2;
text("n = " + n, 110, 565);
push();
translate(500, 550);
Turtle();
pop();
Result = Generate();
}
}
'Others > Processing' 카테고리의 다른 글
p5.js 연습 006. 프랙탈 스파이로그래프(fractal spirograph) (0) | 2017.07.14 |
---|---|
p5.js 연습 005. 에피사이클로이드(epicycloid) (0) | 2017.07.09 |
p5.js 연습 004. 스파이로그래프(Spirograph) (0) | 2017.07.07 |
p5.js 연습 002. 프랙탈 나무 (0) | 2017.07.05 |
p5.js 연습 001 (1) | 2017.07.04 |