/**
* Copyright Aquioux ( http://wonderfl.net/user/Aquioux )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/CmWU
*/
package {
import com.bit101.components.Label;
import com.bit101.components.PushButton;
import flash.display.Sprite;
import flash.events.Event;
import flash.geom.ColorTransform;
[SWF(width = "465", height = "465", frameRate = "60", backgroundColor = "#000000")]
/**
* 2変数関数 Two variable function
* @author YOSHIDA, Akio(Aquioux)
*/
public class Main extends Sprite {
private var viewer_:Viewer; // ビューアクラス
private var figure_:Coordinate;
private var indices_:Vector.<Vector.<int>>; // 線を引くためのインデックス
private var prevButton_:PushButton;
private var label_:Label;
private var fade1_:ColorTransform = new ColorTransform(0.5, 0.9, 1, 0.95); // 青
private var fade2_:ColorTransform = new ColorTransform(1, 0.93, 0.5, 0.95); // 黄
private var fade3_:ColorTransform = new ColorTransform(1, 0.5, 0.25, 0.95); // 赤
private var fade4_:ColorTransform = new ColorTransform(0.25, 1, 0.5, 0.95); // 緑
// コンストラクタ
public function Main() {
// ステージサイズ
var sw:int = stage.stageWidth;
var sh:int = stage.stageHeight;
// プロジェクションクラス設定
Projection.offsetX = sw >> 1;
Projection.offsetY = sh >> 1;
Projection.offsetZ = 150;
// マウス挙動クラス生成
MouseBehavior.setup(this.stage);
// ビューアクラス作成
viewer_ = new Viewer(sw, sh);
addChild(viewer_);
// ボタン
var buttonWidth:int = 58;
var button0:PushButton = new PushButton(this, buttonWidth * 0, 0, "saddle1", button0Action);
button0.width = buttonWidth;
addChild(button0);
var button1:PushButton = new PushButton(this, buttonWidth * 1, 0, "saddle2", button1Action);
button1.width = buttonWidth;
addChild(button1);
var button2:PushButton = new PushButton(this, buttonWidth * 2, 0, "parabola", button2Action);
button2.width = buttonWidth;
addChild(button2);
var button3:PushButton = new PushButton(this, buttonWidth * 3, 0, "ripple", button3Action);
button3.width = buttonWidth;
addChild(button3);
var button4:PushButton = new PushButton(this, buttonWidth * 4, 0, "unevenness", button4Action);
button4.width = buttonWidth;
addChild(button4);
var button5:PushButton = new PushButton(this, buttonWidth * 5, 0, "gaussian1", button5Action);
button5.width = buttonWidth;
addChild(button5);
var button6:PushButton = new PushButton(this, buttonWidth * 6, 0, "gaussian2", button6Action);
button6.width = buttonWidth;
addChild(button6);
var button7:PushButton = new PushButton(this, buttonWidth * 7, 0, "gaussian3", button7Action);
button7.width = buttonWidth;
addChild(button7);
// ラベル
var labelHeight:int = 16;
label_ = new Label(this, 0, sh - labelHeight, "");
label_.height = labelHeight;
addChild(label_);
// 最初の状態
button0Action(null);
buttonCommonAction(button0);
// ENTER_FRAME
addEventListener(Event.ENTER_FRAME, update);
}
// 更新
private function update(event:Event):void {
MouseBehavior.update();
viewer_.update(Projection.update(MouseBehavior.moveX, MouseBehavior.moveY), indices_);
}
// ボタンアクション
private function button0Action(event:Event):void {
figure_ = new Saddle1();
label_.text = "Saddle1 : z = a * x * y, a = 1";
if (event) buttonCommonAction(PushButton(event.target));
}
private function button1Action(event:Event):void {
figure_ = new Saddle2();
label_.text = "Saddle2 : z = a * (x^2 - y^2), a = 0.5";
if (event) buttonCommonAction(PushButton(event.target));
}
private function button2Action(event:Event):void {
figure_ = new Parabola();
label_.text = "Parabola : z = a * (x^2 + y^2), a = 0.5";
if (event) buttonCommonAction(PushButton(event.target));
}
private function button3Action(event:Event):void {
figure_ = new Ripple();
label_.text = "Ripple : z = a * cos(sqrt(x^2 + y^2)), a = 1";
if (event) buttonCommonAction(PushButton(event.target));
}
private function button4Action(event:Event):void {
figure_ = new Unevenness();
label_.text = "Unevenness : a * sin(x) * sin(y), a = 1";
if (event) buttonCommonAction(PushButton(event.target));
}
private function button5Action(event:Event):void {
figure_ = new Gaussian1();
label_.text = "Gaussian1 : a * exp(-(x^2 + y^2) / b), a = 3, b = 2";
if (event) buttonCommonAction(PushButton(event.target));
}
private function button6Action(event:Event):void {
figure_ = new Gaussian2();
label_.text = "Gaussian2 : a * x * exp(-(x^2 + y^2) / b), a = 3, b = 2";
if (event) buttonCommonAction(PushButton(event.target));
}
private function button7Action(event:Event):void {
figure_ = new Gaussian3();
label_.text = "Gaussian3 : a * (x * y) * exp(-(x^2 + y^2) / b), a = 5, b = 2";
if (event) buttonCommonAction(PushButton(event.target));
}
// 全ボタン共通アクション
private function buttonCommonAction(currentButton:PushButton):void {
resetButton(currentButton);
resetFigure();
var rnd:int = Math.random() * 4 >> 0;
switch(rnd) {
case 0: viewer_.fade = fade1_; break;
case 1: viewer_.fade = fade2_; break;
case 2: viewer_.fade = fade3_; break;
case 3: viewer_.fade = fade4_; break;
}
}
// ボタンのリセット
private function resetButton(currentButton:PushButton):void {
if (prevButton_) prevButton_.enabled = true;
currentButton.enabled = false;
prevButton_ = currentButton;
}
// 形状の入れ替え
private function resetFigure():void {
figure_.create();
indices_ = figure_.indices;
Projection.verts = figure_.verts;
}
}
}
//package {
import flash.geom.Matrix3D;
import flash.geom.PerspectiveProjection;
import flash.geom.Utils3D;
import flash.geom.Vector3D;
/**
* 三次元座標を二次元座標に投射する
* @author YOSHIDA, Akio(Aquioux)
*/
/*public*/ class Projection {
/**
* X座標オフセット値
*/
static public function get offsetX():Number { return _offsetX; }
static public function set offsetX(value:Number):void { _offsetX = value; }
static private var _offsetX:Number = 0;
/**
* Y座標オフセット値
*/
static public function get offsetY():Number { return _offsetY; }
static public function set offsetY(value:Number):void { _offsetY = value; }
static private var _offsetY:Number = 0;
/**
* Z座標オフセット値
*/
static public function get offsetZ():Number { return _offsetZ; }
static public function set offsetZ(value:Number):void { _offsetZ = value; }
static private var _offsetZ:Number = 150;
/**
* 頂点の座標(三次元座標)
*/
static public function set verts(verts:Vector.<Number>):void {
// Utils3D.projectVectors 用パラメータ初期化
_verts = verts;
var len:int = _verts.length;
projectedVerts_ = new Vector.<Number>(len * 2 / 3, true);
uvts_ = new Vector.<Number>(len, true);
matrix3D_ = new Matrix3D();
// PerspectiveProjection 生成
projection_ = new PerspectiveProjection();
projection_.fieldOfView = 75; // 値を大きくするほど遠近法の歪みが大きくなる
projectionMatrix3D_ = projection_.toMatrix3D();
// 移動計算用変数の初期化
vx_ = 0.0;
vy_ = 0.0;
}
static private var _verts:Vector.<Number>;
// Utils3D.projectVectors 用パラメータ
static private var matrix3D_:Matrix3D;
static private var projectedVerts_:Vector.<Number>;
static private var uvts_:Vector.<Number>;
// PerspectiveProjection
static private var projection_:PerspectiveProjection;
static private var projectionMatrix3D_:Matrix3D;
// 移動計算用
static private var vx_:Number = 0.0;
static private var vy_:Number = 0.0;
/**
* 更新
* @param moveX 移動量(X軸)
* @param moveY 移動量(Y軸)
*/
static public function update(moveX:Number, moveY:Number):Vector.<Number> {
// 移動量適用
vx_ += moveX;
vy_ -= moveY;
// 移動量を適用した回転の計算と適用
matrix3D_.identity();
matrix3D_.appendRotation(vy_, Vector3D.X_AXIS);
matrix3D_.appendRotation(vx_, Vector3D.Y_AXIS);
matrix3D_.appendTranslation(0, 0, _offsetZ);
matrix3D_.append(projectionMatrix3D_);
Utils3D.projectVectors(matrix3D_, _verts, projectedVerts_, uvts_);
// 回転を適用した座標データを zsort
var len:uint = projectedVerts_.length / 2; // 頂点の数
for (var i:int = 0; i < len; i++) {
var idx:int = i * 2;
projectedVerts_[idx] += _offsetX;
projectedVerts_[idx + 1] += _offsetY;
}
return projectedVerts_;
}
}
//}
//package {
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Graphics;
import flash.display.Shape;
import flash.display.Sprite;
import flash.filters.BitmapFilterQuality;
import flash.filters.BlurFilter;
import flash.geom.ColorTransform;
import flash.geom.Point;
import flash.geom.Rectangle;
/**
* ビューア
* @author YOSHIDA, Akio(Aquioux)
*/
/*public*/ class Viewer extends Sprite {
/**
* 残像の有無
*/
public function set isAfterimage(value:Boolean):void { _isAfterimage = value; }
private var _isAfterimage:Boolean = true;
/**
* 残像生成のための Blur フィルター
*/
public function set blur(value:BlurFilter):void { _blur = value; }
private var _blur:BlurFilter = new BlurFilter(2, 2, BitmapFilterQuality.LOW);
/**
* 残像生成のための ColorTransform
*/
public function set fade(value:ColorTransform):void { _fade = value; }
private var _fade:ColorTransform = new ColorTransform(0.5, 0.9, 1, 0.95);
// 線を描画する Shape
private var drawShape_:Shape;
private var g_:Graphics;
// BitmapData
private var bufferBmd_:BitmapData; // バッファ用
private var viewBmd_:BitmapData; // 表示用
// BitmapData 描画に使う変数
private var rect_:Rectangle;
private const ZERO_POINT:Point = new Point(0, 0);
private const BACK_COLOR:uint = 0x000000;
private const LINE_COLOR:uint = 0xffffff;
/**
* コンストラクタ
*/
public function Viewer(w:int, h:int) {
// 線を描画する Shape
drawShape_ = new Shape();
g_ = drawShape_.graphics;
// BitmapData
bufferBmd_ = new BitmapData(w, h, false, BACK_COLOR);
viewBmd_ = bufferBmd_.clone();
addChild(new Bitmap(viewBmd_));
// BitmapData 描画に使う変数
rect_ = new Rectangle(0, 0, w, h);
// ボタンモード
this.buttonMode = true;
}
/**
* 更新
* @param data 描画データ(X座標,Y座標の2項目を一次元配列で)
*/
public function update(vertices:Vector.<Number>, indices:Vector.<Vector.<int>>):void {
// 線の描画
var isFirst:Boolean = true;
g_.clear();
g_.lineStyle(0, LINE_COLOR, 0.5);
for each (var idxs:Vector.<int> in indices) {
for each (var idx:int in idxs) {
var posX:Number = vertices[idx * 2];
var posY:Number = vertices[idx * 2 + 1];
if (isFirst) {
g_.moveTo(posX, posY);
isFirst = false;
} else {
g_.lineTo(posX, posY);
}
}
isFirst = true;
}
// 表示
if (_isAfterimage) {
// 表示部分
// 前回の状態に現在の状態を被せて描く
bufferBmd_.draw(drawShape_);
// 表示 BitmapData を最新の状態で塗りつぶす
viewBmd_.copyPixels(bufferBmd_, rect_, ZERO_POINT);
// 残像部分
// バッファに対して Blur を適用し、次回のためにぼかす
bufferBmd_.applyFilter(viewBmd_, rect_, ZERO_POINT, _blur);
// バッファに対して ColorTransForm を適用し、次回のためにアルファ値を落とす
bufferBmd_.colorTransform(rect_, _fade);
} else {
// 前フレームの描画をクリア
viewBmd_.fillRect(rect_, BACK_COLOR);
// 表示
viewBmd_.draw(drawShape_);
}
}
}
//}
//package {
/**
* 頂点座標データ生成の抽象クラス
* @author YOSHIDA, Akio
*/
/*public*/ class Coordinate {
/**
* 頂点座標を格納するリスト(X, Y, Z座標を1次元形式で格納)
*/
public function get verts():Vector.<Number> { return _verts; }
protected var _verts:Vector.<Number> = new Vector.<Number>();
/**
* 頂点をどの順番でつなぐかを示すインデックス
*/
public function get indices():Vector.<Vector.<int>> { return _indices; }
protected var _indices:Vector.<Vector.<int>> = new Vector.<Vector.<int>>();
/**
* 座標データ生成(定義はサブクラスで)
*/
public function create():void {
}
}
//}
//package {
/**
* 2変数関数
* z = a * x * y 頂点座標データ生成クラス
* @author YOSHIDA, Akio
*/
/*public*/ class Saddle1 extends Coordinate {
/**
* 頂点座標データ生成
*/
override public function create():void {
const NUM_OF_X:int = 40; // X軸上の置かれる点の数
const NUM_OF_Y:int = 40; // Y軸上の置かれる点の数
const RANGE:Number = 1; // X軸、Y軸上の置かれる点は -RANGE ~ RANGE の範囲
const STEP_X:Number = (RANGE * 2) / (NUM_OF_X - 1);
const STEP_Y:Number = (RANGE * 2) / (NUM_OF_Y - 1);
const SCALE:Number = 50;
var a:Number = 1;
// 座標の生成
for (var y:int = 0; y < NUM_OF_Y; y++) {
var posY:Number = y * STEP_Y - RANGE;
for (var x:int = 0; x < NUM_OF_X; x++) {
var posX:Number = x * STEP_X - RANGE;
var posZ:Number = a * posX * posY;
_verts.push(posX * SCALE, posY * SCALE, posZ * SCALE);
}
}
_verts.fixed = true;
// 線を引くためのインデックスの生成
// X軸方向
var idxs:Vector.<int> = new Vector.<int>();
for (y = 0; y < NUM_OF_Y; y++) {
for (x = 0; x < NUM_OF_X; x++) {
idxs.push(NUM_OF_X * y + x);
}
_indices.push(idxs.concat());
idxs.length = 0;
}
// Y軸方向
for (x = 0; x < NUM_OF_X; x++) {
for (y = 0; y < NUM_OF_Y; y++) {
idxs.push(NUM_OF_X * y + x);
}
_indices.push(idxs.concat());
idxs.length = 0;
}
_indices.fixed = true;
}
}
//}
//package {
/**
* 2変数関数
* z = a * (x^2 - y^2) 頂点座標データ生成クラス
* @author YOSHIDA, Akio
*/
/*public*/ class Saddle2 extends Coordinate {
/**
* 頂点座標データ生成
*/
override public function create():void {
const NUM_OF_X:int = 40; // X軸上の置かれる点の数
const NUM_OF_Y:int = 40; // Y軸上の置かれる点の数
const RANGE:Number = 1; // X軸、Y軸上の置かれる点は -RANGE ~ RANGE の範囲
const STEP_X:Number = (RANGE * 2) / (NUM_OF_X - 1);
const STEP_Y:Number = (RANGE * 2) / (NUM_OF_Y - 1);
const SCALE:Number = 50;
var a:Number = 0.5;
// 座標の生成
for (var y:int = 0; y < NUM_OF_Y; y++) {
var posY:Number = y * STEP_Y - RANGE;
for (var x:int = 0; x < NUM_OF_X; x++) {
var posX:Number = x * STEP_X - RANGE;
var posZ:Number = a * (posX * posX - posY * posY);
_verts.push(posX * SCALE, posY * SCALE, posZ * SCALE);
}
}
_verts.fixed = true;
// 線を引くためのインデックスの生成
// X軸方向
var idxs:Vector.<int> = new Vector.<int>();
for (y = 0; y < NUM_OF_Y; y++) {
for (x = 0; x < NUM_OF_X; x++) {
idxs.push(NUM_OF_X * y + x);
}
_indices.push(idxs.concat());
idxs.length = 0;
}
// Y軸方向
for (x = 0; x < NUM_OF_X; x++) {
for (y = 0; y < NUM_OF_Y; y++) {
idxs.push(NUM_OF_X * y + x);
}
_indices.push(idxs.concat());
idxs.length = 0;
}
_indices.fixed = true;
}
}
//}
//package {
/**
* 2変数関数
* z = a * (x^2 + y^2) 頂点座標データ生成クラス
* @author YOSHIDA, Akio
*/
/*public*/ class Parabola extends Coordinate {
/**
* 頂点座標データ生成
*/
override public function create():void {
const NUM_OF_X:int = 40; // X軸上の置かれる点の数
const NUM_OF_Y:int = 40; // Y軸上の置かれる点の数
const RANGE:Number = 1; // X軸、Y軸上の置かれる点は -RANGE ~ RANGE の範囲
const STEP_X:Number = (RANGE * 2) / (NUM_OF_X - 1);
const STEP_Y:Number = (RANGE * 2) / (NUM_OF_Y - 1);
const SCALE:Number = 50;
var a:Number = 0.5;
// 座標の生成
for (var y:int = 0; y < NUM_OF_Y; y++) {
var posY:Number = y * STEP_Y - RANGE;
for (var x:int = 0; x < NUM_OF_X; x++) {
var posX:Number = x * STEP_X - RANGE;
var posZ:Number = a * (posX * posX + posY * posY);
_verts.push(posX * SCALE, posY * SCALE, posZ * SCALE);
}
}
_verts.fixed = true;
// 線を引くためのインデックスの生成
// X軸方向
var idxs:Vector.<int> = new Vector.<int>();
for (y = 0; y < NUM_OF_Y; y++) {
for (x = 0; x < NUM_OF_X; x++) {
idxs.push(NUM_OF_X * y + x);
}
_indices.push(idxs.concat());
idxs.length = 0;
}
// Y軸方向
for (x = 0; x < NUM_OF_X; x++) {
for (y = 0; y < NUM_OF_Y; y++) {
idxs.push(NUM_OF_X * y + x);
}
_indices.push(idxs.concat());
idxs.length = 0;
}
_indices.fixed = true;
}
}
//}
//package {
/**
* 2変数関数
* z = a * cos(sqrt(x^2 + y^2)) 頂点座標データ生成クラス
* @author YOSHIDA, Akio
*/
/*public*/ class Ripple extends Coordinate {
/**
* 頂点座標データ生成
*/
override public function create():void {
const NUM_OF_X:int = 50; // X軸上の置かれる点の数
const NUM_OF_Y:int = 50; // Y軸上の置かれる点の数
const RANGE:Number = 15; // X軸、Y軸上の置かれる点は -RANGE ~ RANGE の範囲
const STEP_X:Number = (RANGE * 2) / (NUM_OF_X - 1);
const STEP_Y:Number = (RANGE * 2) / (NUM_OF_Y - 1);
const SCALE:Number = 4;
var a:Number = 1;
for (var y:int = 0; y < NUM_OF_Y; y++) {
var posY:Number = y * STEP_Y - RANGE;
for (var x:int = 0; x < NUM_OF_X; x++) {
var posX:Number = x * STEP_X - RANGE;
var posZ:Number = a * Math.cos(Math.sqrt(posX * posX + posY * posY));
_verts.push(posX * SCALE, posY * SCALE, posZ * SCALE);
}
}
_verts.fixed = true;
// 線を引くためのインデックスの生成
// X軸方向
var idxs:Vector.<int> = new Vector.<int>();
for (y = 0; y < NUM_OF_Y; y++) {
for (x = 0; x < NUM_OF_X; x++) {
idxs.push(NUM_OF_X * y + x);
}
_indices.push(idxs.concat());
idxs.length = 0;
}
// Y軸方向
for (x = 0; x < NUM_OF_X; x++) {
for (y = 0; y < NUM_OF_Y; y++) {
idxs.push(NUM_OF_X * y + x);
}
_indices.push(idxs.concat());
idxs.length = 0;
}
_indices.fixed = true;
}
}
//}
//package {
/**
* 2変数関数
* z = a * sin(x) * sin(y) 頂点座標データ生成クラス
* @author YOSHIDA, Akio
*/
/*public*/ class Unevenness extends Coordinate {
/**
* 頂点座標データ生成
*/
override public function create():void {
const NUM_OF_X:int = 50; // X軸上の置かれる点の数
const NUM_OF_Y:int = 50; // Y軸上の置かれる点の数
const RANGE:Number = 8; // X軸、Y軸上の置かれる点は -RANGE ~ RANGE の範囲
const STEP_X:Number = (RANGE * 2) / (NUM_OF_X - 1);
const STEP_Y:Number = (RANGE * 2) / (NUM_OF_Y - 1);
const SCALE:Number = 8;
var a:Number = 1;
for (var y:int = 0; y < NUM_OF_Y; y++) {
var posY:Number = y * STEP_Y - RANGE;
for (var x:int = 0; x < NUM_OF_X; x++) {
var posX:Number = x * STEP_X - RANGE;
var posZ:Number = a * Math.sin(posX) * Math.sin(posY);
_verts.push(posX * SCALE, posY * SCALE, posZ * SCALE);
}
}
_verts.fixed = true;
// 線を引くためのインデックスの生成
// X軸方向
var idxs:Vector.<int> = new Vector.<int>();
for (y = 0; y < NUM_OF_Y; y++) {
for (x = 0; x < NUM_OF_X; x++) {
idxs.push(NUM_OF_X * y + x);
}
_indices.push(idxs.concat());
idxs.length = 0;
}
// Y軸方向
for (x = 0; x < NUM_OF_X; x++) {
for (y = 0; y < NUM_OF_Y; y++) {
idxs.push(NUM_OF_X * y + x);
}
_indices.push(idxs.concat());
idxs.length = 0;
}
_indices.fixed = true;
}
}
//}
//package {
/**
* 2変数関数
* z = a * exp(-(x^2 + y^2) / b) 頂点座標データ生成クラス
* @author YOSHIDA, Akio
*/
/*public*/ class Gaussian1 extends Coordinate {
/**
* 頂点座標データ生成
*/
override public function create():void {
const NUM_OF_X:int = 40; // X軸上の置かれる点の数
const NUM_OF_Y:int = 40; // Y軸上の置かれる点の数
const RANGE:Number = 4; // X軸、Y軸上の置かれる点は -RANGE ~ RANGE の範囲
const STEP_X:Number = (RANGE * 2) / (NUM_OF_X - 1);
const STEP_Y:Number = (RANGE * 2) / (NUM_OF_Y - 1);
const SCALE:Number = 15;
var a:Number = 3;
var b:Number = 2;
for (var y:int = 0; y < NUM_OF_Y; y++) {
var posY:Number = y * STEP_Y - RANGE;
for (var x:int = 0; x < NUM_OF_X; x++) {
var posX:Number = x * STEP_X - RANGE;
var posZ:Number = a * Math.exp((-(posX * posX + posY * posY)) / b);
_verts.push(posX * SCALE, posY * SCALE, posZ * SCALE);
}
}
_verts.fixed = true;
// 線を引くためのインデックスの生成
// X軸方向
var idxs:Vector.<int> = new Vector.<int>();
for (y = 0; y < NUM_OF_Y; y++) {
for (x = 0; x < NUM_OF_X; x++) {
idxs.push(NUM_OF_X * y + x);
}
_indices.push(idxs.concat());
idxs.length = 0;
}
// Y軸方向
for (x = 0; x < NUM_OF_X; x++) {
for (y = 0; y < NUM_OF_Y; y++) {
idxs.push(NUM_OF_X * y + x);
}
_indices.push(idxs.concat());
idxs.length = 0;
}
_indices.fixed = true;
}
}
//}
//package {
/**
* 2変数関数
* z = a * x * exp(-(x^2 + y^2) / b) 頂点座標データ生成クラス
* @author YOSHIDA, Akio
*/
/*public*/ class Gaussian2 extends Coordinate {
/**
* 頂点座標データ生成
*/
override public function create():void {
const NUM_OF_X:int = 40; // X軸上の置かれる点の数
const NUM_OF_Y:int = 40; // Y軸上の置かれる点の数
const RANGE:Number = 4; // X軸、Y軸上の置かれる点は -RANGE ~ RANGE の範囲
const STEP_X:Number = (RANGE * 2) / (NUM_OF_X - 1);
const STEP_Y:Number = (RANGE * 2) / (NUM_OF_Y - 1);
const SCALE:Number = 15;
var a:Number = 3;
var b:Number = 2;
for (var y:int = 0; y < NUM_OF_Y; y++) {
var posY:Number = y * STEP_Y - RANGE;
for (var x:int = 0; x < NUM_OF_X; x++) {
var posX:Number = x * STEP_X - RANGE;
var posZ:Number = a * posX * Math.exp((-(posX * posX + posY * posY)) / b);
_verts.push(posX * SCALE, posY * SCALE, posZ * SCALE);
}
}
_verts.fixed = true;
// 線を引くためのインデックスの生成
// X軸方向
var idxs:Vector.<int> = new Vector.<int>();
for (y = 0; y < NUM_OF_Y; y++) {
for (x = 0; x < NUM_OF_X; x++) {
idxs.push(NUM_OF_X * y + x);
}
_indices.push(idxs.concat());
idxs.length = 0;
}
// Y軸方向
for (x = 0; x < NUM_OF_X; x++) {
for (y = 0; y < NUM_OF_Y; y++) {
idxs.push(NUM_OF_X * y + x);
}
_indices.push(idxs.concat());
idxs.length = 0;
}
_indices.fixed = true;
}
}
//}
//package {
/**
* 2変数関数
* z = a * (x * y) * exp(-(x^2 + y^2) / b) 頂点座標データ生成クラス
* @author YOSHIDA, Akio
*/
/*public*/ class Gaussian3 extends Coordinate {
/**
* 頂点座標データ生成
*/
override public function create():void {
const NUM_OF_X:int = 40; // X軸上の置かれる点の数
const NUM_OF_Y:int = 40; // Y軸上の置かれる点の数
const RANGE:Number = 4; // X軸、Y軸上の置かれる点は -RANGE ~ RANGE の範囲
const STEP_X:Number = (RANGE * 2) / (NUM_OF_X - 1);
const STEP_Y:Number = (RANGE * 2) / (NUM_OF_Y - 1);
const SCALE:Number = 15;
var a:Number = 5;
var b:Number = 2;
for (var y:int = 0; y < NUM_OF_Y; y++) {
var posY:Number = y * STEP_Y - RANGE;
for (var x:int = 0; x < NUM_OF_X; x++) {
var posX:Number = x * STEP_X - RANGE;
var posZ:Number = a * (posX * posY) * Math.exp((-(posX * posX + posY * posY)) / b);
_verts.push(posX * SCALE, posY * SCALE, posZ * SCALE);
}
}
_verts.fixed = true;
// 線を引くためのインデックスの生成
// X軸方向
var idxs:Vector.<int> = new Vector.<int>();
for (y = 0; y < NUM_OF_Y; y++) {
for (x = 0; x < NUM_OF_X; x++) {
idxs.push(NUM_OF_X * y + x);
}
_indices.push(idxs.concat());
idxs.length = 0;
}
// Y軸方向
for (x = 0; x < NUM_OF_X; x++) {
for (y = 0; y < NUM_OF_Y; y++) {
idxs.push(NUM_OF_X * y + x);
}
_indices.push(idxs.concat());
idxs.length = 0;
}
_indices.fixed = true;
}
}
//}
//package aquioux.sketch {
import flash.display.DisplayObject;
import flash.display.Stage;
import flash.events.MouseEvent;
/**
* マウス挙動クラス
* @author YOSHIDA, Akio(Aquioux)
*/
/*public*/ class MouseBehavior {
/**
* マウス移動量(X軸)
*/
static public function get moveX():Number { return _moveX; }
static private var _moveX:Number = 0.0;
/**
* マウス移動量(Y軸)
*/
static public function get moveY():Number { return _moveY; }
static private var _moveY:Number = 0.0;
// 前回の MOUSW_MOVE 時のマウス座標
static private var prevMouseX_:Number = 0.0;
static private var prevMouseY_:Number = 0.0;
// マウスをダウンしているか否か
static private var isMouseDown_:Boolean = false;
// マウスイベントの対象ステージ
static private var stage_:DisplayObject;
// 摩擦係数
static private const FRICTION:Number = 0.98;
/**
* 初期化
* @param stage マウスイベントの対象ステージ
*/
static public function setup(stage:DisplayObject):void {
// マウスイベントの対象
stage_ = stage;
// マウスハンドラ登録
stage_.addEventListener(MouseEvent.MOUSE_DOWN, function():void { isMouseDown_ = true; });
stage_.addEventListener(MouseEvent.MOUSE_UP, function():void { isMouseDown_ = false; });
stage_.addEventListener(MouseEvent.MOUSE_MOVE, function():void {
if (!isMouseDown_) {
prevMouseX_ = stage_.mouseX;
prevMouseY_ = stage_.mouseY;
}
});
}
/**
* 更新
*/
static public function update():void {
if (isMouseDown_) {
_moveX = stage_.mouseX - prevMouseX_;
_moveY = stage_.mouseY - prevMouseY_;
prevMouseX_ = stage_.mouseX;
prevMouseY_ = stage_.mouseY;
} else {
_moveX *= FRICTION;
_moveY *= FRICTION;
}
}
}
//}