ruby+svgでフラクタル
幾何なんて久しぶりだ。
コッホ曲線
rubyのmatrixが意外に使いやすいことがわかった。
てか、行列とか幾何とかすっかり忘れてるよ。
復習のために一応書いておく
2点の3分割点c,dの座標はそれぞれ
点eは点dを点cを中心に反時計回りに60°つまりπ/3回転したもの
だから、点dを-c分だけ平行移動、π/3回転、c分平行移動することを行列で表すと
展開した方が良さそうな気がしたが面倒なのでそのままrubyに埋め込むことにする
#!/usr/bin/ruby require 'matrix' puts <<HEAD content-type: text/xml <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>svg koch</title> </head> <body> <svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="1000" height="1000"> HEAD def line(a,b) %Q!<line x1="#{a[0]}" y1="#{a[1]}" x2="#{b[0]}" y2="#{b[1]}" stroke="blue" stroke-width="1"/>! end def koch(a,b,n) c=Vector[(a[0]*2+b[0])/3,(a[1]*2+b[1])/3,1] d=Vector[(a[0]+b[0]*2)/3,(a[1]+b[1]*2)/3,1] e=Matrix[[1,0,c[0]], [0,1,c[1]], [0,0, 1]] * Matrix[[Math.cos(Math::PI/3),-Math.sin(Math::PI/3),0], [Math.sin(Math::PI/3), Math.cos(Math::PI/3),0], [0 ,0 ,1]] * Matrix[[1,0,-c[0]], [0,1,-c[1]], [0,0, 1]] * d if n>0 koch(a,c,n-1) koch(c,e,n-1) koch(e,d,n-1) koch(d,b,n-1) else puts line(a,c) puts line(c,e) puts line(e,d) puts line(d,b) end end koch(Vector[100,100,1],Vector[900,100,1],5) puts <<TAIL </svg> </body> </html> TAIL
ドラゴンカーブ
コッホ曲線とほぼ同じなのだが、再帰する際に a->c と b->c で行う点が違う。c->bにすると45°のコッホ崩れが現れる。
#!/usr/bin/ruby require 'matrix' puts <<HEAD content-type: text/xml <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>svg dragon</title> </head> <body> <svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="1000" height="1000"> HEAD def line(a,b) %Q!<line x1="#{a[0]}" y1="#{a[1]}" x2="#{b[0]}" y2="#{b[1]}" stroke="blue" stroke-width="1"/>! end def dragon(a,b,n) c=Matrix[[1,0,a[0]], [0,1,a[1]], [0,0, 1]] * Matrix[[1/Math.sqrt(2),0 ,0], [0 ,1/Math.sqrt(2),0], [0 ,0 ,1]] * Matrix[[Math.cos(Math::PI/4),-Math.sin(Math::PI/4),0], [Math.sin(Math::PI/4), Math.cos(Math::PI/4),0], [0 ,0 ,1]] * Matrix[[1,0,-a[0]], [0,1,-a[1]], [0,0, 1]] * b if n>0 dragon(a,c,n-1) dragon(b,c,n-1) else puts line(a,c) puts line(b,c) end end dragon(Vector[200,300,1],Vector[800,300,1],14) puts <<TAIL </svg> </body> </html> TAIL