package { import flash.display.MovieClip; import flash.display.Shape; import flash.display.Sprite; import flash.events.Event; import flash.geom.Point; import flash.events.MouseEvent; public class Spiro extends Sprite { private var center:Point = new Point(255, 200); //固定円の中心座標 private var centerX:Number; //可動円の中心X座標 private var centerY:Number; //可動円の中心Y座標 private var dx:Number = 336; //Spiroの中心X座標(420)  private var dy:Number = 200; //Spiroの中心Y座標 private var _x:Number; //可動円の中心とSpiroの中心・X座標の差 private var _y:Number; //可動円の中心とSpiroの中心・Y座標の差 private var xPos:Number; //SpiroのX座標 private var yPos:Number; //SpiroのY座標 private var angle:Number = 0; //三角関数の角度(ラジアン表示) private var r1:uint = 96; //固定円の半径(96) private var r2:uint = 45; //可動円の半径(45) private var r3:Number; //可動円の中心からSpiroまでの距離 public function Spiro():void { FixCircle(); //固定円 MovaCircle(); //可動円 DrawPoint(); //Spiro } //固定円インスタンス private function FixCircle():void { var FixCircle:Sprite = new Sprite(); FixCircle.graphics.lineStyle(1, 0x000000); FixCircle.graphics.drawCircle(center.x, center.y, r1); FixCircle.graphics.beginFill(0xFF0000); FixCircle.graphics.drawCircle(center.x, center.y, 1); addChild(FixCircle); } //可動円インスタンス private function MovaCircle():void { //可動円の中心を定める centerX = center.x + r1 - r2; centerY = center.y; var MovaCircle:Sprite = new Sprite(); MovaCircle.graphics.lineStyle(1, 0x000000); MovaCircle.graphics.drawCircle(centerX, centerY, r2); MovaCircle.graphics.beginFill(0x0000FF); MovaCircle.graphics.drawCircle(centerX, centerY, 1); //可動円内の十字線 MovaCircle.graphics.lineStyle(0, 0x000000); MovaCircle.graphics.moveTo(centerX, centerY + r2); MovaCircle.graphics.lineTo(centerX, centerY - r2); MovaCircle.graphics.moveTo(centerX + r2, centerY); MovaCircle.graphics.lineTo(centerX - r2, centerY); addChild(MovaCircle); //固定円の周辺に沿った可動円の動き MovaCircle.addEventListener(Event.ENTER_FRAME, onTwist); } //Spiroインスタンス private function DrawPoint(/*event:MouseEvent*/):void { var DrawPoint:Sprite = new Sprite(); DrawPoint.graphics.lineStyle(1, 0x000000); DrawPoint.graphics.beginFill(0x00FF00); DrawPoint.graphics.drawCircle(dx, dy, 3); addChild(DrawPoint); //可動円内におけるSpiroの動き DrawPoint.addEventListener(Event.ENTER_FRAME, onRote); //Spiroの軌跡 DrawPoint.addEventListener(Event.ENTER_FRAME, SpiroLoop); } //可動円の動き private function onTwist(event:Event):void { angle -= 0.075; //固定円の中心から観た可動円の中心の座標 var MovaCircle:Sprite = event.target as Sprite; MovaCircle.x = (r1 - r2) * Math.cos(angle) - (r1 - r2); MovaCircle.y = (r1 - r2) * Math.sin(angle); } //Spiroの動き private function onRote(event:Event):void { _x = dx - centerX; _y = dy - centerY; //線の大きさを求める r3 = Math.sqrt(_x * _x + _y * _y); //固定円の中心から観たSpiroの座標 var DrawPoint:Sprite = event.target as Sprite; DrawPoint.x = (r1 - r2) * Math.cos(angle) + r3 * Math.cos((r1 - r2) / r2 * angle) - (r1 - r2 + r3); DrawPoint.y = (r1 - r2) * Math.sin(angle) - r3 * Math.sin((r1 - r2) / r2 * angle); } //Spiroの軌跡に点を打つ private function SpiroLoop(event:Event): void { _x = dx - centerX; _y = dy - centerY; r3 = Math.sqrt(_x * _x + _y * _y); //固定円の中心から観たSpiroの座標 xPos = (r1 - r2) * Math.cos(angle) + r3 * Math.cos((r1 - r2) / r2 * angle) - (r1 - r2 + r3) + dx; yPos = (r1 - r2) * Math.sin(angle) - r3 * Math.sin((r1 - r2) / r2 * angle) + dy; var Spiro:Sprite = new Sprite(); Spiro.graphics.lineStyle(1, 0x000000); //Spiro.graphics.beginFill(Math.random() * 0xCCCCCC); Spiro.graphics.beginFill(0x00FF00); Spiro.graphics.drawCircle(xPos, yPos, 1); addChild(Spiro); } } }