反転の「見える化」 円による「反転」の様子を見てみる Aquioux forked:1favorite:2lines:146license : MIT License modified : 2010-09-02 22:36:52 Embed Tweet package { import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.Graphics; import flash.display.Shape; import flash.display.Sprite; import flash.events.Event; import flash.events.MouseEvent; import flash.geom.Point; [SWF(width = "465", height = "465", frameRate = "30", backgroundColor = "#FFFFFF")] /** * 反転の「見える化」 * * 青:反転前図形 * 緑:反転対称軸としての円とその円の中心点を通る縦横の直線 * 赤:反転後座標 * * ステージクリックで反転前の図形を線/円でトグル切り替え * * @see http://aquioux.net/blog/?p=548 * * @author YOSHIDA, Akio (Aquioux) */ public class Main extends Sprite { private const RADIUS:uint = 100; // 反転軸円の半径 private const RADIUS_SQUARE:uint = RADIUS * RADIUS; // 反転軸円の半径の2乗 private const N_PIXEL_COLOR:uint = 0xFF0000FF; // 反転前ピクセルの色 private const I_PIXEL_COLOR:uint = 0xFFFF0000; // 反転後ピクセルの色 private const BMD_FILL_COLOR:uint = 0x00000000; // ピクセルを描く BitmapData の fill 色 private const AXIS_COLOR:uint = 0x00FF00; // 反転軸円の色 private var nBmd_:BitmapData; // 反転前ピクセルを描く BitmapData; private var iBmd_:BitmapData; // 反転後ピクセルを描く BitmapData; private var axis_:Shape; // 反転軸円と中心交差線を描く表示物 // 反転前座標 private var nCoordinates_:Vector.<int>; private var nCoordinatesLine_:Vector.<int>; private var nCoordinatesCircle_:Vector.<int>; // 反転後座標 private var iCoordinates_:Vector.<int>; private var iCoordinatesLine_:Vector.<int>; private var iCoordinatesCircle_:Vector.<int>; private var len_:int; // [n/i]Coordinates の length private var toggle_:Boolean = false; // トグルスイッチ(反転前座標の「線」と「円」を切り替える // コンストラクタ public function Main() { setup1(); setup2(); addEventListener(Event.ENTER_FRAME, update); stage.addEventListener(MouseEvent.CLICK, clickHandler); } private function clickHandler(e:MouseEvent):void { toggle_ = !toggle_; setup2(); } // 表示物の生成と不動要素の描画 private function setup1():void { var sw:Number = stage.stageWidth; var sh:Number = stage.stageHeight; var cx:Number = sw / 2; var cy:Number = sh / 2; // 表示物の生成 // BitmapData および Bitmap nBmd_ = new BitmapData(sw, sh, true, BMD_FILL_COLOR); iBmd_ = nBmd_.clone(); // 反転軸円と中心交差線を描く Shape axis_ = new Shape(); addChild(axis_); addChild(new Bitmap(nBmd_)); addChild(new Bitmap(iBmd_)); // 反転軸円と中心交差線を描く var g_:Graphics = axis_.graphics; g_.lineStyle(0, AXIS_COLOR); g_.drawCircle(0, 0, RADIUS); g_.moveTo(0, -sh); g_.lineTo(0, sh); g_.moveTo(-sw, 0); g_.lineTo( sw, 0); // 反転前座標の生成 nCoordinatesLine_ = new Vector.<int>(); nCoordinatesCircle_ = new Vector.<int>(); nCoordinatesLine_ = DataFactory.drawLine(sw, sh, cx, 0, cx, sh); // 線 nCoordinatesCircle_ = DataFactory.drawCircle(sw, sh, cx, cy, RADIUS); // 円 nCoordinatesLine_.fixed = true; nCoordinatesCircle_.fixed = true; iCoordinatesLine_ = new Vector.<int>(nCoordinatesLine_.length, true); iCoordinatesCircle_ = new Vector.<int>(nCoordinatesCircle_.length, true); } // 反転前座標の切り替えと描画 private function setup2():void { if (toggle_) { nCoordinates_ = nCoordinatesCircle_; iCoordinates_ = iCoordinatesCircle_; len_ = nCoordinatesCircle_.length; } else { nCoordinates_ = nCoordinatesLine_; iCoordinates_ = iCoordinatesLine_; len_ = nCoordinatesLine_.length; } // 反転前座標の描画 nBmd_.lock(); nBmd_.fillRect(nBmd_.rect, BMD_FILL_COLOR); for (var i:int = 0; i < len_; i += 2) { var posX:Number = nCoordinates_[i]; var posY:Number = nCoordinates_[i + 1]; nBmd_.setPixel32(posX, posY, N_PIXEL_COLOR); } nBmd_.unlock(); } // ループ処理 private function update(e:Event):void { // マウスカーソル座標取得 var mx:Number = mouseX; var my:Number = mouseY; // マウスの移動に伴い対称軸円と中心交差線を動かす axis_.x = mx; axis_.y = my; // 座標の反転計算 invert(mx, my, nCoordinates_, iCoordinates_); // 反転座標の描画 iBmd_.lock(); iBmd_.fillRect(iBmd_.rect, BMD_FILL_COLOR); for (var i:int = 0; i < len_; i += 2) { var posX:Number = iCoordinates_[i]; var posY:Number = iCoordinates_[i + 1]; iBmd_.setPixel32(posX, posY, I_PIXEL_COLOR); } iBmd_.unlock(); } // 座標の反転計算 private function invert(x0:Number, y0:Number, nCoordinate:Vector.<int>, iCoordinate:Vector.<int>):void { for (var i:int = 0; i < len_; i += 2) { // 円の中心O(x0, y0) -> マウスカーソルの座標 // 与えられた点P(x, y) -> nCoordinates_ // 求める点P'(x', y') -> iCoordinates_ // 反転計算式 // x' = r^2 * (x - x0) / ((x - x0)^2 + (y - y0)^2) + x0 // y' = r^2 * (y - y0) / ((x - x0)^2 + (y - y0)^2) + y0 var xp:Number = nCoordinates_[i]; var yp:Number = nCoordinates_[i + 1]; var distX:Number = xp - x0; var distY:Number = yp - y0; var distXY:Number = distX * distX + distY * distY; iCoordinates_[i] = RADIUS_SQUARE * distX / distXY + x0; iCoordinates_[i + 1] = RADIUS_SQUARE * distY / distXY + y0; } } } } //package { import flash.display.BitmapData; import flash.display.Graphics; import flash.display.Shape; /** * 指定図形を構成する座標値の取得 * @author YOSHIDA, Akio (Aquioux) */ /*public*/ class DataFactory { public function DataFactory() { } /** * 線の座標取得 * @param sw ステージサイズ幅 * @param sh ステージサイズ高 * @param x0 開始座標X * @param y0 開始座標Y * @param x1 終了座標X * @param y1 終了座標Y * @return 座標を1次元配列で格納した Vector */ public static function drawLine(sw:int, sh:int, x0:int, y0:int, x1:int, y1:int):Vector.<int> { var shape:Shape = new Shape(); var g:Graphics = shape.graphics; g.lineStyle(0, 0x000000); g.moveTo(x0, y0); g.lineTo(x1, y1); return getVector(shape, sw, sh); } /** * 円の座標取得 * @param sw ステージサイズ幅 * @param sh ステージサイズ高 * @param px 中心座標X * @param py 中心座標Y * @param radius 半径 * @return 座標を1次元配列で格納した Vector */ public static function drawCircle(sw:int, sh:int, px:int, py:int, radius:int):Vector.<int> { var shape:Shape = new Shape(); var g:Graphics = shape.graphics; g.lineStyle(0, 0x000000); g.drawCircle(px, py, radius); return getVector(shape, sw, sh); } static private function getVector(shape:Shape, sw:int, sh:int):Vector.<int> { var transparent:int = 0x00000000; var bmd:BitmapData = new BitmapData(sw, sh, true, transparent); bmd.draw(shape); var v:Vector.<int> = new Vector.<int>(); for (var y:int = 0; y < sh; y++) { for (var x:int = 0; x < sw; x++) { if (bmd.getPixel32(x, y) != transparent) v.push(x, y); } } return v; } } //} Code Fullscreen Preview Fullscreen kuroarizuka Thy 反転 数学 Shape graphics Vector fixed mouseY mouseX clone addEventListener MouseEvent.CLICK MouseEvent.ENTER_FRAME length MouseEvent push Boolean uint Number int sort new page view favorite forked pv2121 forked from: 反転の「見える化」(シュタイナー・.. Aquioux forked:1 favorite:9lines:148 (diff:44) tag: シュタイナーの円鎖 反転 数学