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

Electric potential

電位を計算して3次元表示する教材。

画面下部の赤丸(正電荷)・青丸(負電荷)をドラッグして緑の四角の中に入れると、
上の画面が変更されます。
上の画面はマウスドラッグで視点変更、↑↓キーでカメラ距離変更できます。

追記:定数を少しいじりました(3/10,14:10)
Get Adobe Flash player
by Nicolas 10 Mar 2010
/**
 * Copyright Nicolas ( http://wonderfl.net/user/Nicolas )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/xFWj
 */

/*
電位を計算して3次元表示する教材。

画面下部の赤丸(正電荷)・青丸(負電荷)をドラッグして緑の四角の中に入れると、
上の画面が変更されます。
上の画面はマウスドラッグで視点変更、↑↓キーでカメラ距離変更できます。

追記:定数を少しいじりました(3/10,14:10)

*/

package 
{
	import flash.display.Sprite;
	import flash.display.Graphics;
	import flash.events.Event;
	import org.papervision3d.core.geom.renderables.Vertex3D;
	[SWF(width="465",height="465",backgroundColor="#CCCCCC")]
	public class Main extends Sprite
	{
		private var canvas:canvas3D;
		private var charges:Array;
		
		public function Main()
		{
			//3Dキャンバス
			canvas = new canvas3D(465, 300);
			addChild(canvas);
			
			//2Dフィールド
			var field2D:Sprite = new Sprite();
			var fg:Graphics = field2D.graphics;
			fg.beginFill(0xFFFFFF);
			fg.lineStyle(2, 0x00CC99);
			fg.drawRect(-75, -75, 150, 150);
			fg.endFill();
			fg.moveTo(0, -75); fg.lineTo(0, 75); fg.moveTo(-75, 0); fg.lineTo(75, 0);
			field2D.x = 225; field2D.y = 380;
			addChild(field2D);
			
			//電荷
			charges = [
				new PCharge(), new PCharge(), new PCharge(),
				new NCharge(), new NCharge(), new NCharge()
			];
			for (var i:int = 0; i < charges.length; i++)
			{
				var c:Charge = charges[i] as Charge;
				c.x = -90;
				c.y = 20 * i - 65;
				field2D.addChild(c);
				c.addEventListener(Event.CHANGE, changeHandler);
			}
			
		}
		
		private function changeHandler(e:Event):void
		{
			var vertices:Array = canvas.v;
			for (var i:int = 0; i < vertices.length; i++)
			{
				var v:Vertex3D = vertices[i];
				var tempV:Number = 0;
				for (var j:int = 0; j < charges.length; j++)
				{
					var c:Charge = charges[j];
					
					//2Dフィールドの座標を3Dキャンバスの座標に対応させる
					var cx:Number = c.x / 150 * 500;
					var cy:Number = c.y / 150 * 500;
					
					//電位を計算
					if(c.x > -75 && c.y > -75 && c.x < 75 && c.y < 75)
					tempV += 500 * c.q / Math.sqrt((v.x - cx)*(v.x - cx) + (v.y - cy)*(v.y - cy))
				}
				v.z = tempV;
			}
		}
	}
	
}

import flash.display.Graphics;
import flash.events.Event;
import flash.events.KeyboardEvent;
import org.papervision3d.view.BasicView;
import org.papervision3d.materials.WireframeMaterial;
import org.papervision3d.objects.primitives.Plane;
class canvas3D extends BasicView
{
	public var v:Array;
	private var r:Number = 800;
	private var theta:Number = 60;
	private var phi:Number = -90;
	private var mouseDownX:Number;
	private var mouseDownY:Number;
	public function canvas3D(w:uint, h:uint) 
	{
		super(w, h, false);
		
		var g:Graphics = this.graphics;
		g.beginFill(0x000000);
		g.drawRect(0, 0, w, h);
		g.endFill();
		
		var m:WireframeMaterial = new WireframeMaterial(0xFF0000);
		m.doubleSided = true;
		var field:Plane = new Plane(m, 500, 500, 30, 30);
		field.rotationX = -90;
		scene.addChild(field);
		
		setCameraPosition(r, theta, phi);
		camera.zoom = 80;
		startRendering();
		
		v = field.geometry.vertices;
		
		addEventListener(Event.ADDED_TO_STAGE, function(e:Event):void 
		{
			addEventListener(MouseEvent.MOUSE_DOWN, function(e:MouseEvent):void 
			{
				//マウスダウン位置を記録
				mouseDownX = mouseX;
				mouseDownY = mouseY;
				addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
			});
			stage.addEventListener(MouseEvent.MOUSE_UP, function(e:MouseEvent):void 
			{
				removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
			});
			stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
		});
	}
	
	/**
	 * カメラの位置を極座標から直交座標に変換する。
	 * @param	$r
	 * @param	$theta
	 * @param	$phi
	 */
	private function setCameraPosition($r:Number, $theta:Number, $phi:Number):void {
		var thetaRad:Number = $theta / 180 * Math.PI;
		var phiRad:Number = $phi / 180 * Math.PI;
		camera.x = -$r * Math.sin(thetaRad) * Math.cos(phiRad);
		camera.y = $r * Math.cos(thetaRad);
		camera.z = $r * Math.sin(thetaRad) * Math.sin(phiRad);
	}
	
	/**
	 * ドラッグ量を角度に変換し、カメラの位置を設定する。
	 * @param	e
	 */
	private function mouseMoveHandler(e:MouseEvent):void 
	{
		if (e.buttonDown) {
			phi += e.stageX - mouseDownX;
			theta -= e.stageY - mouseDownY;
			if (theta > 179) theta = 179;
			if (theta < 1) theta = 1;
			if (phi < -180) phi = -179;
			if (phi > 0) phi = -1;
			
			setCameraPosition(r, theta, phi);//直交座標に変換
			
			mouseDownX = e.stageX;
			mouseDownY = e.stageY;
		}
	}
	
	/**
	 * カメラの中心からの距離を設定する。↑:近づく、↓:遠ざかる。
	 * @param	e
	 */
	private function keyDownHandler(e:KeyboardEvent):void 
	{
		switch(e.keyCode)
		{
			case 38:
				r -= 50;
				setCameraPosition(r, theta, phi);
			break;
			
			case 40:
				r += 50;
				setCameraPosition(r, theta, phi);
			break;
		}
	}
}

import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.events.Event;
class Charge extends Sprite
{
	public var q:Number = 0;
	private var ev:Event = new Event(Event.CHANGE);
	public function Charge()
	{
		init();
	}
	
	private function init():void
	{		
		buttonMode = true;
		addEventListener(MouseEvent.MOUSE_DOWN, function(e:MouseEvent):void { 
			startDrag(); 
		} );
		addEventListener(MouseEvent.MOUSE_UP, function(e:MouseEvent):void { 
			stopDrag(); 
			if(y < -75) y = -75;
			dispatchEvent(ev);
		} );
	}
}

import flash.display.Sprite;
class PCharge extends Charge
{
	public function PCharge()
	{
		q = 10;
		var g:Graphics = this.graphics;
		g.beginFill(0xFF0000);
		g.drawCircle(0, 0, 5);
		g.endFill();
	}
}

import flash.display.Sprite;
class NCharge extends Charge
{
	public function NCharge()
	{
		q = -10;
		var g:Graphics = this.graphics;
		g.beginFill(0x0000FF);
		g.drawCircle(0, 0, 5);
		g.endFill();
	}
}