7월 아빠들의 코딩 모임은 동탄 토즈에서 진행했습니다.
지난달 따식님이 내준 스크래치로 "자연스럽게 공던지기" 숙제 검사로 시작했습니다.
고양이를 좌우로 움직이게 한 상태에서 각도를 조정해서 위로 던질 때, 자연스럽게 공이 올라갔다가 내려오도록 하는 문제입니다. 내심 욕심이 생겨서 바닥에 닿으면 공이 튕겨 오르도록 했습니다.
공의 y 좌표값이 바닥 아래가 될 때 반전시켜서 오르도록 하고, 바닥에 부딪칠 때마다 x축 증가속도를 감속하도록 했습니다. 그러나 공이 튕겨 오를 때 자연스럽지 않고 통통통 굴러가게 되었습니다.
이걸 어떻게 하면 자연스럽게 할 수 있을까 하며 토론하는 중에 지난달부터 합류한 장책임이 준비한 걸 보여주었습니다.
운동 방정식은 F=ma 에서부터 시작해야 합니다. (F : 힘, m : 질량, a : 가속도)
속도는 가속도를 적분하고, 거리는 이 속도를 적분하면 나옵니다.
여기서 가속도가 중력이 될 경우엔 상수가 될 것이고, 중간에 공을 한번 더 밀어주는 행위가 있다면 변수가 될 것입니다. 이걸 어떻게 표현할 수 있을까요?
아래와 같이 가속도를 시간에 따라 변하지 않는 ao와 시간에 따라 변하는 kt로 두는 것입니다.
그러면 가속도를 적분, 적분해서 거리에 대한 수식으로 표현하면 x(t)로 아래와 같이 나오게 됩니다.
만약 공기에 대한 저항이나 바닥에 부딪쳤을 때 마찰력에 의한 속도 감소가 있을 경우엔 힘은 속도에 비례해서 감소하게 됩니다. 위에서 얻은 가속도를 적분해서 저항 -R을 곱해 감속하는 수식으로 만들 수 있습니다.
그러면 가속하는 부분과 감속하는 부분을 더해서 가속도, 속도, 거리를 표현하면 어떻게 될까요?
음... 1/2, 1/6, 1/24 등의 복잡한 계수가 붙은 수식이 나오는군요
여기서 ao, R 등은 상수가 되고, k는 속도에 비례해서 변하는 수입니다.
다음은 이걸 어떻게 코딩으로 표현할 수 있는가입니다. 시간이 변화하면서 가속도, 속도, 거리는 변화하게 되는 게, △t 이전 값을 받아서 변화하는 값을 더해 t 시간의 가속도, 속도, 거리 값을 얻어내야 합니다.
복잡하게 설명했지만 반복문 안에서 보통 a=a+1로 표현할 경우, 앞의 a는 최종 변화된 값이고, 뒤 a는 이전 값입니다.
음.... 이렇게 표현하면 복잡해 보이지만 코딩을 짜기에 보다 현실적으로 잘 표현된 식이 됩니다.
일단 중간에 공을 건드려서 속도를 증가시키는 것을 제외하고 (k=0), x(t)는 중력을 받지 않으므로 ao=0, y(t)는 중력을 받으므로 ao=-10로 두겠습니다.(위쪽 방향이 +, 아래 방향이 -1) , 중력가속도는 실제 9.8m/s2
그러면 초기에 대각방향으로 공을 던질 때, x방향 속도 1000m/s, y방향 속도 1000m/s으로 던진다고 하고, 공 던지는 고양이의 x, y 좌표는 (0,0)이라 둡니다.
1) 공기에 의해 속도 감소가 없다고 가정하면 : R=0
1초 후에 공의 가속도, 속도, 거리는 어떻게 될까요? (△t=1)
x축 : a(1) = a(0)+△a = 0 --> x축 방향으로는 중력이 없으므로 가속도는 없습니다.
v(1) = v(0)+{a(0)+△a}*1=1000+0=1000
x(1) = x(0)+v(0)*1 + a(0)*1^2+ △a*1^2 = 1000
y축 : a(1) = a(0)+△a = -10y축 방향으로는 중력가속도가 있으므로.
v(1) = v(0)+{a(0)+△a}*1=1000+(-10+0)=990
y(1) = y(0)+v(0)*1 + a(0)*1^2+ △a*1^2 = 1000-10=990
이런 식으로 x(1), x(2), x(3)... 과 y(1), y(2), y(3)... 를 구해나가면 공의 시간에 따른 위치를 알 수 있게 됩니다.
2) 공기에 의해 속도 감소가 있다고 하면 : R=-0.001m/s2
1초 후에 공의 가속도, 속도, 거리는 (△t=1)
x축 : a(1) = a(0)+△a = 0 -R*v(0)=-1 : 공기저항으로 인하여 1만큼 변화
v(1) = v(0)+{a(0)+△a}*1=1000-1=999
x(1) = x(0)+v(0)*1 + a(0)*1^2+ △a*1^2 = 1000-1=999
y축 : a(1) = a(0)+△a = -10-1=-11 : y축 방향으로는 중력가속도와 공기저항이 있으므로.
v(1) = v(0)+{a(0)+△a}*1=1000+(-10-1)=989
y(1) = y(0)+v(0)*1 + a(0)*1^2+ △a*1^2 = 1000-11=989
이런 식으로 x(1), x(2), x(3)... 과 y(1), y(2), y(3)... 를 구해나가면 공의 시간에 따른 위치를 알 수 있게 됩니다.
이것이 공기 저항이 있는 것과 없는 것의 공의 궤적 차이입니다.
우리는 장책임의 설명을 들으면서 코딩을 배우기 위해서는 먼저 수학과 물리를 열심히 해야겠다는 공감대가 형성되었습니다. 이 수식을 이용하여 공 던지기 코딩을 만들어 가지고 오는 것을 다음 숙제로 받고서 머리가 아프긴 했지만 ^^ 아이들이 고등학생 정도 되면 이 예제를 가지고 서로 고민하는 날이 올걸 기대하면서...
아래는 따식님의 새로운 스크래치 예제입니다. 위 예제보다는 좀 쉽지만 나름 고민이 필요하는 선풍기 돌리기 예제입니다. 바람의 세기를 조절하고 멈추는 버튼이 있고, 이걸 누를 때마다 선풍기가 천천히 원하는 속도까지 도달하도록 하는 예제입니다. 공 던지기처럼 자연스럽게 만드는 게 핵심...
따식님의 간단한 코딩 설명을 듣고, 다음 모임까지 여기서 하나 더 들어가는? 고민이 들어간 코딩을 만들어가지고 오는 것을 또 다른 숙제로 받은 후 모임을 끝냈습니다.
오늘 모임은 왠지 벅찬 느낌이 들지만 모임의 수준이 한층 업그레이드된 생각에 기분이 좋습니다.