Whirl Variation 2.
Whirls are figures constructed by nesting a sequence of polygons (each having the same number of sides), each slightly smaller and rotated relative to the previous one. ( http://mathworld.wolfram.com/Whirl.html )
/**
* Copyright szbzs2004 ( http://wonderfl.net/user/szbzs2004 )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/k2Mp
*/
package {
import flash.display.Graphics;
import flash.display.Sprite;
import flash.display.Shape;
import flash.events.Event;
import com.bit101.components.ColorChooser;
import com.bit101.components.HUISlider;
import com.bit101.components.Window;
[SWF(width = "465", height = "465", frameRate = "40")];
public class WhirlVariation2 extends Sprite {
public static const WIDTH:Number = 465;
public static const HEIGHT:Number = 465;
private static const SIZE_0:Number = WIDTH;
private static const SIZE_MIN:Number = 2;
private static const MAX_ITERATION:int = 500;
private static const DEFAULT_Q:Number = 0.98;
private static const DEFAULT_CS:uint = 0xffffff;
private static const DEFAULT_CE:uint = 0x800000;
private static const DEFAULT_CG:Number = 3;
private var canvas:Shape;
private var squares:Vector.<Square>;
private var q:Number = DEFAULT_Q;
private var cs:uint = DEFAULT_CS;
private var ce:uint = DEFAULT_CE;
private var cg:Number = DEFAULT_CG;
private var pWindow:Window;
private var qSlider:HUISlider;
private var csChooser:ColorChooser;
private var ceChooser:ColorChooser;
private var cgSlider:HUISlider;
public function WhirlVariation2():void {
canvas = new Shape();
canvas.x = WIDTH / 2;
canvas.y = HEIGHT / 2;
addChild(canvas);
initParametersWindow();
squaresGenerate();
squaresDraw();
}
private function squaresGenerate():void {
squares = new Vector.<Square>();
var s:Square = new Square(SIZE_0);
squares.push(s);
for (var i:int = 1; i < MAX_ITERATION && s.size > SIZE_MIN; ++i) {
s = s.whirl(q);
squares.push(s);
}
}
private function squaresDraw():void {
var csf:ColorFloat = ColorFloat.fromUInt(cs);
var cef:ColorFloat = ColorFloat.fromUInt(ce);
canvas.graphics.clear();
for (var i:int = 0; i < squares.length; ++i) {
var cf:ColorFloat = ColorFloat.interpolate(csf, cef, i / (squares.length - 1));
cf.adjustGamma(cg);
squares[i].paint(canvas.graphics, cf.toUInt(), 1);
}
}
private function initParametersWindow():void {
pWindow = new Window(this, 10, 10, "Whirl Variation 2.");
// pWindow.hasMinimizeButton = true;
pWindow.setSize(180, 86);
qSlider = new HUISlider(pWindow, 0, 25, "", changeQ);
qSlider.labelPrecision = 2;
qSlider.setSliderParams(0, 1, q);
csChooser = new ColorChooser(pWindow, 9, 46, cs, changeCs);
csChooser.usePopup = true;
ceChooser = new ColorChooser(pWindow, 100, 46, ce, changeCe);
ceChooser.usePopup = true;
cgSlider = new HUISlider(pWindow, 0, 65, "", changeCg);
cgSlider.labelPrecision = 2;
cgSlider.setSliderParams(0.1, 5, cg);
}
private function changeQ(e:Event):void {
q = e.target.value;
squaresGenerate();
squaresDraw();
}
private function changeCs(e:Event):void {
cs = e.target.value;
squaresDraw();
}
private function changeCe(e:Event):void {
ce = e.target.value;
squaresDraw();
}
private function changeCg(e:Event):void {
cg = e.target.value;
squaresDraw();
}
}
}
import flash.display.Graphics;
import flash.geom.Point;
class Square {
private var v1:Point;
private var v2:Point;
private var v3:Point;
private var v4:Point;
public function Square(s:Number = 1) {
v1 = new Point(-s / 2, -s / 2);
v2 = new Point( s / 2, -s / 2);
v3 = new Point( s / 2, s / 2);
v4 = new Point(-s / 2, s / 2);
}
public function get size():Number {
return Point.distance(v1, v2);
}
public function whirl(q:Number):Square {
var s:Square = new Square();
s.v1 = Point.interpolate(v1, v2, q);
s.v2 = Point.interpolate(v2, v3, q);
s.v3 = Point.interpolate(v3, v4, q);
s.v4 = Point.interpolate(v4, v1, q);
return (s);
}
public function paint(g:Graphics, c:uint, a:Number):void {
g.beginFill(c, a);
g.moveTo(v1.x, v1.y);
g.lineTo(v2.x, v2.y);
g.lineTo(v3.x, v3.y);
g.lineTo(v4.x, v4.y);
g.endFill();
}
}
class ColorFloat {
private var r:Number;
private var g:Number;
private var b:Number;
public function ColorFloat(_r:Number = 0, _g:Number = 0, _b:Number = 0) {
r = _r;
g = _g;
b = _b;
}
public function adjustGamma(gamma:Number):void {
r = Math.pow(r, gamma);
g = Math.pow(g, gamma);
b = Math.pow(b, gamma);
}
public function toUInt():uint {
var ru:uint = Math.round(r * 255) & 0xff;
var gu:uint = Math.round(g * 255) & 0xff;
var bu:uint = Math.round(b * 255) & 0xff;
return ((((ru << 8) | gu) << 8) | bu);
}
static public function fromUInt(c:uint):ColorFloat {
var cf:ColorFloat = new ColorFloat();
cf.b = Number(c & 0xff) / 255;
c >>= 8;
cf.g = Number(c & 0xff) / 255;
c >>= 8;
cf.r = Number(c & 0xff) / 255;
return(cf);
}
static public function interpolate(c1:ColorFloat, c2:ColorFloat, q:Number):ColorFloat {
var _r:Number = c1.r + q * (c2.r - c1.r);
var _g:Number = c1.g + q * (c2.g - c1.g);
var _b:Number = c1.b + q * (c2.b - c1.b);
return (new ColorFloat(_r, _g, _b));
}
}