- L-System
植物の成長プロセスを初めとした様々な自然物の構造を記述・表現できるアルゴリズム
L-System は1968年、アリステッド・リンデンマイヤー(Aristid Lindenmayer)により提唱された。
![]()
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import javax.swing.JFrame;
class Vector2D{
double x;
double y;
public Vector2D(double x,double y){
this.x=x;
this.y=y;
}
public void rotate(Vector2D o,double theta) {
double rx=(this.x-o.x)*Math.cos(theta)-(this.y-o.y)*Math.sin(theta);
double ry=(this.x-o.x)*Math.sin(theta)+(this.y-o.y)*Math.cos(theta);
this.x=rx+o.x;
this.y=ry+o.y;
}
public Vector2D copy() {
return new Vector2D(this.x,this.y);
}
}
public class LSystem{
public int screenW=640;
public int screenH=480;
Canvas canvas;
Graphics fg;
Graphics bg;
Image image;
int n=0;
public void drawBranch(Vector2D s,int length,int dir,int angle,int n) {
if(n<=0)return;
double theta=dir*Math.PI/180;
Graphics2D g2d=(Graphics2D)bg;
g2d.setColor(Color.black);
Vector2D e;
//BasicStroke stroke=new BasicStroke((float) (n*2));
//g2d.setStroke(stroke);
e=s.copy();
e.x-=length*Math.cos(theta);
e.y-=length*Math.sin(theta);
g2d.drawLine(
(int)s.x,
(int)s.y,
(int)e.x,
(int)e.y
);
drawBranch(e,(int)(length*0.9),(int)(dir+angle),angle,n-1);
drawBranch(e,(int)(length*0.9),(int)(dir-angle),angle,n-1);
}
public void drawScreen() {
bg.clearRect(0, 0, screenW, screenH);
bg.setColor(Color.white);
bg.fillRect(0, 0, screenW, screenH);
bg.setColor(Color.red);
Vector2D o=new Vector2D((screenW)/2,(screenH));//原点
int angle=15;
double theta=angle*Math.PI/180;
//int n=8;
double rn=Math.pow(0.9, -(n/2));
int length=(int)(2*screenH/((n+1)*(1+Math.cos(theta)))*rn*0.8);
//回転角の設定
drawBranch(o,length,90,angle,n+1);
//drawBranch(o,length,0,angle,n+1);
//drawBranch(o,length,180,angle,n+1);
//drawBranch(o,length,270,angle,n+1);
n=(n+1)%10;
//描画画面にイメージの転送
fg.drawImage(image, 0, 0, null);
}
public LSystem(){
JFrame f=new JFrame();
f.setTitle("Graphics Test");
f.setBounds(200,200,screenW,screenH);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
canvas=new Canvas();
canvas.setSize(screenW,screenH);
f.add(canvas);
canvas.setPreferredSize(new Dimension(screenW,screenH));
f.pack();
f.setVisible(true);
image=canvas.createImage(screenW,screenH);
fg=canvas.getGraphics();
bg=image.getGraphics();
while(true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO 自動生成された catch ブロック
e.printStackTrace();
}
drawScreen();
}
}
public static void main(String[] args){
new LSystem();
}
}