2つの円運動
青いラインと緑のラインが個別に円運動を行い、2つの円運動によってできる軌跡が赤いラインです。
[スライダーの解説]
・blue speed: 青いラインが1秒間で何周するか
・green speed: 緑のラインが1秒間で何周するか
・blue distance: 青いラインの長さ
・green distance: 緑のラインの長さ
[詳細記事]
2つの円運動の組み合せで出来る動き - いたち じっけん室
http://b.i-tach.com/?p=816
/**
* Copyright usami ( http://wonderfl.net/user/usami )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/xWuX
*/
package {
import flash.display.Sprite
import com.bit101.components.HUISlider;
import com.bit101.components.ComboBox;
import flash.events.Event;
import flash.geom.Point;
[SWF(width="465", height="465", backgroundColor="0x000000", frameRate="60")]
public class Index extends Sprite {
public var xLine:Sprite;
public var yLine:Sprite;
public var mainLine:Sprite;
public var bg:Sprite;
public var lines:Vector.<Sprite> = new Vector.<Sprite>();
public var maxLineN:int = 600;
public var lineCount:int = 0;
public var oldLineX:int = 232;
public var oldLineY:int = 232;
public var isFirst:Boolean = true;
public var fr:int;
//blue line
public var speed1:Number = 1;//スピード
public var distance1:Number = 100;//距離
public var degree1:Number = 0;//角度
public var ball1:Sprite;
//green line
public var speed2:Number = 1;
public var distance2:Number = 100;
public var degree2:Number = 0;
public var ball2:Sprite;
public var ball3:Sprite;
//スライダー
public var slider:Sprite;
public var slDistance1:HUISlider;
public var slSpeed1:HUISlider;
public var slDistance2:HUISlider;
public var slSpeed2:HUISlider;
//--------------------------------------------------------------------
//コンストラクタ
public function Index() {
stage.scaleMode = "noScale";
stage.align = "TL";
fr = stage.frameRate;
set_viewInit();
set_ui();
resizeHandler();
addEventListener(Event.ENTER_FRAME, enterFrameHandler);
stage.addEventListener(Event.RESIZE, resizeHandler);
}
//--------------------------------------------------------------------
//メイン描画セット
//
private function set_viewInit():void
{
bg = new Sprite();
bg.graphics.beginFill(0x000000);
bg.graphics.drawRect(0, 0, 100, 100);
addChild(bg);
mainLine = new Sprite();
addChild(mainLine);
xLine = new Sprite();
xLine.graphics.beginFill(0xffffff);
xLine.graphics.drawRect(0, -10, 1, 10);
addChild(xLine);
yLine = new Sprite();
yLine.graphics.beginFill(0xffffff);
yLine.graphics.drawRect(-10, 0, 10, 1);
addChild(yLine);
ball1 = set_ball(0x0000FF);
ball2 = set_ball(0x006D1B);
ball3 = set_ball(0xFF0000);
for (var i:int = 0; i < maxLineN; i++)
{
lines[i] = new Sprite();
addChild(lines[i]);
}
lines.fixed = true;
}
//ball
private function set_ball(clr:uint):Sprite
{
var ball:Sprite = new Sprite();
ball.graphics.beginFill(clr);
ball.graphics.drawCircle(0, 1.5, 1.5);
addChild(ball);
return ball;
}
//UIセット
private function set_ui():void
{
//スライダー
slider = new Sprite();
slider.x = 10;
slider.y = 10;
addChild(slider);
slSpeed1 = new HUISlider(slider, 0, 0, "blue speed", function():void {
speed1 = slSpeed1.value;
} );
slSpeed1.width = 200;
slSpeed1.minimum = 0;
slSpeed1.maximum = 4;
slSpeed1.value = speed1;
slSpeed2 = new HUISlider(slider, 0, 20, "green speed", function():void {
speed2 = slSpeed2.value;
} );
slSpeed2.width = 200;
slSpeed2.minimum = 0;
slSpeed2.maximum = 4;
slSpeed2.value = speed2;
slDistance1 = new HUISlider(slider, 0, 40, "blue distance", function():void {
distance1 = slDistance1.value;
} );
slDistance1.width = 200;
slDistance1.minimum = 10;
slDistance1.maximum = 120;
slDistance1.value = distance1;
slDistance2 = new HUISlider(slider, 0, 60, "green distance", function():void {
distance2 = slDistance2.value;
} );
slDistance2.width = 200;
slDistance2.minimum = 10;
slDistance2.maximum = 120;
slDistance2.value = distance2;
//コンボボックス
var box:ComboBox = new ComboBox(this, 10, 100, "SELECT SAMPLE");
box.addItem("1:1 sample");
box.addItem("1:1.5 sample");
box.addItem("1:2 sample");
box.addItem("1:3 sample");
box.addItem("1:4 sample");
box.addItem("1:5 sample");
box.addItem("1:6 sample");
box.addItem("1:10 sample");
box.addItem("1:20 sample");
box.addEventListener(Event.SELECT, onSelect);
}
private function onSelect(event:Event):void
{
var box:ComboBox = event.currentTarget as ComboBox;
trace(box.selectedItem);
switch (box.selectedItem)
{
case "1:1 sample": set_prop(1, 120, 1, 37); break;
case "1:1.5 sample": set_prop(0.9, 50, 0.6, 79); break;
case "1:2 sample": set_prop(1, 33, 0.5, 95); break;
case "1:3 sample": set_prop(2.4, 70, 0.8, 70); break;
case "1:4 sample": set_prop(2, 50, 0.5, 120); break;
case "1:5 sample": set_prop(4, 19, 0.8, 120); break;
case "1:6 sample": set_prop(0.5, 120, 3, 20); break;
case "1:10 sample": set_prop(2, 44, 0.2, 104); break;
case "1:20 sample": set_prop(2, 13, 0.1, 120); break;
}
}
private function set_prop(s1:Number,d1:Number,s2:Number,d2:Number):void
{
slSpeed1.value = speed1 = s1;
slDistance1.value = distance1 = d1;
slSpeed2.value = speed2 = s2;
slDistance2.value = distance2 = d2;
}
//--------------------------------------------------------------------
//enterFrame
private function enterFrameHandler(e:Event):void
{
degree1 = (degree1 + speed1 / fr * 360) % 360;
degree2 = (degree2 + speed2 / fr * 360) % 360;
var radian1:Number = Math.PI / 180 * degree1;
var radian2:Number = Math.PI / 180 * degree2;
//green ball
ball2.x = ball1.x + distance1 * Math.cos(radian1);
ball2.y = ball1.y + distance1 * Math.sin(radian1);
//red ball
ball3.x = ball2.x + distance2 * Math.cos(radian2);
ball3.y = ball2.y + distance2 * Math.sin(radian2);
mainLine.graphics.clear();
//blue line
mainLine.graphics.lineStyle(1, 0x0000CC);
mainLine.graphics.moveTo(ball1.x, ball1.y);
mainLine.graphics.lineTo(ball2.x, ball2.y);
//green line
mainLine.graphics.lineStyle(1, 0x004C13);
mainLine.graphics.lineTo(ball3.x, ball3.y);
//red line
lines[lineCount].graphics.clear();
lines[lineCount].graphics.lineStyle(1, 0xFF0000);
if (isFirst) {
lines[lineCount].graphics.moveTo(ball3.x, ball3.y);
if (lineCount > 1) isFirst = false;
}else {
lines[lineCount].graphics.moveTo(oldLineX, oldLineY);
}
lines[lineCount].graphics.lineTo(ball3.x, ball3.y);
for (var i:int = 0; i < maxLineN; i++)
{
var n:int = (lineCount - i + maxLineN) % maxLineN;
lines[n].alpha = 1 - (i / maxLineN);
}
lineCount = (lineCount + 1) % maxLineN;
oldLineX = ball3.x;
oldLineY = ball3.y;
xLine.x = ball3.x;
yLine.y = ball3.y;
}
//--------------------------------------------------------------------
//ステージリサイズ
private function resizeHandler(e:Event = null):void
{
ball1.x = stage.stageWidth/2;
ball1.y = stage.stageHeight / 2;
yLine.x = stage.stageWidth;
xLine.y = stage.stageHeight;
bg.width = stage.stageWidth;
bg.height = stage.stageHeight;
}
//--------------------------------------------------------------------
}
}