In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

波の式

y-xグラフとy-tグラフの意味や両者の違いを理解させるための教材。
y-xグラフの赤い円を動かすと、y-tグラフの対象となるx座標が変わります。
y-tグラフの赤い円を動かすと、y-xグラフの時刻が変わります。
playボタンを押すと、時間が進みます。
/**
 * Copyright Nicolas ( http://wonderfl.net/user/Nicolas )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/a046
 */

package {
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.text.TextField;
    import com.bit101.components.*;
    
    [SWF(width="465", height="465", frameRate="60")]
    public class Main extends Sprite {
        public var yxChart:Chart;
        public var ytChart:Chart;
        public var amplitude:Number = 50;
        public var lambda:Number = 50;
        public var term:Number = 5;
        public var time:Number = 0;
        public var pos:Number = 0;
        public var initialPhase:Number = 0;
        public var vec:Vector.<Number>;
        public var playing:Boolean = false;
        private var timeLabel:TextField;
        private var posLabel:TextField;
        
        public function Main() {
            //波の式
            var waveEquation:TextField = addChild(new TextField()) as TextField;
            waveEquation.text = "y=Asin{2π(t/T - x/λ)+φ}";
            waveEquation.width = 200;
            waveEquation.x = 10;
            waveEquation.y = 100;
            waveEquation.scaleX = waveEquation.scaleY = 1.8;
            
            var panel:Panel = new Panel(this, 10, 200);
            panel.width = 225;
            panel.height = 155;
            
            //振幅
            var amplitudeLabel:TextField = panel.addChild(new TextField()) as TextField;
            amplitudeLabel.text = "A:振幅";
            amplitudeLabel.x = 10;
            amplitudeLabel.y = 20;
            amplitudeLabel.selectable = false;
            var amplitudeNS:NumericStepper = new NumericStepper(panel, 110, 20, function(e:Event):void {
                amplitude = amplitudeNS.value;
            });
            amplitudeNS.value = amplitude;
            amplitudeNS.minimum = 10;
            
            //波長(波1個分の長さ)
            var lambdaLabel:TextField = panel.addChild(new TextField()) as TextField;
            lambdaLabel.text = "λ:波長";
            lambdaLabel.x = 10;
            lambdaLabel.y = 45;
            lambdaLabel.selectable = false;
            var lambdaNS:NumericStepper = new NumericStepper(panel, 110, 45, function(e:Event):void {
                lambda = lambdaNS.value;
            });
            lambdaNS.value = lambda;
            lambdaNS.minimum = 1;
            
            //周期(振動1回にかかる時間)
            var termLabel:TextField = panel.addChild(new TextField()) as TextField;
            termLabel.text = "T:周期";
            termLabel.x = 10;
            termLabel.y = 70;
            termLabel.selectable = false;
            var termNS:NumericStepper = new NumericStepper(panel, 110, 70, function(e:Event):void {
                term = termNS.value;
            });
            termNS.value = term;
            termNS.step = 0.1;
            termNS.minimum = 1;
            
            //初期位相(時刻t=0での振動の進み具合)
            var initialPhaseLabel:TextField = panel.addChild(new TextField()) as TextField;
            initialPhaseLabel.text = "φ:初期位相(度)";
            initialPhaseLabel.x = 10;
            initialPhaseLabel.y = 95;
            initialPhaseLabel.selectable = false;
            var initialPhaseNS:NumericStepper = new NumericStepper(panel, 110, 95, function(e:Event):void {
                initialPhase = initialPhaseNS.value;
            });
            initialPhaseNS.value = initialPhase;
            initialPhaseNS.step = 5;
            initialPhaseNS.minimum = -180;
            initialPhaseNS.maximum = 180;
            
            
            //PLAY
            var playBtn:PushButton = new PushButton(panel, 10, 120, "play", function(e:Event):void {
                playing = !playing;
                if (playing) playBtn.label = "pause";
                if (!playing) playBtn.label = "play";
            });
            
            //RESET
            var resetBtn:PushButton = new PushButton(panel, 115, 120, "reset", function(e:Event):void {
                playing = false;
                playBtn.label = "play";
                time = 0;
                timeLabel.text = "y-xグラフ (t=0)";
                ytChart.position = 0;
            });
            
            //y-xグラフのラベル
            timeLabel = addChild(new TextField()) as TextField;
            timeLabel.text = "y-xグラフ (t=0)";
            timeLabel.x = 250;
            timeLabel.y = 0;
            timeLabel.selectable = false;
            timeLabel.width = 300;
            timeLabel.scaleX = timeLabel.scaleY = 1.5;
            
            //y-tグラフのラベル
            posLabel = addChild(new TextField()) as TextField;
            posLabel.text = "y-tグラフ (x=0)";
            posLabel.x = 250;
            posLabel.y = 235;
            posLabel.selectable = false;
            posLabel.width = 300;
            posLabel.scaleX = posLabel.scaleY = 1.5;
            
            
            //y-xグラフ(時刻tにおける波形)
            yxChart = new Chart("x", "y", 0x000000);
            addChild(yxChart);
            yxChart.x = 250;
            yxChart.y = 30;
            yxChart.originY = 100;
            yxChart.addEventListener(Event.CHANGE, function(e:Event):void {
                pos = yxChart.position;
                posLabel.text = "y-tグラフ (x=" + String(pos) + ")";
            });
            
            //y-tグラフ(位置xにある媒質の振動)
            ytChart = new Chart("t", "y", 0x000000);
            addChild(ytChart);
            ytChart.x = 250;
            ytChart.y = 265;
            ytChart.originY = 100;
            
            addEventListener(Event.ENTER_FRAME, onEnterFrame);
        }
        
        public function onEnterFrame(e:Event):void {
            if (playing) {
                time += 1 / 60;
            } else {
                time = ytChart.position / 10;
            }
            timeLabel.text = "y-xグラフ (t=" + String(int(time * 10) / 10) + ")";
            vec = new Vector.<Number>();
            for (var xx:int = 0; xx < 200; xx++) {
                vec.push(xx, amplitude * Math.sin((2 * Math.PI * (time / term - xx/ lambda) + initialPhase * Math.PI / 180)));
            }
            yxChart.plot(vec);
            yxChart.position = yxChart.position;//赤円の位置を再計算
            
            vec = new Vector.<Number>();
            for (var t:int = 0; t < 200; t++) {
                vec.push(t, amplitude * Math.sin((2 * Math.PI * (t/10 / term - pos/ lambda) + initialPhase * Math.PI / 180)));
            }
            ytChart.plot(vec);
            ytChart.position = time * 10;
        }
    }
}
import flash.display.Graphics;
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.text.TextField;
class Chart extends Sprite {
    
