검색결과 리스트
processing에 해당되는 글 5건
- 2017.01.11 [프로세싱] 클래스 Arrow
- 2013.11.27 프랙탈 나무
- 2013.11.22 시에르핀스키 삼각형
- 2013.04.09 [Processing] 기체분자의 확산(2)
- 2013.04.02 [Processing] 기체분자의 확산(1)
글
[프로세싱] 클래스 Arrow
[이 글은 제 개인 블로그 새길 공작소(http://saegil-lab.kr) 에도 함께 올린 글입니다.]
아래 소스는 프로세싱에서 사용할 수 있는 화살표를 그리는 클래스입니다. 오늘 아이들과 프로세싱 수업하면서 삼각형의 위치 계산하며 만든 화살표 클래스입니다.
그래프를 그릴 때 x축과 y축을 화살표를 그리기 위해 제작했습니다. 그 이외에도 힘을 표시한다거나 할 때 유용하게 사용할 수 있을 것입니다.
- 예제 : 이 예제는 (100, 100)인 점에서 (200, 200)인 점으로 화살표를 그리고 화살표의 끝점이 이동할 때 화살표의 모양을 보기 위한 예제입니다.
Arrow a; float y2 = 100; void setup(){ size(400, 400); a = new Arrow( 100, 100, 200, 200); } void draw(){ background(255); a.display(); a.setP2(200, y2); y2 = y2 + 1; if (y2 > height) { y2 = 0; } }
클래스 Arrow 소스
/** * Processing class for drawing arrow * by Eom Taeho * * http://saegil-lab.kr * http://saegil.tistory.com */ class Arrow{ float x1, y1, x2, y2; Arrow(float x1_, float y1_, float x2_, float y2_){ x1 = x1_; y1 = y1_; x2 = x2_; y2 = y2_; } void display(){ stroke(0); line(x1, y1, x2, y2); float x, y, a, b, c, d, theta; theta = atan((y2-y1)/(x2-x1)); if ((x2 - x1) < 0){
theta = -(PI - theta);
}
x = x2 - 10*cos(theta); y = y2 - 10*sin(theta); a = x - 5*sin(theta); b = y + 5*cos(theta); c = x + 5*sin(theta); d = y - 5*cos(theta); fill(0); triangle(x2, y2, a, b, c, d); } void setP1(float x1_, float y1_){ x1 = x1_; y1 = y1_; } void setP2(float x2_, float y2_){ x2 = x2_; y2 = y2_; } }
아래 그림은 화살표를 그릴 때 삼각형을 그리기 위한 계산과정입니다. 참고하세요.
'과학이야기 > 물리학' 카테고리의 다른 글
엑셀을 이용한 등가속도 운동의 분석 (0) | 2017.11.14 |
---|---|
[프로세싱] 종단속도 룽게-쿠타 계산 링크 (0) | 2017.01.11 |
mp4동영상에서 다중섬광사진 뽑아내기 (0) | 2016.11.11 |
mp4파일을 압축되지 않은 AVI파일로 변환하는 프로그램 (0) | 2016.10.20 |
파동의 굴절 - 스넬 법칙 (7) | 2016.05.11 |
글
프랙탈 나무
[이 글의 프로세싱(Processing) 애니메이션은 크롬이나, IE9이상에서 작동됩니다.]
어제 아이들과 프랙탈 이미지를 만드는 것을 해 봤습니다. 간단하게 칠판에다 나무가 자라는 모습을 그려 보았는데, 오늘 프로세싱으로 구현을 해 봤습니다. 다음은 나무가 특정한 규칙에 의해 자라나는 모습을 프로세싱으로 시뮬레이션해본 모습입니다. 1초에 1단계씩 진행되며 총 9단계가 진행되는 모습입니다. 프로그래밍의 편의를 위해 옆으로 자라난다고 가정하고 시뮬레이션을 해 봤습니다.
규칙은 다음과 같습니다.
위의 그림에서 초록색으로 표시된 것이 첫 단계입니다. 그리고 옆으로 가지가 각각 1/3, 2/3, 그리고 끝부분에서, 각각 ,
,
각도로 뻗어 나오고 자라는 길이는 원래 길이의 80%까지 자란다고 가정했습니다. 위의 시뮬레이션에서는
=-10도,
=10도,
=5도로 시뮬레이션을 했습니다.
그리고 뻗어나온 가지에서도 역시 같은 규칙에 의해 뻗어나온다고 했을 때 총 10단계가 진행되는 모습을 시뮬레이션해 본 것입니다.
위의 그림에서는 위로 자라나는 모습으로 보여드리는데 시뮬레이션에서는 간단하게 하기 위해 옆으로 자라난다고 가정하고 시뮬레이션을 했습니다. 소스를 공개하니 적당히 알아서 수정해 보시기 바랍니다.
아래는 1단계부터 9단계까지 진행되는 모습을 단계별로 저장하고 그림을 회전시켜 놓았습니다. 참고하시기 바랍니다.
[새길]
int m = 1;
float scale = 0.8; //뻗어나온 가지가 자라는 비율
void setup() {
size(400, 400);
smooth();
background(255);
frameRate(1);
}
void draw() {
background(255);
drawTree( 0, height/2, -10, 10, 5, 100, m);
m = m + 1;
if (m > 9) {
m = 1;
}
}
void drawTree(float x, float y, float theta1, float theta2, float theta3, float len, int level) {
stroke(0, 255*(10-level)/10, 0);
strokeWeight(level/3);
pushMatrix();
translate(x, y);
line(0, 0, len, 0);
if (level > 1) {
level = level - 1;
pushMatrix();
translate( len/3, 0);
rotate(radians(theta1));
drawTree(0, 0, theta1, theta2, theta3, len*scale, level);
popMatrix();
pushMatrix();
translate( len*2/3, 0);
rotate(radians(theta2));
drawTree(0, 0, theta1, theta2, theta3, len*scale, level);
popMatrix();
pushMatrix();
translate( len, 0);
rotate(radians(theta3));
drawTree(0, 0, theta1, theta2, theta3, len*scale, level);
popMatrix();
}
popMatrix();
}
이 글이 마음에 드시면 아래 손가락 한번 꾹 찍어주세요...^_^
'과학이야기 > 물리학' 카테고리의 다른 글
등전위면 그리기 계산 (0) | 2013.12.03 |
---|---|
전기장 그리기 계산 (0) | 2013.12.03 |
시에르핀스키 삼각형 (0) | 2013.11.22 |
회전된 좌표계에서 본 벡터의 표현 (0) | 2013.05.07 |
2차원 충돌 후의 물체의 속력 계산 (1) | 2013.04.10 |
글
시에르핀스키 삼각형
아래는 시에르핀스키 삼각형을 구현하는 프로세싱 애니메이션입니다. 잘 지켜보시면 삼각형의 형태가 나타날 것입니다. 그리고 애니메이션이 되고 있는 그림을 마우스로 클릭하시면 새로 그리기 시작합니다.
먼저 다음과 같이 세점 A, B, C와 그 안의 임의의 점 D가 있다고 가정해 봅시다.
이제 주사위를 던저 1이나 2가 나오면 A와 D의 중점에 점을 찍고, 3이나 4가 나오면 B와 D사이의 중점에 점을 찍고. 5나 6이 나오면 C와 D사이에 점을 찍습니다. 그리고 새롭게 찍힌 점을 다시 출발점으로 삼고 다시 주사위를 계속 던저 같은 과정을 반복합니다. 그러면 아래와 같은 그림을 얻을 수 있습니다.
아래는 1000번 정도 찍었을 때의 모습입니다.
아래는 5000번 정도 찍었을 때의 모습입니다.
아래는 10000번 정도 찍었을 때의 모습이니다.
이렇듯이 주사위를 던지는 횟수를 점점 더 늘려 갈수록 패턴은 더욱 뚜렸해지는데, 이런 프랙탈 이미지를 '시에르핀스키 삼각형'이라고 합니다.
바츌라프 시에르핀스키(Waclaw Sierpinski)(1882-1969)는 폴란드 수학자로 집합론에서 뛰어난 논문을 많이 남겼습니다. 그는 1915년에 시에르핀스키 삼각형을 발견했는데, 이것은 훗날 말덴브로가 프랙탈을 연구하는데 많은 영감을 주었습니다. 시에르핀스키 삼각형은 프랙탈의 단순한 형태라고 할 수 있습니다.
시에르핀스키 삼각형을 구현하는 프로세싱 코드는 다음과 같습니다. 여기서는 주사위를 던지는 대신에 1, 2, 3중에서 난수를 뽑아 점을 찍게 했습니다. 아래 소스를 복사하셔서 프로세싱에 붙여 넣으면 작동이 됩니다.
int x1, y1, x2, y2, x3, y3;
int x, y;
int dice;
void setup() {
size(400, 400);
background(255);
stroke(0);
x1 = width/2;
y1 = 0;
x2 = 0;
y2 = height;
x3 = width;
y3 = height;
x = width/2;
y = height/2;
point(x, y);
}
void draw() {
dice = int(random(0, 4));
if (dice == 1) {
x = (x + x1)/2;
y = (y + y1)/2;
} else if (dice == 2) {
x = (x + x2)/2;
y = (y + y2)/2;
} else if (dice == 3) {
x = (x + x3)/2;
y = (y + y3)/2;
}
point(x, y);
}
void mousePressed() {
background(255);
}
[새길]
[이 글이 마음에 드시면 아래 손가락을 한번 꾹 눌러 주세요...^_^]
'과학이야기 > 물리학' 카테고리의 다른 글
전기장 그리기 계산 (0) | 2013.12.03 |
---|---|
프랙탈 나무 (0) | 2013.11.27 |
회전된 좌표계에서 본 벡터의 표현 (0) | 2013.05.07 |
2차원 충돌 후의 물체의 속력 계산 (1) | 2013.04.10 |
[Processing] 기체분자의 확산(2) (0) | 2013.04.09 |
글
[Processing] 기체분자의 확산(2)
지난주에 기체분자의 확산현상을 시뮬레이션한 것을 올렸습니다.
기체의 확산과 관련해서 조금 부연설명을 하려고 합니다.
먼저 왼쪽에 분자 1개가 있다고 가정해 보겠습니다. 그 분자가 움직이면 오른쪽으로도 이동을 합니다. 이 분자 1개가 왼쪽에 있을 확률은 1/2입니다.
그럼 2개의 분자가 있을 때는 어떨까 생각해 보겠습니다. 이 2개의 분자가 동시에 왼쪽에 있을 확률은 이 됩니다.
20개의 분자가 있을 때 20개의 분자가 동시에 왼쪽에 있을 확률을 계산해보면
이 됩니다. 즉, 거의 0이라고 봐야 겠지요.
실제 엄청나게 많은 기체 분자가 어느 한 쪽에 있다가 확산이 일어난 후 다시 원래 상태인 왼쪽으로 모일 확률은 거의 0입이다. 즉 다시 원상태로 돌려놓을 수 없다고 보는 것이 맞겠죠. 이런 현상을 우리말로 이야기 한다면 '무질서도'가 증가한다라고 합니다. 처음에는 한쪽에 정리되어 있지만 자연스럽게 무질서한 상태가 되고 저절로는 원래의 상태로 돌아갈 수는 없다는 것입니다. 이 무질서도를 영어로 '엔트로피(entropy)'라고 한답니다. 이 시스템에서는 엔트로피가 증가하게 되는 것이지요.
엔트로피에 대한 자세한 이야기는 생략하도록 하겠습니다. 수식을 써 넣는 것도 일이고, 일반인들을 상대로 하는 이 블로그의 취지에도 맞지 않으니까요. 자세한 것을 공부하고 싶으시다면 열역학에 관한 책이나 통계역학에 관한 책을 읽어 보시면 될 것 같습니다.
오늘은 여기까지 입니다. 좋은 하루 되세요.
--------------------------------------------------------
2014.03.25 추가 : 아래는 위에서 사용한 시뮬레이션의 소스크드입니다. 이 소스코드의 두번째 줄의 int num = 1;에서 숫자가 분자의 숫자입니다. 이 숫자를 바꾸시면 다양한 갯수의 분자의 운동모습을 시뮬레이션해볼 수 있습니다.
int rad=1;
int num = 1;
float[] xpos = new float[num];
float[] ypos = new float[num];
float xspeed = 5;
float yspeed = 5;
float[] xdirection = new float[num];
float[] ydirection = new float[num];
float[] unitDirectionMagnitude = new float[num];
void setup(){
size(540, 200);
noStroke();
frameRate(30);
background(0);
rectMode(CORNER);
fill(105);
rect(0, 0, 430/2, height);
for(int i=0; i < num; i++) {
xpos[i] = random(0, 430/2);
ypos[i] = random(0, height);
xdirection[i] = random(-1, 1);
ydirection[i] = random(-1, 1);
unitDirectionMagnitude[i] = sqrt((xdirection[i]*xdirection[i] + ydirection[i]*ydirection[i]));
ellipse(xpos[i], ypos[i], rad, rad);
}
}
void draw(){
int leftCount, rightCount;
if (mousePressed && (mouseButton == LEFT)) {
update();
}
background(0);
rectMode(CORNER);
fill(105);
rect(0, 0, 430/2, height);
leftCount = 0;
rightCount = 0;
for (int i=0; i < num; i++) {
xpos[i] = xpos[i] + (xspeed * xdirection[i]/unitDirectionMagnitude[i]);
ypos[i] = ypos[i] + (yspeed * ydirection[i]/unitDirectionMagnitude[i]);
if (xpos[i] > 430 - rad || xpos[i] < rad) {
xdirection[i] *= -1;
}
if ((ypos[i] > height - rad) || (ypos[i] < rad)) {
ydirection[i] *= -1;
}
ellipseMode(RADIUS);
fill(255);
ellipse(xpos[i], ypos[i], rad, rad);
}
for (int i = 0; i < num; i++) {
if (xpos[i] < 430/2) {
leftCount += 1;
}
}
rightCount = num - leftCount;
stroke(255);
rect(680, 20, 50, 150);
rect(740, 20, 50, 150);
noStroke();
textSize(12);
fill(105);
rect(459, 20+(150-(150*leftCount/num)), 30, 150*leftCount/num);
text("Left", 459, 190);
fill(200);
rect(500, 20+(150-(150*rightCount/num)), 30, 150*rightCount/num);
text("Right", 500, 190);
//output.print(leftCount);
//output.print(",");
//output.println(rightCount);
}
void update() {
for(int i=0; i < num; i++) {
xpos[i] = random(0, 430/2);
ypos[i] = random(0, height);
xdirection[i] = random(-1, 1);
ydirection[i] = random(-1, 1);
unitDirectionMagnitude[i] = sqrt((xdirection[i]*xdirection[i] + ydirection[i]*ydirection[i]));
ellipse(xpos[i], ypos[i], rad, rad);
}
}
[새길]
[이 글이 마음에 드시면 아래 손가락 한번 꾹 찍어 주세요...^_^]
'과학이야기 > 물리학' 카테고리의 다른 글
회전된 좌표계에서 본 벡터의 표현 (0) | 2013.05.07 |
---|---|
2차원 충돌 후의 물체의 속력 계산 (1) | 2013.04.10 |
[Processing] 기체분자의 확산(1) (0) | 2013.04.02 |
물 위를 걷는 사람들 (0) | 2013.03.06 |
바실리스크 도마뱀 (0) | 2013.03.06 |
글
[Processing] 기체분자의 확산(1)
Processing Simulation : 기체분자의 확산(1)
브라우져에 따라 다른 시뮬레이션이 보이기도 하고 보이지 않기도 합니다.
테스트결과 시뮬레이션 결과가 크롬에서는 잘 보이는데 익스플로러 8에서는 잘 안보이네요. 스크립트 오류가 나옵니다. 익스플로러 10에서는 잘 보이는지 모르겠습니다.
익스플로러 말고 크롬에서 보시기 바랍니다.
크롬 다운받기 : https://www.google.com/intl/ko/chrome/browser/
이 시뮬레이션은 Processing을 이용하여 기체분자의 확산현상을 관찰해본 것입니다.
Processing 다운로드 받기 : http://processing.org/
[컨트롤기능 추가] 시뮬레이션 화면을 마우스로 클릭하시면 시뮬레이션을 다시시작합니다.
왼쪽에 몰려 있던 10,000개의 기체분자들이 기체가 들어있지 않던 오른쪽으로 확산하는 모습을 시뮬레이션해 봤습니다.
[시뮬레이션 기본 가정]
1. 기체분자는 벽과 완전탄성충돌한다.(즉, 충돌했을 때 운동방향만 바뀌고, 속력은 변하지 않는다.)
2. 기체분자 자체의 충돌은 무시(충돌이 일어날 경우는 다음에 다시 시뮬레이션을 해 보도록 하겠습니다.)
3. 기체의 속력은 균일하다. - 실제로는 기체분자의 속력이 제각각 다르지만 이 시뮬레이션에서는 같다고 가정하고 진행했습니다.
4. 기체의 처음 운동방향은 각각 다르다. - 시뮬레이션 초기단계에서 각 기체의 운동방향을 랜덤하게 잡았습니다.
[시뮬레이션 결과]
확산 초기 - 확산이 시작되면서 많은 수의 분자들이 오른쪽으로 이동하는 것을 확인할 수 있었습니다. 또한 왼쪽으로 이동하던 분자들도 벽과 충돌하여 많은 분자들이 오른쪽으로 이동하였습니다.
분자들의 이동상황을 텍스트파일로 저장하여 엑셀에서 그래프를 그려본 결과는 다음과 같습니다.
그래프에서 볼 수 있는 것과 같이 왼쪽에 있던 분자들이 오른쪽으로 이동하면서 감쇠진동과 같은 형태를 이루면서 분자의 수가 변하는 것을 확인할 수 있었습니다. 데이터는 좀 더 분석을 해봐야 할 것 같습니다.
----------------------------------------------------------------
2014.03.25일 추가 : 이 포스트에서 사용한 시뮬레이션 소스는 아래와 같습니다. 복사하셔서 프로세싱에 넣고 실행하시면 시뮬레이션 모습을 보실 수 있습니다.
int rad=1; int num = 10000; float[] xpos = new float[num]; float[] ypos = new float[num]; float xspeed = 1; float yspeed = 1; float[] xdirection = new float[num]; float[] ydirection = new float[num]; float[] unitDirectionMagnitude = new float[num]; PrintWriter output; void setup(){ size(540, 360); noStroke(); frameRate(30); background(0); rectMode(CORNER); fill(105); rect(0, 0, 430/2, height); for(int i=0; i < num; i++) { xpos[i] = random(0, 430/2); ypos[i] = random(0, height); xdirection[i] = random(-1, 1); ydirection[i] = random(-1, 1); unitDirectionMagnitude[i] = sqrt((xdirection[i]*xdirection[i] + ydirection[i]*ydirection[i])); ellipse(xpos[i], ypos[i], rad, rad); } } void draw(){ int leftCount, rightCount; if (mousePressed && (mouseButton == LEFT)) { update(); } background(0); rectMode(CORNER); fill(105); rect(0, 0, 430/2, height); leftCount = 0; rightCount = 0; for (int i=0; i < num; i++) { xpos[i] = xpos[i] + (xspeed * xdirection[i]/unitDirectionMagnitude[i]); ypos[i] = ypos[i] + (yspeed * ydirection[i]/unitDirectionMagnitude[i]); if (xpos[i] > 430 - rad || xpos[i] < rad) { xdirection[i] *= -1; } if ((ypos[i] > height - rad) || (ypos[i] < rad)) { ydirection[i] *= -1; } ellipseMode(RADIUS); fill(255); ellipse(xpos[i], ypos[i], rad, rad); } for (int i = 0; i < num; i++) { if (xpos[i] < 430/2) { leftCount += 1; } } rightCount = num - leftCount; stroke(255); rect(680, 20, 50, 150); rect(740, 20, 50, 150); noStroke(); textSize(12); fill(105); rect(459, 20+(150-(150*leftCount/num)), 30, 150*leftCount/num); text("Left", 459, 190); fill(200); rect(500, 20+(150-(150*rightCount/num)), 30, 150*rightCount/num); text("Right", 500, 190); //output.print(leftCount); //output.print(","); //output.println(rightCount); } void update() { for(int i=0; i < num; i++) { xpos[i] = random(0, 430/2); ypos[i] = random(0, height); xdirection[i] = random(-1, 1); ydirection[i] = random(-1, 1); unitDirectionMagnitude[i] = sqrt((xdirection[i]*xdirection[i] + ydirection[i]*ydirection[i])); ellipse(xpos[i], ypos[i], rad, rad); } }
[새길]
[이 글이 마음에 드시면 아래 손가락을 한번 꾹 눌러 주세요...^_^]
'과학이야기 > 물리학' 카테고리의 다른 글
2차원 충돌 후의 물체의 속력 계산 (1) | 2013.04.10 |
---|---|
[Processing] 기체분자의 확산(2) (0) | 2013.04.09 |
물 위를 걷는 사람들 (0) | 2013.03.06 |
바실리스크 도마뱀 (0) | 2013.03.06 |
[2013학년도 9월 수능 모의고사] 물리I 문제 풀이-07 (0) | 2012.10.06 |