본문 바로가기

Software/Processing

Processing에서 진자 운동을 애니메이션으로 시뮬레이션하기

최근 저는 1차 혹은 2차 미분방정식을 직접 프로그램으로 푸는 Runge Kutta를 소개하고 MATLAB m-file을 이용해 구현한 코드를 다루었는데요.[바로가기] 그리고 나서 MATLAB을 아용해서 진자의 자유운동을 애니메이션으로 직접 보여주는 프로그램도 한 번 다루어 보았습니다.[바로가기]^^ 그런데 사실 MATLAB을 또  많이 쓰는 분들이 어디 있겠습니까..ㅠㅠ. 물론 이 글을 보고 미방을 직접 풀 사람도 없을듯 합니다만.ㅠㅠ. 뭐 그래도 이왕하는 김에 예제 하나 더 다루겠습니다. 바로 제가 몇 번 소개했던 적이 있는 Processing인데요. 처음엔

[The Robot/Prog.Lang.] - Processing 프로세싱 언어를 소개합니다.

그냥 어떤 것인지 소개했고... 그리고

[The Robot/Prog.Lang.] - Processing에서 시리얼통신으로 받은 데이터를 그래프로 표현하기

에서는 시리얼통신으로 받은 데이터를 실시간 모니터링의 개념으로 관찰하면서 그래프를 보는 프로그램의 예도 보였는데요. 또 그러다가

[The Robot/Useful SITE and S/W] - Sublime Text에서 사용할 Processing 플러그인

에디터로 Sublime Text도 괜찮다는 이야기까지 했네요^^. 아무튼 이 Processing으로도 한 번 구현해 보죠. 자유 운동하는 진자~~~~^^

최근 MATLAB에서 다룬 그 그림이지요.[바로가기] 그 운동 방정식의 결과는


이었습니다. 이제 코드를 한 번 보시죠.^^.


float h = 0.01, t = 0, x = 30*PI/180, v = 0;
float pen_fm = 0.05, pen_m = 0.1, pen_l = 100*0.01, pen_J = 0.02, pen_g = 9.8;

float gndCenterX = 150, gndCenterY =20, penLength = pen_l*100*2;

PFont font;

void setup() {
	size(300,300);  
	font=loadFont("CenturyGothic-12.vlw");	
}

void draw() {
	background(255);
	fill(255);
  	smooth();
  	stroke(50);
	strokeWeight(10);
	line(10,20,290,20);
	stroke(0);
	strokeWeight(3);
	ellipse(gndCenterX,gndCenterY,15,15);

	drawText();

	drawPendulum(x);

	float[] states = solveODEusingRK4(t, x, v);

	delay(10);

	x = states[0];
	v = states[1];
	t = t + h;
}

void drawPendulum(float theta) {
	float updatedX = gndCenterX + penLength*sin(theta);
	float updatedY = gndCenterY + penLength*cos(theta);

	fill(255);
	stroke(150);
	strokeWeight(2);
    line(gndCenterX, gndCenterY, updatedX, updatedY);
    stroke(0);
    ellipse(updatedX, updatedY, 20, 20);
}

float[] solveODEusingRK4(float t, float x, float v){
	float kx1 = v;
	float kv1 = calcODEFunc( t, x, v );
	 
	float kx2 = v + h*kv1/2;
	float kv2 = calcODEFunc( t + h/2, x + h*kx1/2, v + h*kv1/2 );
	 
	float kx3 = v + h*kv2/2;
	float kv3 = calcODEFunc( t + h/2, x + h*kx2/2, v + h*kv2/2 );
	 
	float kx4 = v + h*kv3;
	float kv4 = calcODEFunc( t + h, x + h*kx3, v + h*kv3 );
	 
	float dx = h*(kx1 + 2*kx2 + 2*kx3 + kx4)/6;
	float dv = h*(kv1 + 2*kv2 + 2*kv3 + kv4)/6;
    
    float[] result = {x+dx, v+dv};

    return result;
}

float calcODEFunc(float tVal, float xVal, float vVal) {
	return -pen_fm/(pen_m*pen_l*pen_l+pen_J)*vVal-pen_m*pen_g*pen_l/(pen_m*pen_l*pen_l+pen_J)*xVal;
}

void drawText() {
	fill(50);
	textFont(font);
  	text("by PinkWink",200,280);
}


위 코드에서 solveODEusingRK4가 최근 다룬 Runge Kutta[바로가기]가 됩니다. 그리고, 나머지는 역시 간단합니다만.. draw함수에 있는 delay의 숫자는 좀 높이셔야할 겁니다.ㅠㅠ. 제 PC가 2009년에 구입한 노트북인데요.[바로가기]  뭐 엄청 느리답니다. 혹시 집에 안쓰는 애플 노트북 있으시면 저렴하게 분양 부탁드립니다.ㅠㅠ. 노트북 사달라고 와이푸님한테 말할 수가 없어요.ㅠㅠ....

뭐 여하튼~~~

저런 결과를 가져올 코드입니다. 흠.. 사실 같은 노력을 투자한다면 확실히 그래픽한 부분은 저는 Processing이 정말 마음에 듭니다. 간결하고 이쁘죠~~^^ 뭐 여하튼 요것도 동영상이 있습니다.

뭐 아무튼... 좋은 프로그램을 익히는건 참 즐거운 일입니다. 항상 배우고 또 구현하고 또 이렇게 널리널리 알리고~~~ 하는 과정이 좋아요.. ㅎㅎㅎ^^ 그럼 전 이만~~~


반응형