アットウィキロゴ

点電荷の作る電場

  • 発表者:南波 拓也
  • 2011年度夏合宿
  • 使用言語:c
  • 使用ライブラリ:Dxライブラリ
  • 添付資料:夏合宿発表資料2011

概要

点電荷の電場は次式によりもとめられる、
{\bf E}=k\frac{q}{|{\bf r}|^_{3}}} {\bf r}

結果


考察


感想


参考文献


ソースコード

#include "DxLib.h"
#include "math.h"
 
const double Pi = 3.14159;                      //円周率π
double ips= 8.85/pow(10,12.5);			//真空の誘電率ε0
double k  = 1/(4*Pi*ips);                       //比例係数k
double e  = 1.6/pow(10,7);			//電気素量e 
char Key[256];                                  //キー取得
 
int pros[10], prosn;				//処理制限...
int Blue, Red, White, Purple;		     	//各種色
int num, Now_e;					//電荷の個数
double x[50][50], y[50][50], r[50][50];         //観測点のx,y座標と観測点までの距離r
double x1, y1, xn[10], yn[10];			//n個目の電荷の位置xn,yn
double Ex[50][50], Ey[50][50];                  //重ね合わせた電場Ex,Ey
double Exn[50][50][10], Eyn[50][50][10];	//n個目の電荷の作る電場Exn,Eyn
double e_size[10];				//n個目の電荷量
double magni;					//描画倍率
int SelectNum = 0; 				// 現在の選択番号
int SelectNum_a = 0;				//pros[4]の現在選択番号
 
 
// メニュー項目の表示に必要な構造体を用意する
typedef struct{
        int x, y;       // 座標格納用変数
        char name[128]; // 項目名格納用変数
} MenuElement_t ;
 
