複数電荷の電荷・電位 irobutsu forked:0favorite:6lines:798license : MIT License modified : 2010-03-18 19:56:16 Embed Tweet package{ import flash.system.*; import flash.events.Event; import flash.events.MouseEvent; import flash.utils.IDataInput; import flash.accessibility.Accessibility; import flash.display.Sprite; import flash.display.Graphics; [SWF(width="400", height="400",frameRate="120", backgroundColor=0xffffff)] public class charges extends Sprite { private var chgFlgV:Boolean=false; private var chgFlgE:Boolean=false; private var hankei:int=10; private var Q:Charges; private var nowDragQ:int; private var sbEE:Tsumami; private var ttM:ThreeToggle; private var cbE:Check; private var cbV:Check; private var btC:PushButton; private var w:int=400; private var h:int=364; private var XX:int; public function charges():void { Q=new Charges(w,h); nowDragQ=-1; var i:int; A=new Vector.<Vector.<int>>(w+1); V=new Vector.<Vector.<int>>(w+1); for( i=0; i <= w; i++ ) { A[i]=new Vector.<int>(h+1); V[i]=new Vector.<int>(h+1); } addEventListener("change",changeEvt); addEventListener("update",updateEvt); addEventListener("allerase",alleraseEvt); sbEE=new Tsumami(this,0,-100,100,200,382,200,"外部電場↑="); ttM=new ThreeToggle("正電荷を加える(ドラッグで移動)","負電荷を加える(ドラッグで移動)","電荷を消す(ドラッグ不可)",0,382,200); addChild(ttM); cbE=new Check(true,0,364,140,"電気力線を描く",0xff0000); addChild(cbE); cbV=new Check(true,140,364,140,"等電位線を描く",0xaa00); addChild(cbV); btC=new PushButton(280,364,120,"すべて消去"); addChild(btC); addEventListener(Event.ENTER_FRAME,calcWriteOneLine); stage.addEventListener(MouseEvent.MOUSE_DOWN, mPressed); stage.addEventListener(MouseEvent.MOUSE_UP, mReleased); stage.addEventListener(MouseEvent.MOUSE_MOVE, mMove); update(); } public function alleraseEvt(e:Event):void { var i:int; for( i=0; i < Q.size(); i++ ) { removeChild(Q.C(i)); } Q.deleteAll(); chgFlgE=true; chgFlgV=true; update(); } public function updateEvt(e:Event):void { update(); } public function update():void { write(); // Q.drawMarks(graphics); ttM.update(); cbE.update(); cbV.update(); } public function mMove( e:MouseEvent ):void { } public function mPressed( e:MouseEvent ):void { var mx:int=e.stageX; var my:int=e.stageY; var i:int; if( my<0 || my >= h || mx<0 || mx>=w ) { return; } for( i=0; i < Q.size(); i++ ) { if( Q.hitTest(i,mx,my) ) { if( ttM.value()==2 ) { nowDragQ=-1; chgFlgE=true; chgFlgV=true; removeChild(Q.C(i)); Q.deleteOne(i); update(); } else { nowDragQ=i; Q.startDrag(i); } return ; } } if( ttM.value()==0 ) { Q.addNew(mx-hankei,my-hankei,1,this); chgFlgE=true; chgFlgV=true; } else if( ttM.value()==1 ) { Q.addNew(mx-hankei,my-hankei,-1,this); chgFlgE=true; chgFlgV=true; } Q.C(Q.size()-1).update(); dispatchEvent(new Event("update")); return; } public function mReleased( e:MouseEvent ):void { if( nowDragQ>=0 ) { Q.endDrag(nowDragQ); nowDragQ=-1; chgFlgE=true; chgFlgV=true; dispatchEvent(new Event("update")); } } public function write():void { XX=0; } private var SQX:Vector.<Vector.<int>>; private var SQY:Vector.<Vector.<int>>; private var DX:Vector.<Vector.<int>>; private var DY:Vector.<Vector.<int>>; public function calcWriteOneLine(e:Event):void { var YY:int; var i:int; var c:int; var l:int=Q.size(); if( XX<0 ) { return; } if( XX== 0 ) { Vmin=1; Vmax=0; graphics.clear(); graphics.lineStyle(1,0xffffff); graphics.beginFill(0xffffff); graphics.drawRect(0,0,w,h); graphics.endFill(); if( l!=0 ) { SQX=new Vector.<Vector.<int>>(l) SQY=new Vector.<Vector.<int>>(l) DX=new Vector.<Vector.<int>>(l) DY=new Vector.<Vector.<int>>(l) for(i=0; i< l ; i++ ) { DX[i]=new Vector.<int>(w+1); DY[i]=new Vector.<int>(h+1); SQX[i]=new Vector.<int>(w+1); SQY[i]=new Vector.<int>(h+1); var j:int; for( j=0 ; j<=w ; j++) { DX[i][j]=j-Q.X(i); SQX[i][j]=DX[i][j]*DX[i][j]; } for( YY=0; YY<=h ; YY++) { DY[i][YY]=YY-Q.Y(i); SQY[i][YY]=DY[i][YY]*DY[i][YY]; } } } } if( cbE.isChecked() ) { var BunsiReal:Number=1; var BunsiIm:Number=0; var BunboReal:Number=1; var BunboIm:Number=0; var FiveOverPi:Number=5.0/Math.PI; var EEX:Number=0.001*sbEE.value()*XX; for( YY=0; YY <= h; YY++ ) { BunsiReal=1; BunsiIm=0; var NReal:Number; for( i=0; i<l ; i++ ) { var DXi:Number=DX[i][XX]; var DYi:Number=DY[i][YY]; if( Q.Q(i)>0 ) { NReal= DXi*BunsiReal-DYi*BunsiIm; BunsiIm= DXi*BunsiIm+DYi*BunsiReal; BunsiReal=NReal; } else { NReal= DXi*BunsiReal+DYi*BunsiIm; BunsiIm= DXi*BunsiIm-DYi*BunsiReal; BunsiReal=NReal; } } if( EEX != 0.0 ) { var Mcos:Number=Math.cos(EEX); var Msin:Number=Math.sin(EEX); NReal=BunsiReal*Mcos-BunsiIm*Msin; BunsiIm=Msin*BunsiReal+Mcos*BunsiIm; BunsiReal=NReal; } A[XX][YY]=int(Math.floor(FiveOverPi*Math.atan2(BunsiReal,BunsiIm))); } chgFlgE=false; } if( cbV.isChecked() ) { var v:int; for( YY=0; YY <= h; YY++ ) { var EBYY:Number=0.002*sbEE.value()*YY; if( !Q.isNear(XX, YY) ) { var Vbunsi:Number=1.0; var Vbunbo:Number=1.0; for(i=0; i<l ; i++ ) { if( Q.Q(i)>0 ) { Vbunsi *= SQX[i][XX]+SQY[i][YY]; }else { Vbunbo *= SQX[i][XX]+SQY[i][YY]; } } v=int(Math.floor(-Math.log(Vbunsi/Vbunbo)+EBYY)); if( v>Vmax) {Vmax=v;} if( v<Vmin) {Vmin=v;} V[XX][YY]=v; } else { V[XX][YY]=EBYY; } } chgFlgV=false; } if( XX>0 ) { if( cbE.isChecked() ) { graphics.lineStyle(1,0xff0000); for( YY=0; YY < h; YY++ ) { if( !Q.isNear(XX-1, YY) ) { if( A[XX-1][YY] != A[XX-1][YY+1] || A[XX-1][YY] != A[XX][YY] ) { graphics.beginFill(0xff0000); graphics.drawRect(XX-1,YY,1,1); graphics.endFill(); } } } } if( cbV.isChecked() ) { c=0xaa00; for( YY=0; YY < h; YY++ ) { // c=int(( 255.0*( Number(( V[XX][j] - Vmin )) ) / ( Number(( Vmax - Vmin )) ) )); graphics.lineStyle(1,c); if( !Q.isNear(XX-1,YY) ) { if( V[XX-1][YY] != V[XX-1][YY + 1] || V[XX-1][YY] != V[XX][YY] ) { graphics.beginFill(c); graphics.drawRect(XX-1,YY,1,1); graphics.endFill(); } } } } } XX++; if( XX > w ) { if( cbV.isChecked() ) { var XXX:int; var Ratio:Number=255.0/(Number(Vmax-Vmin)); for(XXX=0; XXX< w; XXX++ ) { for( YY=0; YY < h; YY++ ) { c=int(Ratio* Number(( V[XXX][YY] - Vmin )) ); c=0x10001*c+(255-c)*0x100; graphics.lineStyle(1,c); if( !Q.isNear(XX,YY) ) { if( V[XXX][YY] != V[XXX][YY + 1] || V[XXX][YY] != V[XXX+1][YY] ) { graphics.beginFill(c); graphics.drawRect(XXX,YY,1,1); graphics.endFill(); } } } } } XX=-1; } } private var V:Vector.<Vector.<int>>; private var A:Vector.<Vector.<int>>; private var Vmax:int; private var Vmin:int; public function changeEvt(e:Event):void { chgFlgV=true; chgFlgE=true; XX=0; } } } import flash.events.Event; import flash.events.MouseEvent; import flash.utils.IDataInput; import flash.accessibility.Accessibility; import flash.display.Sprite; import flash.display.*; import flash.system.*; import flash.geom.*; import flash.text.* class Clickable extends Sprite { protected var Width:int; public function Clickable(X:int,Y:int,W:int):void { x=X; y=Y; Width=W; buttonMode=true; writeNormal(); addEventListener(MouseEvent.MOUSE_UP,MUp); addEventListener(MouseEvent.MOUSE_OVER,MOver); addEventListener(MouseEvent.MOUSE_OUT,MOut); } public function MUp(e:Event):void { ; } public function MOut(e:Event):void { writeNormal(); } protected function writeNormal():void { graphics.clear(); graphics.lineStyle(1,0xaaaaaa); graphics.beginFill(0xdddddd); graphics.drawRect(0,0,Width-1,17); graphics.endFill(); graphics.lineStyle(1,0x666666); graphics.moveTo(1,17); graphics.lineTo(Width-1,17); graphics.lineTo(Width-1,1); } public function MOver(e:Event):void { writeHilight(); } protected function writeHilight():void { graphics.clear(); graphics.lineStyle(1,0xffffff); graphics.beginFill(0xdddddd); graphics.drawRect(0,0,Width-1,17); graphics.endFill(); graphics.lineStyle(1,0xaaaaaa); graphics.moveTo(1,17); graphics.lineTo(Width-1,17); graphics.lineTo(Width-1,1); } } class Charge extends Sprite { private var q:int; private var hankei:int; private var color:int; private var nowDrag:Boolean; public function Q():int { return q;} public function X():int {return x+hankei;} // 中心のx座標を返す。xは左隅なので、半径分足す。 public function Y():int {return y+hankei;} // 中心のy座標を返す。yは上隅なので、半径分足す。 public function Charge(qq:int,XXX:int, YYY:int,pp:Sprite):void { buttonMode=true; pp.addChild(this); x=XXX; y=YYY; q=qq; hankei=10; if( qq>0 ) { color=0xbb0000; } else { color=0xbb; } nowDrag=false; write(); } public function goDrag():void { nowDrag=true; startDrag(false,new Rectangle(0,0,400-hankei*2,346-hankei*2)); } public function endDrag():void { nowDrag=false; stopDrag(); dispatchEvent(new Event("update")); } public function update():void { write(); } public function write():void { graphics.clear(); graphics.lineStyle(1,color); graphics.beginFill(color); graphics.drawCircle(hankei,hankei,hankei); graphics.endFill(); if( q != 0 ) { graphics.lineStyle(1,0xffffff); graphics.moveTo(3,hankei); graphics.lineTo(2*hankei-2 ,hankei); // ↑マイナス符号 if( q> 0 ) { graphics.moveTo(hankei,2); graphics.lineTo(hankei,2*hankei-2); // ↑プラス符号に } } } } class PushButton extends Clickable{ private var txt:TextField; private var label:String; public function PushButton(L:int,Y:int,WW:int,l:String,c:int=0):void { super(L,Y,WW); label=l; txt=new TextField(); txt.text=label; txt.height=18; txt.width=Width; txt.x=2; txt.textColor=c; txt.y=0; addChild(txt); } public override function MUp(e:Event):void { dispatchEvent(new Event("allerase",true)); } } class Check extends Clickable { private var val:Boolean; private var txt:TextField; private var label:String; private var box:Sprite; public function Check(now:Boolean,X:int,Y:int,W:int,l:String,c:int=0):void { super(X,Y,W); val=now; label=l; txt=new TextField(); txt.text=label; txt.height=18; txt.x=16; txt.textColor=c; txt.y=0; addChild(txt); box=new Sprite(); box.buttonMode=true; addChild(box); write(); } public override function MUp(e:Event):void { toggle(); dispatchEvent(new Event("update",true)); } public function setValue(a:Boolean):void { val=a; write(); } public function isChecked():Boolean { return val; } public function toggle():void { setValue(!val); } public function update():void { write(); } public function write():void { box.graphics.clear(); box.graphics.lineStyle(1,0); box.graphics.beginFill(0xffffff); box.graphics.drawRect(1,1,14,14); box.graphics.endFill(); if( val ) { box.graphics.lineStyle(2,0); box.graphics.moveTo(2,11); box.graphics.lineTo(4,11); box.graphics.lineTo(6,13); box.graphics.lineTo(14,3); } } } class ThreeToggle extends Clickable { private var val:int; private var txt:TextField; private var box:Sprite; private var s1:String; private var s2:String; private var s3:String; public function ThreeToggle(ss1:String,ss2:String,ss3:String,L:int,Y:int,WW:int,c:int=0):void { super(L,Y,WW); s1=ss1; s2=ss2; s3=ss3; val=0; box=new Sprite(); txt=new TextField(); txt.text=s1; txt.height=18; txt.x=16; txt.width=Width-30; txt.textColor=c; txt.y=0; addChild(txt); addChild(box); write(); } public override function MUp(e:Event):void { toggle(); update(); } public function setValue(a:int):void { val=a; if( val==0 ) { txt.text=s1; } else if( val==1 ) { txt.text=s2; } else if( val==2 ) { txt.text=s3; } else { txt.text="Something wrong!"; } } public function value():int { return val; } public function toggle():void { val ++; if( val >2 ) {val=0;} setValue(val); } public function update():void { write(); } public function write():void { box.graphics.clear(); box.graphics.lineStyle(1,0); box.graphics.beginFill(0xffffff); box.graphics.drawRect(1,1,14,14); box.graphics.endFill(); box.graphics.lineStyle(1,0x8800000); box.graphics.beginFill(0xee0000); box.graphics.moveTo(2,3); box.graphics.lineTo(8,14); box.graphics.lineTo(14,3); box.graphics.endFill(); } } class Charges { private var chargeList:Array; private var hankei:int=10; private var w:int; private var h:int; function Charges(WW:int,HH:int){ w=WW; h=HH; chargeList=new Array(); Clear(); } public function C(i:int):Charge { return chargeList[i]; } public function hitTest(i:int,mx:int,my:int):Boolean { return chargeList[i].hitTestPoint(mx,my,false); } public function Clear():void { if( chargeList.length > 0 ) { chargeList.splice(0,chargeList.length); } } public function addNew( xx:int,yy:int,qq:int,pp:Sprite ):int { return chargeList.push(new Charge(qq, xx,yy,pp )); } public function size():int {return chargeList.length; } public function X( i:int ):int { return chargeList[i].X(); } public function Y( i:int ):int { return chargeList[i].Y(); } public function Q( i:int ):int { return chargeList[i].Q(); } public function drawMark( gc:Graphics,i:int ):void { var x1:int=chargeList[i].X(); var y1:int=chargeList[i].Y(); var q1:int=chargeList[i].Q(); if( q1 < 0 ) { gc.beginFill(0x0a0a0a ); } else { gc.beginFill(0xaa00000); } gc.drawCircle(x1,y1,hankei); gc.lineStyle(1,0xffffff); gc.moveTo(x1 - hankei + 3,y1); gc.lineTo(x1 + hankei - 2,y1); if( q1 > 0 ) { gc.moveTo(x1,y1 - hankei + 2); gc.lineTo(x1,y1 + hankei - 2); } } public function drawMarks( gc:Graphics ):void { var i:int; for( i=0; i < chargeList.length; i++ ) { drawMark(gc,i); } } public function startDrag(i:int) :void { chargeList[i].startDrag(); } public function endDrag(i:int) :void { chargeList[i].endDrag(); } public function isNear( x1:int,y1:int ):Boolean { var i:int; for( i=0; i < chargeList.length; i++ ) { var xx:int=chargeList[i].X(); var yy:int=chargeList[i].Y(); if( ( xx - x1 )*( xx - x1 ) + ( yy - y1 )*( yy - y1 ) <= hankei*hankei ) { return true; } } return false; } public function deleteOne( i:int ):void { chargeList.splice(i,1); } public function deleteAll():void { chargeList.splice(0); } } class Plate extends Sprite { protected var txt:TextField; protected var Width:int; public function Plate(pp:Sprite,X:int,Y:int,W:int,s:String):void { x=X; y=Y; txt=new TextField(); txt.text=s; txt.height=18; txt.width=W-20; txt.y=0; addChild(txt); Width=W; buttonMode=true; writeNormal(); pp.addChild(this); } protected function writeNormal():void { graphics.clear(); graphics.lineStyle(1,0xaaaaaa); graphics.beginFill(0xdddddd); graphics.drawRect(0,0,Width-1,17); graphics.endFill(); graphics.lineStyle(1,0x666666); graphics.moveTo(1,17); graphics.lineTo(Width-1,17); graphics.lineTo(Width-1,1); } } class Tsumami extends Plate { private var val:int; private var min:int; private var max:int; private var label:String; private var nowDrag:Boolean; private var lever:Sprite; private var mizo:Sprite; public function Tsumami(pp:Sprite,now:int,minimum:int,maximum:int,X:int,Y:int,WW:int,l:String,c:int=0):void { super(pp,X,Y,WW,l); buttonMode=false; nowDrag=false; min=minimum; max=maximum; val=now; label=l; lever=new Sprite(); mizo=new Sprite(); addChild(mizo); addChild(lever); mizo.x=Width/2; mizo.y=6; mizo.buttonMode=true; lever.buttonMode=true; mizo.addEventListener(MouseEvent.MOUSE_UP,mizoMUp); mizo.addEventListener(MouseEvent.MOUSE_OVER,mizoMOver); mizo.addEventListener(MouseEvent.MOUSE_OUT,mizoMOut); stage.addEventListener(MouseEvent.MOUSE_UP,leverMUp); lever.addEventListener(MouseEvent.MOUSE_DOWN,leverMDown); lever.addEventListener(MouseEvent.MOUSE_OVER,leverMOver); lever.addEventListener(MouseEvent.MOUSE_OUT,leverMOut); leverNormal(); mizoNormal(); update(); } public function leverMUp(e:MouseEvent):void { if(nowDrag ) { endDrag(); } } public function leverMOver(e:MouseEvent):void { leverHighlight(); } public function leverMDown(e:MouseEvent):void { goDrag(); } public function mizoMUp(e:MouseEvent):void { var p:Point=localToGlobal(new Point(lever.x,lever.y) ); if( e.stageX < p.x+6 ) { oneDown(); } else { oneUp(); } mizoHighlight(e); } public function mizoMOver(e:MouseEvent):void { mizoHighlight(e); } public function mizoMOut(e:MouseEvent):void { mizoNormal(); } public function mizoNormal():void { mizo.graphics.clear(); mizo.graphics.lineStyle(1,0x555555); mizo.graphics.beginFill(0x555555); mizo.graphics.drawRect(0,0,Width/2-4,5); mizo.graphics.endFill(); mizo.graphics.lineStyle(1,0); mizo.graphics.moveTo(0,5); mizo.graphics.lineTo(0,0); mizo.graphics.lineTo(Width/2-4,0); } public function mizoHighlight(e:MouseEvent):void { if( nowDrag ) { return; } var p:Point=localToGlobal(new Point(lever.x,lever.y) ); mizo.graphics.clear(); mizo.graphics.lineStyle(1,0x555555); mizo.graphics.beginFill(0x555555); mizo.graphics.drawRect(0,0,Width/2-4,5); mizo.graphics.endFill(); mizo.graphics.lineStyle(1,0xffffff); if( e.stageX > p.x+6 ) { mizo.graphics.moveTo(lever.x-mizo.x,0); mizo.graphics.lineTo(Width/2-4,0); mizo.graphics.beginFill(0xaaaa); mizo.graphics.moveTo(lever.x-mizo.x+8,0); mizo.graphics.lineTo(lever.x-mizo.x+18,3); mizo.graphics.lineTo(lever.x-mizo.x+8,6); mizo.graphics.endFill(); } else { mizo.graphics.moveTo(lever.x-mizo.x,0); mizo.graphics.lineTo(0,0); mizo.graphics.lineTo(0,6); mizo.graphics.beginFill(0xaaaa); mizo.graphics.moveTo(lever.x-mizo.x-2,0); mizo.graphics.lineTo(lever.x-mizo.x-12,3); mizo.graphics.lineTo(lever.x-mizo.x-2,6); mizo.graphics.endFill(); } } public function leverMOut(e:MouseEvent):void { if( !nowDrag ) { leverNormal(); } } public function oneUp():void { setValue(val+1); } public function oneDown():void { setValue(val-1); } private function XIchi():int{ return int(Number((Width/2-6)*(val-min))/Number(max-min))+Width/2; } public function goDrag():void { nowDrag=true; leverInDrag(); lever.startDrag(false,new Rectangle(Width/2,0,Width/2-6,0)); } public function endDrag():void { nowDrag=false; leverNormal(); lever.stopDrag(); setValue(min + int(Number((lever.x-Width/2)*(max-min))/Number(Width/2-6)+0.5)); } public function setValue(a:int):void { if( a>max ) { a=max; } if( a<min ) { a=min; } val=a; update(); dispatchEvent(new Event("change",true)); dispatchEvent(new Event("update",true)); } public function value():int { return val; } public function update():void { lever.x=XIchi(); txt.text=label+String(val); } public function leverNormal():void { lever.graphics.clear(); lever.graphics.lineStyle(1,0x333300); lever.graphics.beginFill(0xaa0000); lever.graphics.drawRect(0,0,6,18); lever.graphics.endFill(); } public function leverHighlight():void { lever.graphics.clear(); lever.graphics.lineStyle(1,0xaaaa33); lever.graphics.beginFill(0xaa0000); lever.graphics.drawRect(0,0,6,18); lever.graphics.endFill(); } public function leverInDrag():void { lever.graphics.clear(); lever.graphics.lineStyle(1,0x888800); lever.graphics.beginFill(0xee8888); lever.graphics.drawRect(0,0,6,18); lever.graphics.endFill(); } } Code Fullscreen Preview Fullscreen Thy siouxcitizen.. ep91ckok xor matacat Nicolas : physics physics dispatchEvent label lineStyle Math.min MouseEvent System.gc Vector Math.max localToGlobal text Boolean MouseEvent.MOUSE_OUT MouseEvent.MOUSE_OVER stageX MouseEvent.MOUSE_UP moveTo textColor value height color