Pappus Chain (basic, interactive)
/**
* Copyright Aquioux ( http://wonderfl.net/user/Aquioux )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/AeZi
*/
// forked from Aquioux's Pappus Chain (basic, static)
package {
//import aquioux.display.colorUtil.RGBWheel;
import flash.display.Graphics;
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.MouseEvent;
[SWF(width = "465", height = "465", frameRate = "30", backgroundColor = "#ffffff")]
/**
* パップス・チェーン Pappus Chain (2)
* 基本形(マウス・インタラクティブ)
* @see http://aquioux.net/blog/?p=3830
* @author Yoshida, Akio
*/
public class Main extends Sprite {
// サイズ
private const STAGE_WIDTH:int = stage.stageWidth;
// スケール
static private const SCALE:int = 455;
// キャンバス
private var canvas_:Shape;
// 背景色
static private const FILL_COLOR:uint = 0xffffff;
// 円の色
static private const CIRCLE_COLOR:uint = 0x000000;
// 円を半円に見せるための覆い
private var cover_:Shape;
/**
* コンストラクタ
*/
public function Main():void {
setup();
stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
draw(0.618);
}
/**
* セットアップ
*/
private function setup():void {
// サイズ
const STAGE_HEIGHT:int = stage.stageHeight;
// キャンバスの生成
canvas_ = new Shape();
canvas_.x = (STAGE_WIDTH - SCALE) / 2;
canvas_.y = STAGE_HEIGHT * 0.75;
addChild(canvas_);
// 円を半円に見せるための覆いの生成
cover_ = new Shape();
cover_.x = canvas_.x - 1;
cover_.y = canvas_.y;
addChild(cover_);
var g:Graphics = cover_.graphics;
g.beginFill(FILL_COLOR);
g.drawRect(0, 0, STAGE_WIDTH, STAGE_HEIGHT / 2);
g.endFill();
g.lineStyle(0, 0x0);
g.moveTo(0, 0);
g.lineTo(SCALE + 1, 0);
}
// マウスハンドラ
private function mouseMoveHandler(event:MouseEvent):void {
var r:Number = mouseX / STAGE_WIDTH;
if (r < 0.05) r = 0.05;
if (r > 0.95) r = 0.95;
draw(r);
}
/**
* パップス・チェーンの計算および描画
*/
private function draw(r:Number):void {
// キャンバス・クリア
canvas_.graphics.clear();
// 正接円の直径
var s:Number = 1.0 - r;
// 正接円の半径
var rRadius:Number = r / 2;
var sRadius:Number = s / 2;
// 外接円
drawCircle(0.5, 0.0, 0.5, CIRCLE_COLOR);
// 正接円1
drawCircle(rRadius, 0.0, rRadius, FILL_COLOR);
// 正接円2
drawCircle(r + sRadius, 0.0, sRadius, FILL_COLOR);
var ss:Number = s * s; // 円鎖計算用パラメータ1
var rs:Number = r * s; // 円鎖計算用パラメータ2
var len:int = 10 / s >> 0; // 円鎖の数
var angle:Number = 0.0; // 円鎖色用パラメータ1
var add:Number = 360 / len; // 円鎖色用パラメータ1
for (var i:int = 1; i < len; ++i) {
var val:Number = i * i * ss + r; // 円鎖計算用パラメータ3
var centerX:Number = r * (1 + r) / (2 * val);
var centerY:Number = i * rs / val;
var radius:Number = rs / (2 * val);
drawCircle(centerX, -centerY, radius, RGBWheel.getDegreeColor(angle));
angle += add;
}
}
// 円の描画
private function drawCircle(x:Number, y:Number, radius:Number, color:uint):void {
var g:Graphics = canvas_.graphics;
g.lineStyle(0, 0x0);
g.beginFill(color);
g.drawCircle(x * SCALE, y * SCALE, radius * SCALE);
g.endFill();
}
}
}
//package aquioux.display.colorUtil {
/**
* コサインカーブで色相環的に RGB を計算
* @author YOSHIDA, Akio
*/
/*public*/ class RGBWheel {
/**
* 角度 angle に応じた RGB を得る(弧度法指定 radian)
* @param radian 角度(弧度法)
* @return 色(0xRRGGBB)
*/
static public function getRadianColor(radian:Number):uint {
var r:uint = (Math.cos(radian) + 1) * 0xff >> 1;
var g:uint = (Math.cos(radian + 2.0943951023931953) + 1) * 0xff >> 1;
var b:uint = (Math.cos(radian - 2.0943951023931953) + 1) * 0xff >> 1;
// 2.0943951023931953 = Math.PI * 2 / 3 radian(= 120 degree)
return r << 16 | g << 8 | b;
}
/**
* 角度 angle に応じた RGB を得る(度数法指定 degree)
* @param degree 角度(度数法)
* @return 色(0xRRGGBB)
*/
static public function getDegreeColor(degree:Number):uint {
return getRadianColor(degree * 0.017453292519943295);
}
}
//}