int gpUpdateKey();				//キー入力更新(コピペ)
void Move_A(int i, int j);			//
void Move_B_en(int i, int j, int k);		//
void Move_B_ex(int i, int j);			//
void Back(int pict);				//背景表示
void En(double X, double Y, double e, int num);	//
void E(int num);				//
double EUnit(int i,int j);			//電場を
 
 
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
        if( ChangeWindowMode(FALSE) != DX_CHANGESCREEN_OK || DxLib_Init() == -1 ) return -1; //初期化処理
        SetDrawScreen( DX_SCREEN_BACK );        //裏画面に設定
 
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
	int i,j,k,l;
 
	// メニュー項目要素を5つ作る
        MenuElement_t MenuElement[5]={
                {  80, 100, "電荷の数" }, // タグの中身の順番で格納される。xに80が、yに100が、nameに"ゲームスタート"が
                { 100, 150, "電荷の位置" },
                { 100, 200, "電荷の強さ" },
                { 100, 250, "移動させる電荷" },
                { 100, 300, "設定をデフォルト" },
        };
 
	White = GetColor( 255, 255, 255 );	// 白色...
	Blue  = GetColor( 100,   0, 200 ); 	// 青色...
	Red   = GetColor( 200,   0, 100 );	// 赤色...
	Purple = GetColor( 255,  0, 255 );      // 紫色...
 
	magni = 10.0;
	num   = 1;
	Now_e = 0;
 
	//各電荷の初期化
	for(i=0;i<num;i++){e_size[i]=e;}
	//e_size[0] = e;
	/*
	e_size[1] = -e;
	e_size[2] = -e;
	e_size[3] = e;
	*/
	//個数分の電荷の位置初期化
	for(i=0;i<num;i++){
		xn[i] = 25.5*magni;
		yn[i] = 25.5*magni;
	}
	/*
	xn[2] = 25.5*magni;
	yn[2] = 10.0*magni;
	xn[3] = 40.5*magni;
	yn[3] = 10.0*magni;
         */
 
	//各電荷の作る電場初期化
	for(l=0;l<num;l++){
		for(i=0;i<50;i++){
			for(j=0;j<50;j++){
				Exn[i][j][l] = 0.0;
				Eyn[i][j][l] = 0.0;				
			}
		}
	}
 
	//重ね合わせた電場及び観測点との距離初期化
	for(i=0;i<50;i++){
		for(j=0;j<50;j++){
			r[i][j]   = 0.0;
			Ex[i][j]  = 0.0;
			Ey[i][j]  = 0.0;
		}
	}
 
	//観測点位置初期化(50×50の観測点)
	for(i=0;i<50;i++){
		for(j=0;j<50;j++){
			x[i][j] = magni*i;
			y[i][j] = magni*j;
		}
	}
 
	//処理制限初期化			
	for(i=0;i==9;i++){pros[i] = 0;}
 
	prosn = 0;
	pros[1] = 1;						//処理を段階1へ...
 
	int Back1,Back2,Back3,Back4,Back5;
	Back1 = LoadGraph( "coil.png" );				// 画像をロード
	Back2 = LoadGraph( "coil-a.png" );
	Back3 = LoadGraph( "coil-b.png" );
	Back4 = LoadGraph( "coil-c.png" );
	Back5 = LoadGraph( "coil-d.png" );		
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
        while(!ProcessMessage() && !ClearDrawScreen() && gpUpdateKey()==0 && !Key[KEY_INPUT_ESCAPE] ){
              //↑メッセージ処理         ↑画面をクリア          ↑キーボード入力状態取得       ↑ESCが押されていない		
		if(pros[0]==1){
			DrawString(100,400, "上下左右キーで動くよ!" , White);//文字列表示
 
			for(i=0;i<=num;i++){En(xn[i], yn[i], e_size[i], i);}
			E(num);
 
			for(i=0;i<50;i++){
				for(j=0;j<50;j++){
					DrawLine( 50+(10*i) , (10*j) ,
						 50+(10*i)+10*Ex[i][j]*EUnit(i,j) ,
						 (10*j)+10*Ey[i][j]*EUnit(i,j) ,
						 White , TRUE);
					DrawBox(50+(10*i)+10*Ex[i][j]*EUnit(i,j)-1 , (10*j)+10*Ey[i][j]*EUnit(i,j)-1 ,
						50+(10*i)+10*Ex[i][j]*EUnit(i,j)+1 , (10*j)+10*Ey[i][j]*EUnit(i,j)+1 ,
						Purple,TRUE);
					Ex[i][j] = 0.0; 
					Ey[i][j] = 0.0;
				}
			}
 
			for(i=0;i<num;i++){
				if(e_size[i]>0){DrawCircle(50+xn[i] ,yn[i] ,2 ,Red ,TRUE);}
				else{DrawCircle(50+xn[i] ,yn[i] ,2 ,Blue ,TRUE);}
				DrawFormatString(60+xn[i], 10+yn[i], White, "電荷%d", i);
			}
 
 
			if( CheckHitKey( KEY_INPUT_LEFT )  == 1 ){xn[Now_e] -= 2.0;}
			if( CheckHitKey( KEY_INPUT_RIGHT ) == 1 ){xn[Now_e] += 2.0;}
			if( CheckHitKey( KEY_INPUT_UP )    == 1 ){yn[Now_e] -= 2.0;}
			if( CheckHitKey( KEY_INPUT_DOWN )  == 1 ){yn[Now_e] += 2.0;}
 
			Move_A(0,1);
			prosn+=1;	
		}
 
		if(pros[1]==1){
			if(SelectNum==0){Back(Back2);}
			if(SelectNum==1){Back(Back3);}
			if(SelectNum==2){Back(Back4);}
			if(SelectNum==3){Back(Back5);}
			if(SelectNum==4){Back(Back1);}
			// 計算フェーズ 
                	if( Key[ KEY_INPUT_DOWN ] == 1 ){ // 下キーが押された瞬間だけ処理
                        	SelectNum = ( SelectNum + 1 ) % 5; // 現在の選択項目を一つ下にずらす(ループする)
                        	for( int i=0; i<5; i++ ){		// メニュー項目数である5個ループ処理
                                	if( i == SelectNum ){ MenuElement[i].x = 80; }// 選択番号と同じ要素なら
					else{ MenuElement[i].x = 100; }// 選択番号以外なら
                        	}
                	}
 
                	if( Key[ KEY_INPUT_UP ] == 1 ){ 
                        	SelectNum = ( SelectNum + 4 ) % 5;
                        	for( int i=0; i<5; i++ ){              // メニュー項目数である5個ループ処理
                                	if( i == SelectNum ){ MenuElement[i].x = 80; }// 選択番号と同じ要素なら
                                	else { MenuElement[i].x = 100; }// 選択番号以外なら
                       		 }
                	}
 
                	// 描画フェーズ
                	for( int i=0; i<5; i++ ){ // メニュー項目を描画
                        	DrawFormatString( MenuElement[i].x, MenuElement[i].y, GetColor(0,200,150), MenuElement[i].name );
                	}
 
			Move_A(1,0);
			Move_B_en(1,2,0);
			Move_B_en(1,3,1);
			Move_B_en(1,4,2);
			Move_B_en(1,5,3);		
			prosn+=1;
		}
 
		if(pros[2]==1){
			Back(Back1);
                       	DrawFormatString( 200, 100, GetColor(200,200,255), "電荷の数:%d",num );
			DrawString( 200, 120, "正常動作は電荷9個まで(>_<)", Purple );
			if( Key[ KEY_INPUT_DOWN ] == 1 ){ num -= 1; }
			if( Key[ KEY_INPUT_UP ] == 1 ){ num += 1; }
 
			if( CheckHitKey( KEY_INPUT_RETURN )  == 1 ){
				Move_B_ex(2,1);
				for(i=0;i<num;i++){e_size[i]=e;}
				for(i=0;i<num;i++){
					xn[i] = 25.5*magni;
					yn[i] = 25.5*magni;
				}
			}
 
			prosn+=1;	
		}
 
		if(pros[3]==1){
			Back(Back1);
			for(i=0;i<num;i++){
				DrawFormatString( 200, 100+i*50, GetColor(200,200,255), "電荷%d x:%f y:%f",i,xn[i]/magni,yn[i]/magni );
			}
 
			Move_B_ex(3,1);			
			prosn+=1;
		}
 
		if(pros[4]==1){
			Back(Back1);
			for(i=0;i<num;i++){
				if(SelectNum_a==i){DrawFormatString( 180, 100+i*50, GetColor(200,200,255), "電荷%dの大きさ:%fe",i,e_size[i]/e );}
				else{DrawFormatString( 200, 100+i*50, GetColor(200,200,255), "電荷%dの大きさ:%fe",i,e_size[i]/e );}
			}
			if( Key[ KEY_INPUT_DOWN ] == 1 ){ SelectNum_a = (SelectNum_a + 1)%num; }
			if( Key[ KEY_INPUT_UP ] == 1 ){ SelectNum_a = (SelectNum_a + (num-1))%num; }
			if( Key[ KEY_INPUT_RIGHT ] == 1 ){ e_size[SelectNum_a] +=e ; }
          		if( Key[ KEY_INPUT_LEFT ] == 1 ){ e_size[SelectNum_a] -=e ; }
 
 
			Move_B_ex(4,1);			
			prosn+=1;						
		}
 
		if(pros[5]==1){
			Back(Back1);
			DrawFormatString( 200, 100, GetColor(200,200,255), "動かす電荷→電荷%d",Now_e );
			if( Key[ KEY_INPUT_DOWN ] == 1 ){ Now_e = (Now_e+num-1)%num; }
			if( Key[ KEY_INPUT_UP ] == 1 ){ Now_e = (Now_e+1)%num; }
			Move_B_ex(5,1);			
			prosn+=1;
		}	
		ScreenFlip();	
	}
 
        DxLib_End();
        return 0;
}
 
 
int gpUpdateKey(){
        char tmpKey[256]; // 現在のキーの入力状態を格納する
        GetHitKeyStateAll( tmpKey ); // 全てのキーの入力状態を得る
        for( int i=0; i<256; i++ ){ 
                if( tmpKey[i] != 0 ){ // i番のキーコードに対応するキーが押されていたら
                        Key[i]++;     // 加算
                } else {              // 押されていなければ
                        Key[i] = 0;   // 0にする
                }
        }
        return 0;
}
 
