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ガイド