Fractal Flame Generator
I really impressed on Apophysis 5 years ago. Today, I made my own version!
Reference :
en.wikipedia.org/wiki/Fractal_flame
www.apophysis.org
https://www.google.co.kr/?gws_rd=ssl#newwindow=1&q=fractal+flame+algorithm
* added Triangle editor..
/**
* Copyright greentec ( http://wonderfl.net/user/greentec )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/2DLE
*/
// forked from greentec's forked from: forked from: Barnsley Fern
// forked from greentec's forked from: Barnsley Fern
// forked from greentec's Barnsley Fern
package {
import com.bit101.components.ColorChooser;
import com.bit101.components.ComboBox;
import com.bit101.components.InputText;
import com.bit101.components.Label;
import com.bit101.components.NumericStepper;
import com.bit101.components.PushButton;
import com.bit101.components.RadioButton;
import com.bit101.components.Window;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.ColorTransform;
import flash.geom.Matrix;
import com.bit101.components.Style;
public class FlashTest extends Sprite {
public var _bitmap:Bitmap;
public var _bitmapData:BitmapData;
public var _backBitmap:Bitmap;
public var _backBitmapData:BitmapData;
//public var table:Array = [
//[0, 0, 0, 0.16, 0, 0, 0.01],
//[0.85, 0.04, -0.04, 0.85, 0, 1.6, 0.85],
//[0.2, -0.26, 0.23, 0.22, 0, 1.6, 0.07],
//[-0.15, 0.28, 0.26, 0.24, 0, 0.44, 0.07]
//];
public var table:Array = [
[0,0,0,0,0,0,0],[0,0,0,0,0,0,0],[0,0,0,0,0,0,0],[0,0,0,0,0,0,0]
];
public var cpx:Number;
public var cpy:Number;
public var npx:Number;
public var npy:Number;
public var mat:Matrix;
public var iter:int = 100000;
public var magnitude:int = 120;
public var oneFrameIter:int = 200;
public var nowIter:int = 0;
public var points:Vector.<Vector.<Number>> = new Vector.<Vector.<Number>>(465);
public var colors:Vector.<Vector.<Number>> = new Vector.<Vector.<Number>>(465);
public var colorMap:Array = [[0, 0.2298057, 0.298717966, 0.753683153], [0.03125, 0.26623388, 0.353094838, 0.801466763], [0.0625, 0.30386891, 0.406535296, 0.84495867], [0.09375, 0.342804478, 0.458757618, 0.883725899], [0.125, 0.38301334, 0.50941904, 0.917387822], [0.15625, 0.424369608, 0.558148092, 0.945619588], [0.1875, 0.46666708, 0.604562568, 0.968154911], [0.21875, 0.509635204, 0.648280772, 0.98478814], [0.25, 0.552953156, 0.688929332, 0.995375608], [0.28125, 0.596262162, 0.726149107, 0.999836203], [0.3125, 0.639176211, 0.759599947, 0.998151185], [0.34375, 0.681291281, 0.788964712, 0.990363227], [0.375, 0.722193294, 0.813952739, 0.976574709], [0.40625, 0.761464949, 0.834302879, 0.956945269], [0.4375, 0.798691636, 0.849786142, 0.931688648], [0.46875, 0.833466556, 0.860207984, 0.901068838], [0.5, 0.865395197, 0.86541021, 0.865395561], [0.53125, 0.897787179, 0.848937047, 0.820880546], [0.5625, 0.924127593, 0.827384882, 0.774508472], [0.59375, 0.944468518, 0.800927443, 0.726736146], [0.625, 0.958852946, 0.769767752, 0.678007945], [0.65625, 0.96732803, 0.734132809, 0.628751763], [0.6875, 0.969954137, 0.694266682, 0.579375448], [0.71875, 0.966811177, 0.650421156, 0.530263762], [0.75, 0.958003065, 0.602842431, 0.481775914], [0.78125, 0.943660866, 0.551750968, 0.434243684], [0.8125, 0.923944917, 0.49730856, 0.387970225], [0.84375, 0.89904617, 0.439559467, 0.343229596], [0.875, 0.869186849, 0.378313092, 0.300267182], [0.90625, 0.834620542, 0.312874446, 0.259301199], [0.9375, 0.795631745, 0.24128379, 0.220525627], [0.96875, 0.752534934, 0.157246067, 0.184115123], [1, 0.705673158, 0.01555616, 0.150232812]];
public var flameTypeArray:Array = ["Linear", "Sinusoidal", "Spherical", "Swirl", "Horseshoe", "Polar", "Handkerchief", "Heart", "Disc", "Spiral", "Hyperbolic", "Diamond", "Ex", "Julia", "Fisheye", "Eyefish", "Bubble"];
public var flameType:Array = [0, 0, 0, 0];
public var flameTypeComboBoxArray:Array = [];
public var inputTextArray:Array = [];
public var nowIterLabel:Label;
public var _shape:Shape;
public var colT:ColorTransform;
public var gamma:Number = 0.5;
public var antiBitmapData:BitmapData;
public var drawMoreButton:PushButton;
public var colorMapButtonArray:Array = [];
public var colorMapShapeArray:Array = [];
public var colorSelectShapeYellow:Shape;
public var colorSelectShapeGreen:Shape;
public var colorSelectShapeYellowIndex:int = 0;
public var colorSelectShapeGreenIndex:int = 32;
public var colorSelectYellowRadioButton:RadioButton;
public var colorSelectGreenRadioButton:RadioButton;
public var colorSelectColorChooser:ColorChooser;
public var debugOffset:int = 20;
public var settingsMiniButton:PushButton;
public var colorMiniButton:PushButton;
public var triangleMiniButton:PushButton;
public var flameMiniButton:PushButton;
public var settingWindow:Window;
public var colorWindow:Window;
public var flameWindow:Window;
public var triangleWindow:Window;
//public var triangleHolder:Sprite;
//public var triangleBitmapData:BitmapData;
public var triangleSprite1:Sprite;
public var triangleSprite2:Sprite;
public var triangleSprite3:Sprite;
public var triangleSprite4:Sprite;
public var triangleSpriteArray:Array;
public var trianglePointSpriteArray:Array;
public var triangleColors:Array = [0xFFF001, 0xFD1999, 0x99FC20, 0x00E6FE, 0xA10EEC];
public var isDragging:Boolean = false;
public var prevDragX:Number;
public var prevDragY:Number;
public function FlashTest() {
stage.scaleMode = "noScale";
Style.BACKGROUND = 0x444444;
Style.BUTTON_FACE = 0x666666;
Style.INPUT_TEXT = 0xBBBBBB;
Style.LABEL_TEXT = 0xCCCCCC;
Style.PANEL = 0x666666;
Style.PROGRESS_BAR = 0x666666;
_bitmapData = new BitmapData(465, 465, true, 0x00ffffff);
_bitmap = new Bitmap(_bitmapData);
_backBitmapData = new BitmapData(465, 465, false, 0x292929);
_backBitmap = new Bitmap(_backBitmapData);
addChild(_backBitmap);
addChild(_bitmap);
antiBitmapData = new BitmapData(465, 465, true, 0x00ffffff);
_shape = new Shape();
_shape.graphics.beginFill(0x000000);
_shape.graphics.drawRect(0, 0, 1, 1);
_shape.graphics.endFill();
colT = new ColorTransform();
settingWindow = new Window(this, 465 - 130, 10, "Settings");
settingWindow.hasMinimizeButton = true;
settingWindow.hasCloseButton = true;
settingWindow.width = 120;
settingWindow.height = 260;
settingWindow.alpha = 0.7;
settingWindow.name = "setting";
settingWindow.addEventListener(Event.CLOSE, onWindowClose);
drawMoreButton = new PushButton(settingWindow, 10, 10 + debugOffset, "Draw More", onDrawMore);
drawMoreButton.toggle = true;
nowIterLabel = new Label(settingWindow, drawMoreButton.x, drawMoreButton.y + drawMoreButton.height, "Now Iter: " + String(iter));
var redrawButton:PushButton = new PushButton(settingWindow, nowIterLabel.x, nowIterLabel.y + nowIterLabel.height + 10, "Redraw", onRedraw);
var resetButton:PushButton = new PushButton(settingWindow, redrawButton.x, redrawButton.y + redrawButton.height, "Reset All", onResetAll);
var magnitudeLabel:Label = new Label(settingWindow, resetButton.x, resetButton.y + resetButton.height + 10, "Zoom");
var magnitudeNumericStepper:NumericStepper = new NumericStepper(settingWindow, resetButton.x, magnitudeLabel.y,
function(e:Event):void
{
magnitude = e.target.value;
}
);
magnitudeNumericStepper.value = magnitude;
magnitudeNumericStepper.x = 110 - 60;
magnitudeNumericStepper.width = 60;
var iterLabel:Label = new Label(settingWindow, magnitudeLabel.x, magnitudeLabel.y + magnitudeLabel.height, "Iter");
var iterInputText:InputText = new InputText(settingWindow, magnitudeLabel.x, iterLabel.y, String(iter));
iterInputText.addEventListener(Event.CHANGE, onChangeIter);
iterInputText.restrict = "0-9";
iterInputText.width = 60;
iterInputText.x = 110 - 60;
var gammaLabel:Label = new Label(settingWindow, iterLabel.x, iterLabel.y + iterLabel.height, "Gamma");
var gammaNumericStepper:NumericStepper = new NumericStepper(settingWindow, 50, gammaLabel.y,
function(e:Event):void
{
gamma = e.target.value;
}
);
gammaNumericStepper.width = 60;
gammaNumericStepper.value = gamma;
gammaNumericStepper.minimum = 0.1;
gammaNumericStepper.maximum = 10;
gammaNumericStepper.step = 0.1;
var backgroundLabel:Label = new Label(settingWindow, gammaLabel.x, gammaLabel.y + gammaLabel.height, "Back");
var backgroundColorChooser:ColorChooser = new ColorChooser(settingWindow, 50, backgroundLabel.y, 0x292929,
function(e:Event):void
{
_backBitmapData.fillRect(_backBitmapData.rect, e.target.value);
}
);
backgroundColorChooser.usePopup = true;
var shapeAlphaLabel:Label = new Label(settingWindow, backgroundLabel.x, backgroundLabel.y + backgroundLabel.height, "Px Alpha");
var shapeAlphaNumericStepper:NumericStepper = new NumericStepper(settingWindow, 50, shapeAlphaLabel.y,
function(e:Event):void
{
_shape.graphics.clear();
_shape.graphics.beginFill(0x000000, e.target.value);
_shape.graphics.drawRect(0, 0, 1, 1);
_shape.graphics.endFill();
}
);
shapeAlphaNumericStepper.step = 0.1;
shapeAlphaNumericStepper.minimum = 0.1;
shapeAlphaNumericStepper.maximum = 1.0;
shapeAlphaNumericStepper.value = 1.0;
shapeAlphaNumericStepper.width = 60;
var antiAliasingButton:PushButton = new PushButton(settingWindow, shapeAlphaLabel.x, shapeAlphaLabel.y + shapeAlphaLabel.height + 10, "Anti-aliasing", onAntiAliasing);
flameWindow = new Window(this, 10, 465 - 150, "Flame Editor");
flameWindow.hasMinimizeButton = true;
flameWindow.hasCloseButton = true;
flameWindow.width = 455;
flameWindow.height = 140;
flameWindow.alpha = 0.7;
flameWindow.name = "flame";
flameWindow.addEventListener(Event.CLOSE, onWindowClose);
var label:Label;
label = new Label(flameWindow, 10, 30 + debugOffset, "F0");
label = new Label(flameWindow, 10, 50 + debugOffset, "F1");
label = new Label(flameWindow, 10, 70 + debugOffset, "F2");
label = new Label(flameWindow, 10, 90 + debugOffset, "F3");
label = new Label(flameWindow, 50, 10 + debugOffset, "a");
label = new Label(flameWindow, 100, 10 + debugOffset, "b");
label = new Label(flameWindow, 150, 10 + debugOffset, "c");
label = new Label(flameWindow, 200, 10 + debugOffset, "d");
label = new Label(flameWindow, 250, 10 + debugOffset, "e");
label = new Label(flameWindow, 300, 10 + debugOffset, "f");
label = new Label(flameWindow, 340, 10 + debugOffset, "prob");
label = new Label(flameWindow, 400, 10 + debugOffset, "type");
var i:int, j:int;
var inputText:InputText;
var comboBox:ComboBox;
for (i = 0; i < 4; i += 1)
{
for (j = 0; j < 7; j += 1)
{
inputText = new InputText(flameWindow, 30 + j * 50, 30 + debugOffset + i * 20, "");
inputText.width = 45;
inputTextArray.push(inputText);
}
comboBox = new ComboBox(flameWindow, 380, 30 + debugOffset + i * 20, "", flameTypeArray);
comboBox.selectedIndex = 0;
comboBox.name = String(i);
comboBox.addEventListener(Event.SELECT, onChangeFlameType);
comboBox.width = 70;
flameTypeComboBoxArray.push(comboBox);
}
colorWindow = new Window(this, 10, 10, "Color Map Editor");
colorWindow.hasMinimizeButton = true;
colorWindow.hasCloseButton = true;
colorWindow.width = 284;
colorWindow.height = 140;
colorWindow.alpha = 0.7;
colorWindow.name = "color";
colorWindow.addEventListener(Event.CLOSE, onWindowClose);
var button:PushButton;
var shape:Sprite;
var color:uint;
for (i = 0; i < colorMap.length; i += 1)
{
button = new PushButton(colorWindow, 10 + i * 8, 10 + debugOffset, "", onColorMapButtonClick);
button.width = 8;
button.height = 50;
button.name = String(i);
//Style.BACKGROUND = int(colorMap[i][1] * 255) << 16 | int(colorMap[i][2] * 255) << 16 | int(colorMap[i][3] * 255);
//button.draw();
color = int(colorMap[i][1] * 255) << 16 | int(colorMap[i][2] * 255) << 8 | int(colorMap[i][3] * 255);
shape = new Sprite();
shape.graphics.beginFill(color);
shape.graphics.drawRect(0, 0, 8, 50);
shape.graphics.endFill();
shape.mouseEnabled = false;
shape.mouseChildren = false;
button.addChild(shape);
colorMapButtonArray.push(button);
colorMapShapeArray.push(shape);
}
colorSelectShapeYellow = new Shape();
colorSelectShapeYellow.graphics.beginFill(0xffff00);
colorSelectShapeYellow.graphics.moveTo(4, 0);
colorSelectShapeYellow.graphics.lineTo(0, 8);
colorSelectShapeYellow.graphics.lineTo(8, 8);
colorSelectShapeYellow.graphics.lineTo(4, 0);
colorSelectShapeYellow.graphics.endFill();
colorSelectShapeYellow.x = 10 + colorSelectShapeYellowIndex * 8;
colorSelectShapeYellow.y = 55 + debugOffset;
colorWindow.addChild(colorSelectShapeYellow);
colorSelectShapeGreen = new Shape();
colorSelectShapeGreen.graphics.beginFill(0x00ff00);
colorSelectShapeGreen.graphics.moveTo(4, 0);
colorSelectShapeGreen.graphics.lineTo(0, 8);
colorSelectShapeGreen.graphics.lineTo(8, 8);
colorSelectShapeGreen.graphics.lineTo(4, 0);
colorSelectShapeGreen.graphics.endFill();
colorSelectShapeGreen.x = 10 + colorSelectShapeGreenIndex * 8;
colorSelectShapeGreen.y = 55 + debugOffset;
colorWindow.addChild(colorSelectShapeGreen);
colorSelectYellowRadioButton = new RadioButton(colorWindow, 10, 70 + debugOffset, "Yellow", true);
colorSelectYellowRadioButton.groupName = "ColorSelect";
colorSelectGreenRadioButton = new RadioButton(colorWindow, colorSelectYellowRadioButton.x + colorSelectYellowRadioButton.width + 10, colorSelectYellowRadioButton.y, "Green", false);
colorSelectGreenRadioButton.groupName = "ColorSelect";
colorSelectColorChooser = new ColorChooser(colorWindow, colorSelectYellowRadioButton.x, colorSelectYellowRadioButton.y + colorSelectYellowRadioButton.height + 10, 0xff0000, onColorSelectColorChoose);
colorSelectColorChooser.usePopup = true;
var gradientButton:PushButton = new PushButton(colorWindow, 284 - 110, colorSelectYellowRadioButton.y, "Gradient", onColorGradient);
var randomizeButton:PushButton = new PushButton(colorWindow, gradientButton.x, gradientButton.y + gradientButton.height, "Randomize", onRandomize);
triangleWindow = new Window(this, 10, flameWindow.y - 250, "Triangle Editor");
triangleWindow.hasMinimizeButton = true;
triangleWindow.hasCloseButton = true;
triangleWindow.addEventListener(Event.CLOSE, onWindowClose);
triangleWindow.alpha = 0.7;
triangleWindow.width = 220;
triangleWindow.height = 240;
triangleWindow.name = "triangle";
//draw Coordinates
var plane:Shape = new Shape();
plane.graphics.beginFill(0x002900);
plane.graphics.drawRect(0, debugOffset, 220, 220);
plane.graphics.endFill();
for (i = 0; i < 21; i += 1)
{
if (i % 5 == 0)
{
plane.graphics.lineStyle(2, 0xffffff);
}
else
{
plane.graphics.lineStyle(1, 0xcccccc);
}
plane.graphics.moveTo(10, 10 + i * 10 + debugOffset);
plane.graphics.lineTo(210, 10 + i * 10 + debugOffset);
plane.graphics.moveTo(10 + i * 10, 10 + debugOffset);
plane.graphics.lineTo(10 + i * 10, 210 + debugOffset);
}
var planeBitmapData:BitmapData = new BitmapData(220, 220, false, 0);
var planeBitmap:Bitmap = new Bitmap(planeBitmapData);
planeBitmap.y = debugOffset;
planeBitmapData.draw(plane, new Matrix(1, 0, 0, 1, 0, -debugOffset));
triangleWindow.addChild(planeBitmap);
triangleSpriteArray = [];
triangleSprite1 = new Sprite();
triangleSprite1.y = debugOffset;
triangleSprite1.name = "plane00";
triangleSprite1.addEventListener(MouseEvent.MOUSE_DOWN, onTriangleMouseDown, true);
triangleSprite1.addEventListener(MouseEvent.MOUSE_UP, onTriangleMouseUp, true);
triangleSpriteArray.push(triangleSprite1);
triangleSprite2 = new Sprite();
triangleSprite2.y = debugOffset;
triangleSprite2.name = "plane01";
triangleSprite2.addEventListener(MouseEvent.MOUSE_DOWN, onTriangleMouseDown, true);
triangleSprite2.addEventListener(MouseEvent.MOUSE_UP, onTriangleMouseUp, true);
triangleSpriteArray.push(triangleSprite2);
triangleSprite3 = new Sprite();
triangleSprite3.y = debugOffset;
triangleSprite3.name = "plane02";
triangleSprite3.addEventListener(MouseEvent.MOUSE_DOWN, onTriangleMouseDown, true);
triangleSprite3.addEventListener(MouseEvent.MOUSE_UP, onTriangleMouseUp, true);
triangleSpriteArray.push(triangleSprite3);
triangleSprite4 = new Sprite();
triangleSprite4.y = debugOffset;
triangleSprite4.name = "plane03";
triangleSprite4.addEventListener(MouseEvent.MOUSE_DOWN, onTriangleMouseDown, true);
triangleSprite4.addEventListener(MouseEvent.MOUSE_UP, onTriangleMouseUp, true);
triangleSpriteArray.push(triangleSprite4);
//make 12 sprite... for 4 triangle's point
trianglePointSpriteArray = [];
var trianglePoint:Sprite = new Sprite();
triangleSprite1.addChild(trianglePoint);
trianglePoint.name = "point00";
//trianglePoint.addEventListener(MouseEvent.MOUSE_DOWN, onTriangleMouseDown);
//trianglePoint.addEventListener(MouseEvent.MOUSE_UP, onTriangleMouseUp);
trianglePointSpriteArray.push(trianglePoint);
trianglePoint = new Sprite();
triangleSprite1.addChild(trianglePoint);
trianglePoint.name = "point01";
trianglePointSpriteArray.push(trianglePoint);
trianglePoint = new Sprite();
triangleSprite1.addChild(trianglePoint);
trianglePoint.name = "point02";
trianglePointSpriteArray.push(trianglePoint);
trianglePoint = new Sprite();
triangleSprite2.addChild(trianglePoint);
trianglePoint.name = "point03";
trianglePointSpriteArray.push(trianglePoint);
trianglePoint = new Sprite();
triangleSprite2.addChild(trianglePoint);
trianglePoint.name = "point04";
trianglePointSpriteArray.push(trianglePoint);
trianglePoint = new Sprite();
triangleSprite2.addChild(trianglePoint);
trianglePoint.name = "point05";
trianglePointSpriteArray.push(trianglePoint);
trianglePoint = new Sprite();
triangleSprite3.addChild(trianglePoint);
trianglePoint.name = "point06";
trianglePointSpriteArray.push(trianglePoint);
trianglePoint = new Sprite();
triangleSprite3.addChild(trianglePoint);
trianglePoint.name = "point07";
trianglePointSpriteArray.push(trianglePoint);
trianglePoint = new Sprite();
triangleSprite3.addChild(trianglePoint);
trianglePoint.name = "point08";
trianglePointSpriteArray.push(trianglePoint);
trianglePoint = new Sprite();
triangleSprite4.addChild(trianglePoint);
trianglePoint.name = "point09";
trianglePointSpriteArray.push(trianglePoint);
trianglePoint = new Sprite();
triangleSprite4.addChild(trianglePoint);
trianglePoint.name = "point10";
trianglePointSpriteArray.push(trianglePoint);
trianglePoint = new Sprite();
triangleSprite4.addChild(trianglePoint);
trianglePoint.name = "point11";
trianglePointSpriteArray.push(trianglePoint);
triangleWindow.addChild(triangleSprite1);
triangleWindow.addChild(triangleSprite2);
triangleWindow.addChild(triangleSprite3);
triangleWindow.addChild(triangleSprite4);
settingsMiniButton = new PushButton(this, 465 - 20, 0, "S", onMiniButtonClick);
settingsMiniButton.width = 20;
settingsMiniButton.height = 20;
settingsMiniButton.name = "setting";
settingsMiniButton.alpha = 0.7;
settingsMiniButton.visible = false;
colorMiniButton = new PushButton(this, 465 - 20, 20, "C", onMiniButtonClick);
colorMiniButton.width = 20;
colorMiniButton.height = 20;
colorMiniButton.name = "color";
colorMiniButton.alpha = 0.7;
colorMiniButton.visible = false;
triangleMiniButton = new PushButton(this, 465 - 20, 40, "T", onMiniButtonClick);
triangleMiniButton.width = 20;
triangleMiniButton.height = 20;
triangleMiniButton.name = "triangle";
triangleMiniButton.alpha = 0.7;
triangleMiniButton.visible = false;
flameMiniButton = new PushButton(this, 465 - 20, 60, "F", onMiniButtonClick);
flameMiniButton.width = 20;
flameMiniButton.height = 20;
flameMiniButton.name = "flame";
flameMiniButton.alpha = 0.7;
flameMiniButton.visible = false;
onResetAll();
}
private function onTriangleMouseDown(e:MouseEvent):void
{
if (isDragging == false)
{
isDragging = true;
prevDragX = triangleWindow.mouseX;
prevDragY = triangleWindow.mouseY;
e.target.startDrag();
e.target.parent.setChildIndex(e.target, e.target.parent.numChildren - 1);
}
}
private function onTriangleMouseUp(e:MouseEvent):void
{
if (isDragging == true)
{
isDragging = false;
e.target.stopDrag();
var nowX:Number = triangleWindow.mouseX;
var nowY:Number = triangleWindow.mouseY;
var index:int = parseInt(e.target.name.substr(5, 2));
var type:String = e.target.name.substr(0, 5);
var i:int, j:int;
if (type == "point")
{
i = index / 3;
j = (index % 3) * 2;
//redraw triangle
table[i][j] += (nowX - prevDragX) / 50;
table[i][j + 1] += (nowY - prevDragY) / 50;
var triangle:Sprite = triangleSpriteArray[i];
triangle.graphics.clear();
triangle.graphics.lineStyle(0, triangleColors[i]);
triangle.graphics.beginFill(triangleColors[i], 0.5);
triangle.graphics.moveTo(table[i][0] * 50 + 110, table[i][1] * 50 + 110);
triangle.graphics.lineTo(table[i][2] * 50 + 110, table[i][3] * 50 + 110);
triangle.graphics.lineTo(table[i][4] * 50 + 110, table[i][5] * 50 + 110);
triangle.graphics.lineTo(table[i][0] * 50 + 110, table[i][1] * 50 + 110);
inputTextArray[i * 7 + j].text = table[i][j];
inputTextArray[i * 7 + j + 1].text = table[i][j + 1];
}
else //type == "plane"
{
i = index;
for (j = 0; j < 3; j += 1)
{
table[i][j * 2] += (nowX - prevDragX) / 50;
table[i][j * 2 + 1] += (nowY - prevDragY) / 50;
inputTextArray[i * 7 + j * 2].text = table[i][j * 2];
inputTextArray[i * 7 + j * 2 + 1].text = table[i][j * 2 + 1];
}
}
onRedraw();
}
}
private function drawTriangle():void
{
var i:int, j:int;
var triangle:Sprite;
var trianglePoint:Sprite;
for (i = 0; i < 4; i += 1)
{
triangle = triangleSpriteArray[i];
triangle.x = 0;
triangle.y = debugOffset;
triangle.graphics.clear();
triangle.graphics.lineStyle(0, triangleColors[i]);
triangle.graphics.beginFill(triangleColors[i], 0.5);
triangle.graphics.moveTo(table[i][0] * 50 + 110, table[i][1] * 50 + 110);
triangle.graphics.lineTo(table[i][2] * 50 + 110, table[i][3] * 50 + 110);
triangle.graphics.lineTo(table[i][4] * 50 + 110, table[i][5] * 50 + 110);
triangle.graphics.lineTo(table[i][0] * 50 + 110, table[i][1] * 50 + 110);
triangle.graphics.endFill();
for (j = 0; j < 3; j += 1)
{
trianglePoint = trianglePointSpriteArray[i * 3 + j];
trianglePoint.x = 0;
trianglePoint.y = 0;
trianglePoint.graphics.clear();
trianglePoint.graphics.beginFill(triangleColors[i]);
trianglePoint.graphics.drawCircle(table[i][j * 2] * 50 + 110, table[i][j * 2 +1] * 50 + 110, 5);
trianglePoint.graphics.endFill();
}
}
}
private function onMiniButtonClick(e:Event):void
{
switch(e.target.name)
{
case "setting":
settingsMiniButton.visible = false;
settingWindow.visible = true;
break;
case "color":
colorMiniButton.visible = false;
colorWindow.visible = true;
break;
case "triangle":
triangleMiniButton.visible = false;
triangleWindow.visible = true;
break;
case "flame":
flameMiniButton.visible = false;
flameWindow.visible = true;
break;
}
}
private function onWindowClose(e:Event):void
{
switch(e.target.name)
{
case "setting":
settingsMiniButton.visible = true;
settingWindow.visible = false;
break;
case "color":
colorMiniButton.visible = true;
colorWindow.visible = false;
break;
case "triangle":
triangleMiniButton.visible = true;
triangleWindow.visible = false;
break;
case "flame":
flameMiniButton.visible = true;
flameWindow.visible = false;
break;
}
}
private function onRandomize(e:Event):void
{
var min:int, max:int;
var i:int;
var color:uint;
if (colorSelectShapeYellowIndex != colorSelectShapeGreenIndex) //index same -> no gradient..
{
if (colorSelectShapeYellowIndex < colorSelectShapeGreenIndex)
{
min = colorSelectShapeYellowIndex;
max = colorSelectShapeGreenIndex;
}
else
{
min = colorSelectShapeGreenIndex;
max = colorSelectShapeYellowIndex;
}
for (i = min; i < max + 1; i += 1)
{
//randomize - max 20%
colorMap[i][1] += Math.random() * colorMap[i][1] * 0.2 - colorMap[i][1] * 0.1;
colorMap[i][1] = colorMap[i][1] < 0 ? 0 : ( colorMap[i][1] > 1 ? 1 : colorMap[i][1] );
colorMap[i][2] += Math.random() * colorMap[i][2] * 0.2 - colorMap[i][2] * 0.1;
colorMap[i][2] = colorMap[i][2] < 0 ? 0 : ( colorMap[i][2] > 1 ? 1 : colorMap[i][2] );
colorMap[i][3] += Math.random() * colorMap[i][3] * 0.2 - colorMap[i][3] * 0.1;
colorMap[i][3] = colorMap[i][3] < 0 ? 0 : ( colorMap[i][3] > 1 ? 1 : colorMap[i][3] );
color = int(colorMap[i][1] * 255) << 16 | int(colorMap[i][2] * 255) << 8 | int(colorMap[i][3] * 255);
colorMapShapeArray[i].graphics.beginFill(color);
colorMapShapeArray[i].graphics.drawRect(0, 0, 8, 50);
colorMapShapeArray[i].graphics.endFill();
}
}
}
private function onColorGradient(e:Event):void
{
var min:int, max:int;
var i:int;
var color:uint;
if (colorSelectShapeYellowIndex != colorSelectShapeGreenIndex) //index same -> no gradient..
{
if (colorSelectShapeYellowIndex < colorSelectShapeGreenIndex)
{
min = colorSelectShapeYellowIndex;
max = colorSelectShapeGreenIndex;
}
else
{
min = colorSelectShapeGreenIndex;
max = colorSelectShapeYellowIndex;
}
for (i = min + 1; i < max; i += 1)
{
if (colorMap[min][1] < colorMap[max][1])
{
colorMap[i][1] = colorMap[min][1] + (i - min) / (max - min) * Math.abs(colorMap[max][1] - colorMap[min][1]);
}
else
{
colorMap[i][1] = colorMap[min][1] - (i - min) / (max - min) * Math.abs(colorMap[max][1] - colorMap[min][1]);
}
if (colorMap[min][2] < colorMap[max][2])
{
colorMap[i][2] = colorMap[min][2] + (i - min) / (max - min) * Math.abs(colorMap[max][2] - colorMap[min][2]);
}
else
{
colorMap[i][2] = colorMap[min][2] - (i - min) / (max - min) * Math.abs(colorMap[max][2] - colorMap[min][2]);
}
if (colorMap[min][3] < colorMap[max][3])
{
colorMap[i][3] = colorMap[min][3] + (i - min) / (max - min) * Math.abs(colorMap[max][3] - colorMap[min][3]);
}
else
{
colorMap[i][3] = colorMap[min][3] - (i - min) / (max - min) * Math.abs(colorMap[max][3] - colorMap[min][3]);
}
color = int(colorMap[i][1] * 255) << 16 | int(colorMap[i][2] * 255) << 8 | int(colorMap[i][3] * 255);
colorMapShapeArray[i].graphics.beginFill(color);
colorMapShapeArray[i].graphics.drawRect(0, 0, 8, 50);
colorMapShapeArray[i].graphics.endFill();
}
}
}
private function onColorSelectColorChoose(e:Event):void
{
var index:int;
var color:uint = e.target.value;
if (colorSelectYellowRadioButton.selected == true)
{
index = colorSelectShapeYellowIndex;
}
else
{
index = colorSelectShapeGreenIndex;
}
colorMapShapeArray[index].graphics.beginFill(color);
colorMapShapeArray[index].graphics.drawRect(0, 0, 8, 50);
colorMapShapeArray[index].graphics.endFill();
colorMap[index][1] = ((color >> 16) & 0xff) / 255.0;
colorMap[index][2] = ((color >> 8) & 0xff) / 255.0;
colorMap[index][3] = (color & 0xff) / 255.0;
}
private function onColorMapButtonClick(e:Event = null):void
{
var index:int = parseInt(e.target.name);
var color:uint;
if (colorSelectYellowRadioButton.selected == true)
{
colorSelectShapeYellowIndex = index;
colorSelectShapeYellow.x = 10 + colorSelectShapeYellowIndex * 8;
}
else
{
colorSelectShapeGreenIndex = index;
colorSelectShapeGreen.x = 10 + colorSelectShapeGreenIndex * 8;
}
color = int(colorMap[index][1] * 255) << 16 | int(colorMap[index][2] * 255) << 8 | int(colorMap[index][3] * 255);
colorSelectColorChooser.value = color;
}
private function onAntiAliasing(e:Event = null):void
{
if (hasEventListener(Event.ENTER_FRAME) == true)
{
removeEventListener(Event.ENTER_FRAME, onLoop);
drawMoreButton.selected = false;
}
var i:int, j:int;
var r:int, g:int, b:int, a:int;
var color:uint;
var colorNum:int;
antiBitmapData.lock();
_bitmapData.lock();
for (i = 0; i < 465; i += 1)
{
for (j = 0; j < 465; j += 1)
{
color = _bitmapData.getPixel32(i, j);
a = color >> 24 & 0xff;
r = color >> 16 & 0xff;
g = color >> 8 & 0xff;
b = color & 0xff;
colorNum = 1;
if (i > 0)
{
color = _bitmapData.getPixel32(i - 1, j);
a += color >> 24 & 0xff;
r += color >> 16 & 0xff;
g += color >> 8 & 0xff;
b += color & 0xff;
colorNum += 1;
}
if (i < 464)
{
color = _bitmapData.getPixel32(i + 1, j);
a += color >> 24 & 0xff;
r += color >> 16 & 0xff;
g += color >> 8 & 0xff;
b += color & 0xff;
colorNum += 1;
}
if (j > 0)
{
color = _bitmapData.getPixel32(i, j - 1);
a += color >> 24 & 0xff;
r += color >> 16 & 0xff;
g += color >> 8 & 0xff;
b += color & 0xff;
colorNum += 1;
}
if (j < 464)
{
color = _bitmapData.getPixel32(i, j + 1);
a += color >> 24 & 0xff;
r += color >> 16 & 0xff;
g += color >> 8 & 0xff;
b += color & 0xff;
colorNum += 1;
}
r /= colorNum;
g /= colorNum;
b /= colorNum;
a /= colorNum;
color = a << 24 | r << 16 | g << 8 | b;
//color = r << 16 | g << 8 | b;
antiBitmapData.setPixel32(i, j, color);
//antiBitmapData.setPixel(i, j, color);
}
}
_bitmapData.unlock();
antiBitmapData.unlock();
_bitmapData.draw(antiBitmapData);
}
private function onDrawMore(e:Event):void
{
if (e.target.selected == true)
{
addEventListener(Event.ENTER_FRAME, onLoop);
}
else
{
removeEventListener(Event.ENTER_FRAME, onLoop);
}
}
private function drawIter(iterFrame:int):void
{
var i:int;
var t:int;
var px:int, py:int;
var r:Number;
var theta:Number;
var color:Number = Math.random();
var p0:Number, p1:Number; // for 12-Ex
var omega:Number; // for 13-Julia
for (i = 0; i < iterFrame; i += 1) //note! iter -> oneFrameIter
{
t = getRandomTransform();
npx = cpx * table[t][0] + cpy * table[t][1] + table[t][4];
npy = cpx * table[t][2] + cpy * table[t][3] + table[t][5];
color = (color * table[t][0] + color * table[t][1] + table[t][4] + color * table[t][2] + color * table[t][3] + table[t][5]) / 2;
switch(flameType[t])
{
case 0: //linear
cpx = npx;
cpy = npy;
break;
case 1: //sinusoidal
cpx = Math.sin(npx);
cpy = Math.sin(npy);
break;
case 2: //spherical
r = 1 / (npx * npx + npy * npy);
cpx = npx * r;
cpy = npy * r;
break;
case 3: //swirl
r = npx * npx + npy * npy;
cpx = npx * Math.sin(r) - npy * Math.cos(r);
cpy = npx * Math.cos(r) - npy * Math.sin(r);
break;
case 4: //Horseshoe
r = 1 / Math.sqrt(npx * npx + npy * npy);
cpx = r * (npx - npy) * (npx + npy);
cpy = r * 2 * npx * npy;
break;
case 5: //Polar
r = Math.sqrt(npx * npx + npy * npy);
cpx = Math.atan2(npy, npx) / Math.PI;
cpy = r - 1;
break;
case 6: //Handkerchief
r = Math.sqrt(npx * npx + npy * npy);
theta = Math.atan2(npy, npx);
cpx = r * Math.sin(theta + r);
cpy = r * Math.cos(theta - r);
break;
case 7: //Heart
r = Math.sqrt(npx * npx + npy * npy);
theta = Math.atan2(npy, npx);
cpx = r * Math.sin(theta * r);
cpy = -1 * r * Math.cos(theta * r);
break;
case 8: //Disc
r = Math.sqrt(npx * npx + npy * npy);
theta = Math.atan2(npy, npx) / Math.PI;
cpx = theta * Math.sin(Math.PI * r);
cpy = theta * Math.cos(Math.PI * r);
break;
case 9: //Spiral
r = Math.sqrt(npx * npx + npy * npy);
theta = Math.atan2(npy, npx);
cpx = 1 / r * (Math.cos(theta) + Math.sin(r));
cpy = 1 / r * (Math.sin(theta) - Math.cos(r));
break;
case 10: //Hyperbolic
r = Math.sqrt(npx * npx + npy * npy);
theta = Math.atan2(npy, npx);
cpx = 1 / r * Math.sin(theta);
cpy = r * Math.cos(theta);
break;
case 11: //Diamond
r = Math.sqrt(npx * npx + npy * npy);
theta = Math.atan2(npy, npx);
cpx = Math.sin(theta) * Math.cos(r);
cpy = Math.cos(theta) * Math.sin(r);
break;
case 12: //Ex
r = Math.sqrt(npx * npx + npy * npy);
theta = Math.atan2(npy, npx);
p0 = Math.sin(theta + r);
p0 = p0 * p0 * p0;
p1 = Math.cos(theta - r);
p1 = p1 * p1 * p1;
cpx = r * (p0 + p1);
cpy = r * (p0 - p1);
break;
case 13: //Julia
r = Math.sqrt(Math.sqrt(npx * npx + npy * npy));
theta = Math.atan2(npy, npx);
omega = Math.random() < 0.5 ? 0 : Math.PI;
cpx = r * Math.cos(theta / 2 + omega);
cpy = r * Math.sin(theta / 2 + omega);
break;
case 14: //Fisheye (originally 16)
r = 2 / (Math.sqrt(Math.sqrt(npx * npx + npy * npy)) + 1);
cpx = r * npy;
cpy = r * npx;
break;
case 15: //Eyefish (originally 27)
r = 2 / (Math.sqrt(Math.sqrt(npx * npx + npy * npy)) + 1);
cpx = r * npx;
cpy = r * npy;
break;
case 16: //Bubble (originally 28)
r = 4 / (npx * npx + npy * npy + 4);
cpx = r * npx;
cpy = r * npy;
break;
}
px = cpx * magnitude + 465 / 2;
py = cpy * magnitude + 465 / 2;
if (px >= 0 && px < 465 && py >= 0 && py < 465)
{
points[px][py] += 1;
colors[px][py] = (colors[px][py] + color) / 2;
}
}
}
private function onLoop(e:Event):void
{
drawIter(oneFrameIter);
drawPointVector();
nowIter += oneFrameIter;
nowIterLabel.text = "Now Iter: " + String(nowIter);
}
private function onChangeFlameType(e:Event):void
{
flameType[parseInt(e.target.name)] = e.target.selectedIndex;
//trace(flameType);
}
private function onChangeIter(e:Event = null):void
{
iter = parseInt(e.target.text);
}
private function onRedraw(e:Event = null):void
{
_bitmapData.fillRect(_bitmapData.rect, 0x00ffffff);
cpx = Math.random();
cpy = Math.random();
var i:int;
//initialize points Vector
for (i = 0; i < 465; i += 1)
{
points[i] = new Vector.<Number>(465);
colors[i] = new Vector.<Number>(465);
}
var t:int;
for (i = 0; i < 50; i += 1) //first 50 points are discarded
{
t = getRandomTransform();
npx = cpx * table[t][0] + cpy * table[t][1] + table[t][4];
npy = cpx * table[t][2] + cpy * table[t][3] + table[t][5];
cpx = npx;
cpy = npy;
}
drawIter(iter);
drawPointVector();
nowIter = iter;
nowIterLabel.text = "Now Iter: " + String(nowIter);
}
private function resetFlameType():void
{
var i:int;
for (i = 0; i < 4; i += 1)
{
flameType[i] = Math.random() * flameTypeArray.length;
flameTypeComboBoxArray[i].selectedIndex = flameType[i];
}
}
private function resetTable():void
{
// init Table
var i:int, j:int;
var sum:Number = 1;
var rand:Number;
for (i = 0; i < table.length; i += 1)
{
for (j = 0; j < 6; j += 1)
{
table[i][j] = Math.random() * 2 - 1;
inputTextArray[i * 7 + j].text = table[i][j];
}
rand = Math.random() * sum;
if (sum - rand < 0)
{
table[i][6] = sum;
sum = 0;
}
else
{
table[i][6] = rand;
sum -= rand;
}
inputTextArray[i * 7 + 6].text = table[i][j];
//trace(table[i]);
}
}
private function onResetAll(e:Event = null):void
{
resetFlameType();
resetTable();
onRedraw();
drawTriangle();
nowIter = iter;
nowIterLabel.text = "Now Iter: " + String(nowIter);
}
private function drawPointVector():void
{
var i:int;
var j:int;
var max:Number = -int.MAX_VALUE;
var min:Number = int.MAX_VALUE;
var color:uint;
//var oneColor:uint;
var scalar:Number;
var s:int;
var r:uint;
var g:uint;
var b:uint;
var len:int;
for (i = 0; i < 465; i += 1)
{
for (j = 0; j < 465; j += 1)
{
//points[i][j] = (points[i][j] != 0 ? Math.log(points[i][j]) : 0);
points[i][j] = (points[i][j] > 0 ? Math.log(points[i][j]) : 0);
//if (max < points[i][j])
//{
//max = points[i][j];
//}
if (max < colors[i][j])
{
max = colors[i][j];
}
if (min > colors[i][j])
{
min = colors[i][j];
}
}
}
//trace(max, min);
_bitmapData.lock();
len = colorMap.length;
for (i = 0; i < 465; i += 1)
{
for (j = 0; j < 465; j += 1)
{
if (points[i][j] != 0)
{
//oneColor = 255 * points[i][j] / max;
//color = oneColor << 16 | oneColor << 8 | oneColor;
//scalar = points[i][j] / max * 1.0;
scalar = (colors[i][j]-min) / (max-min) * 1.0;
for (s = 0; s < len; s += 1)
{
if (colorMap[s][0] > scalar)
{
break;
}
}
s -= 1;
//trace(s);
r = Math.pow(colorMap[s][1], 1/gamma) * 255;
g = Math.pow(colorMap[s][2], 1/gamma) * 255;
b = Math.pow(colorMap[s][3], 1/gamma) * 255;
//r = (points[i][j] / max * Math.abs(colorMap[0][0] - colorMap[1][0]) + colorMap[0][0]) * 255;
//g = (points[i][j] / max * Math.abs(colorMap[0][1] - colorMap[1][1]) + colorMap[0][1]) * 255;
//b = (points[i][j] / max * Math.abs(colorMap[0][2] - colorMap[1][2]) + colorMap[0][2]) * 255;
color = r << 16 | g << 8 | b;
colT.color = color;
mat = new Matrix();
mat.translate(i, j);
_bitmapData.draw(_shape, mat, colT, "add");
//_bitmapData.setPixel(i, j, color);
}
}
}
_bitmapData.unlock();
}
private function getRandomTransform():int
{
var randomNumber:Number = Math.random();
var i:int;
var row:Array;
for (i = 0; i < table.length; i += 1)
{
if (randomNumber <= table[i][6])
{
return i;
}
randomNumber -= table[i][6];
}
return table.length - 1;
}
}
}