Ex15_3
/*--------------------------------------
Ex15_3.java
対数螺旋:矩形アニメ(無限回繰返し描画)
---------------------------------------*/
package jp_bunkyo;
import java.applet.*;
import java.awt.*;
public class Ex15_3 extends Applet implements Runnable {
final int cx = 205, cy = 205; // 回転の中心位置
final int[] dx = {-200, 200, 200,-200}; // 中心位置からの四隅のずれ x座標
final int[] dy = {-200,-200, 200, 200}; // 中心位置からの四隅のずれ y座標
double theta = 2*Math.PI/36; // 対数螺旋の回転角 = 2π/36 = 360°/36 = 10°
double scale = 9.0/10.0; // 矩形の縮小率
int[] x = new int[4], y = new int[4]; // 現在の矩形の四隅座標
int tmp, i, j, num = 36; // 描画回数 num
boolean flg = true; // 画面クリア用フラグ(true = 矩形描画, false = 画面クリア)
int red, grn, blu; // 3色:赤・緑・青用
Color col;
Thread thd = null;
public void init() { // 初期化
this.setSize(410, 410); // 描画領域 410×410
red = 0; grn = 125; blu = 255; // 初期3色設定
col = new Color(red,grn,blu); // 初期3色混合・設定
thd = new Thread(this); // スレッド生成
thd.start(); // スレッド開始
}
public void update(Graphics g) { // 上書き(重ね書き)用
paint(g);
}
public void paint(Graphics g) {
if (flg) { // flg = true なら矩形描画
g.setColor(col);
g.drawPolygon(x, y, x.length);
} else { // flg = flase なら画面クリア
g.clearRect(0, 0, 410, 410); // 画面クリアメソッド:左上(0,0)〜右下(410,410)範囲をクリア
flg = true; // 画面クリア後,描画モード flg = true に設定
}
}
public void run() {
while (true) { // 無限に繰り返すための無限ループ
for (i = 0; i < num; i++) { // 1回当たりの繰返し回数:num回繰返し矩形描画
red = (red + 5*i) % 255;
grn = (grn + 15*i) % 255;
blu = (blu + 30*i) % 255;
col = new Color(red, grn, blu);
for (j = 0; j < 4; j++) { // 矩形の四隅を描画
x[j] = (int)(dx[j] * Math.pow(scale, i)); // 矩形の四隅:x座標
y[j] = (int)(dy[j] * Math.pow(scale, i)); // 矩形の四隅:y座標
tmp = cx + rotate_x(x[j], y[j], theta*i); // x座標を回転+平行移動
y[j] = cy + rotate_y(x[j], y[j], theta*i); // y座標を回転+平行移動
x[j] = tmp; // y座標回転前に一時的に保存したx座標地を x座標変数へ
}
repaint(); // 再描画
try {
thd.sleep(100); // スレッド・スリープ(100ミリ秒)
} catch (InterruptedException e) {
}
}
flg = false; // 矩形をnum回描画した後,画面を一度クリアするため,描画モードを false に
}
}
public int rotate_x(int cx, int cy, double r) { // x座標回転:回転前の点(cx,cy)と回転角rラジアン
int tx;
tx = (int)(Math.cos(r) * cx - Math.sin(r) * cy);
return (tx);
}
public int rotate_y(int cx, int cy, double r) { // y座標回転:回転前の点(cx,cy)と回転角rラジアン
int ty;
ty = (int)(Math.sin(r) * cx + Math.cos(r) * cy);
return (ty);
}
}