    private var _position:int = 0;
    
    private var yAxis:Shape;
    private var xAxis:Shape;
    private var yLabel:TextField;
    private var xLabel:TextField;
    private var _originX:Number = 0;
    private var _originY:Number = 0;
    private var _color:uint = 0x000000;
    private var point:Sprite;
    private var pointSelected:Boolean = false;
    private var vec:Vector.<Number> = new Vector.<Number>();
    
    public function Chart(xLabelText:String, yLabelText:String, color:uint = 0x000000, width:Number = 200, height:Number = 200) {
        
        var g:Graphics;
        _color = color;
        
        //軸
        xAxis = new Shape();
        xAxis.y = height -_originY;
        g = xAxis.graphics;
        g.lineStyle(2, _color);
        g.moveTo(0, 0);
        g.lineTo(width, 0);
        addChild(xAxis);
        
        yAxis = new Shape();
        g = yAxis.graphics;
        g.lineStyle(2, _color);
        g.moveTo(0, 0);
        g.lineTo(0, height);
        addChild(yAxis);
        
        xLabel = addChild(new TextField()) as TextField;
        xLabel.x = width + 5;
        xLabel.text = xLabelText;
        yLabel = addChild(new TextField()) as TextField;
        yLabel.y = 0;
        yLabel.x = _originX;
        yLabel.text = yLabelText;
        
        point = new Sprite();
        g = point.graphics;
        g.beginFill(0xFF0000);
        g.drawCircle(0, 0, 5);
        addChild(point);
        point.x = 0;
        point.y = height;
        point.addEventListener(MouseEvent.MOUSE_DOWN, startMoving);
        point.buttonMode = true;
    }
    
    public function plot(xyList:Vector.<Number>):void {
        vec = xyList;
        var g:Graphics = graphics;
        g.clear();
        g.lineStyle(2, _color);
        g.moveTo(xyList[0] - originX, height - originY - xyList[1]);
        var len:int = xyList.length;
        for (var i:int = 2; i < len; i += 2) {
            g.lineTo(xyList[i] - originX, height - originY - xyList[i + 1]);
        }
    }
    
    public function clear():void {
        graphics.clear();
    }
    
    public function startMoving(e:MouseEvent):void {
        pointSelected = true;
        addEventListener(Event.ENTER_FRAME, move);
        stage.addEventListener(MouseEvent.MOUSE_UP, function(e:MouseEvent):void {
            pointSelected = false;
            removeEventListener(Event.ENTER_FRAME, move);
            stage.removeEventListener(MouseEvent.MOUSE_UP, arguments.callee);
        });
    }
    
    //MouseXに応じたy座標を計算し、赤円の位置をそこに持っていく
    public function move(e:Event):void {
        if (!pointSelected) return;
        position = mouseX;
    }
    
    public function get originX():Number { return _originX; }
    
    public function set originX(value:Number):void 
    {
        _originX = value;
        yAxis.x = value;
        yLabel.x = value;
        point.x = value;
    }
    
    public function get originY():Number { return _originY; }
    
    public function set originY(value:Number):void 
    {
        _originY = value;
        xAxis.y = height - value;
        xLabel.y = height - value;
        point.y = height - value;
    }
    
    public function get position():int { return _position; }
    
    //valueに応じたy座標を計算し、赤円の位置をそこに持っていく
    public function set position(value:int):void 
    {
        if (value < 0) return;
        if (vec.length - 1 < value * 2 + 1) return;
        _position = value;
        point.x = _position;
        point.y = height - _originY - vec[_position * 2 + 1];
        dispatchEvent(CHANGE_EVENT);
    }
    private const CHANGE_EVENT:Event = new Event(Event.CHANGE);
}