void Move_A(int i, int j)
{
	if(prosn > 1 && Key[ KEY_INPUT_SPACE ] == 1 ){
		pros[i]=0;
		pros[j]=1;
		prosn=0;
	}
}
 
void Move_B_en(int i, int j, int k)
{
	if(prosn > 1 && Key[ KEY_INPUT_RETURN ] == 1 && SelectNum==k ){
		pros[i]=0;
		pros[j]=1;
		prosn=0;
	}
}
 
void Move_B_ex(int i, int j)
{
	if(prosn > 1 && Key[ KEY_INPUT_RETURN ] == 1 ){
		pros[i]=0;
		pros[j]=1;
		prosn=0;
	}
}
 
void Back(int pict)
{
	SetDrawBlendMode( DX_BLENDMODE_ALPHA,  100 );		//ブレンドモードをαに設定
	DrawGraph( 0, 0,pict , TRUE );
	SetDrawBlendMode( DX_BLENDMODE_NOBLEND,  0 );		//ブレンドモードをオフ
}
 
void En(double X, double Y, double e, int num)
{
	int i,j;
	for(i=0;i<50;i++){
		for(j=0;j<50;j++){
			r[i][j]      = sqrt(pow(X-x[i][j],2)+pow(Y-y[i][j],2));
			Exn[i][j][num] = ((k*e)/(r[i][j]*r[i][j]*r[i][j]))*(x[i][j]-X);
			Eyn[i][j][num] = ((k*e)/(r[i][j]*r[i][j]*r[i][j]))*(y[i][j]-Y);
		}
	}
}
 
void E(int num){
	int i,j,k;
	for(i=0;i<50;i++){
		for(j=0;j<50;j++){
			for(k=0;k<num;k++){
				Ex[i][j] += Exn[i][j][k]; 
				Ey[i][j] += Eyn[i][j][k];
			}
		}
	}
}
 
double EUnit(int i,int j){
	return 1.0/sqrt(pow(Ex[i][j],2)+pow(Ey[i][j],2));
}
 

タグ:

+ タグ編集
  • タグ:
最終更新:2011年10月05日 20:49