import java.applet.*; import java.awt.*; /* class Affine means: x'= xx * x + xy * y + xo y'= yx * x + yy * y + yo */ class Affine { double xx, xy, xo; double yx, yy, yo; /* constructor */ /* make a unit matrix */ Affine() { xx = 1.0; yy = 1.0; } void scale(double a) { xx *= a; xy *= a; xo *= a; yx *= a; yy *= a; yo *= a; } void scale(double a, double b) { xx *= a; xy *= a; xo *= a; yx *= b; yy *= b; yo *= b; } void shift(double a, double b) { xo += a; yo += b; } void rotate(double theta) { double ct = Math.cos(theta); double st = Math.sin(theta); double Nxx = xx * ct - yx * st; double Nxy = xy * ct - yy * st; double Nxo = xo * ct - yo * st; double Nyx = yx * ct + xx * st; double Nyy = yy * ct + xy * st; double Nyo = yo * ct + xo * st; xo = Nxo; xx = Nxx; xy = Nxy; yo = Nyo; yx = Nyx; yy = Nyy; } void mult(Affine m) { double Nxx = xx * m.xx + yx * m.xy ; double Nxy = xy * m.xx + yy * m.xy ; double Nxo = xo * m.xx + yo * m.xy + m.xo; double Nyx = xx * m.yx + yx * m.yy ; double Nyy = xy * m.yx + yy * m.yy ; double Nyo = xo * m.yx + yo * m.yy + m.yo; xx = Nxx; xy = Nxy; xo = Nxo; yx = Nyx; yy = Nyy; yo = Nyo; } double det(){ return xx*yy-xy*yx; } } class coordinate{ double x,y; static final double left=-0.5; static final double right=1.5; static final double bottom=-1; static final double top=1; void transformed(coordinate p, Affine m){ x = p.x * m.xx + p.y * m.xy + m.xo; y = p.x * m.yx + p.y * m.yy + m.yo; } void map(int w[]){ w[0]=(int)Math.round(256*(x-left)/(right-left)); w[1]=(int)Math.round(256*(y-top)/(bottom-top)); } } public class levy extends Applet{ Affine f1,f2; static final coordinate origin= new coordinate(); public void init(){ setBackground(Color.white); f1=new Affine(); f1.scale(1,-1); f1.rotate(Math.PI / 4); f1.scale(Math.sqrt(0.5)); f2=new Affine(); f2.shift(-1.0, 0.0); f2.rotate(Math.PI / 4); f2.scale(Math.sqrt(0.5)); f2.shift(1.0, 0.0); } public void paint(Graphics g){ Affine t=new Affine(); trans(0,t,g); } public void trans(int n, Affine t, Graphics g){ if (n==14) { int w[]; w= new int[2]; coordinate z = new coordinate(); z.transformed(origin,t); z.map(w); g.drawLine(w[0],w[1],w[0],w[1]); } else { Affine m1= new Affine(); m1.mult(f1); m1.mult(t); trans(n+1,m1,g); Affine m2= new Affine(); m2.mult(f2); m2.mult(t); trans(n+1,m2,g); }; } }
Class Affineは,行列演算のパッケージです。
Affine m = new Affine() で,mに恒等変換がセットされます。
Class coordinateは,物理座標と仮想座標との変換を担当します。
Class levyが本体です。
Affine f1に f1 =scale(1,-1)*rotate(π/4)*scale(1/√2)を,
Affine f2に f2 =shift(1,0)*rotate(π/4)*scale(1/√2)*shift(1,0)を
対応させています。
なお,実際に上で動いているアプレットは,安定な動作をするように修正したものになっています。参照
Javaに関する情報は, 日本サン JAVAガイド