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);
	}
}