Pappus Chain (advanced, static)
forked from Pappus Chain (basic, static) (diff: 37)
ActionScript3 source code
/**
* Copyright Aquioux ( http://wonderfl.net/user/Aquioux )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/pyzV
*/
// 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;
[SWF(width = "465", height = "465", frameRate = "30", backgroundColor = "#ffffff")]
/**
* パップス・チェーン Pappus Chain (3)
* 発展形(静止版)
* @see http://aquioux.net/blog/?p=3831
* @author Yoshida, Akio
*/
public class Main extends Sprite {
// スケール
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();
draw();
}
/**
* セットアップ
*/
private function setup():void {
// サイズ
const STAGE_WIDTH:int = stage.stageWidth;
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 draw():void {
// 正接円の直径(外接円の直径が 1.0)
var r:Number = 0.618;
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 = 5 / s >> 0; // 円鎖の数
var angle:Number = 0; // 円列色用パラメータ1
var add:Number = -360 / 5; // 円列色用パラメータ1
for (var i:int = 1; i < len; ++i) {
// 円列1
var val:Number = i * i * ss + r;
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 + add * 0));
// 円列2
val = 4 + 4 * i * (i - 1) * ss + r * (r - 1);
centerX = r * (7 + r) / (2 * val);
centerY = 2 * (2 * i - 1) * rs / val;
radius = rs / (2 * val);
drawCircle(centerX, -centerY, radius, RGBWheel.getDegreeColor(angle + add * 1));
// 円列3(1)
val = 12 + 3 * i * (3 * i - 4) * ss + r * (4 * r - 7);
centerX = r * (17 + r) / (2 * val);
centerY = 3 * (3 * i - 2) * rs / val;
radius = rs / (2 * val);
drawCircle(centerX, -centerY, radius, RGBWheel.getDegreeColor(angle + add * 2));
// 円列3(2)
val = 9 + 12 * i * (i - 1) * ss + r * (4 * r - 1);
centerX = r * (17 + 7 * r) / (2 * val);
centerY = 6 * (2 * i - 1) * rs / val;
radius = rs / (2 * val);
drawCircle(centerX, -centerY, radius, RGBWheel.getDegreeColor(angle + add * 3));
// 円列3(3)
val = 9 + 3 * i * (3 * i - 2) * ss - rs;
centerX = r * (17 + r) / (2 * val);
centerY = 3 * (3 * i - 1) * rs / val;
radius = rs / (2 * val);
drawCircle(centerX, -centerY, radius, RGBWheel.getDegreeColor(angle + add * 4));
}
}
// 円の描画
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);
}
}
//}