역행운동이란 ?

유튜브를 보는 도중에 행성의 겉보기 역행 운동에 대한 영상을 보았다. 행성의 역행운동이란 지구에서 보기에 행성이 반대방향으로 움직이는 것처럼 보이는 현상이다. 행성은 태양을 중심으로 돌고 있지만, 행성 간의 공전 속도의 차이로 뒤로 움직이는 듯이 보이는 현상을 말한다.

retrograde motion

행성이 있고 보이는 각이 어떻게 바뀌는지를 시뮬레이션을 해보고자 하는데 줄리아에서 애니메이션을 만들 때 사용할 수 있는 Javis를 사용해서 그려보기로 한다.

사전준비

줄리아를 설치했다고 가정한다.

우선 패키지를 설치해야 하는데 줄리아 REPL에서 ]으로 패키지 매니저 모드로 들어간 후 add Javis를 입력하여 처리하거나

아래와 같이 Pkg 모듈을 불러와서 설치해야 한다. (몇 분 정도 소요 될 수 있다.)

using Pkg

Pkg.add("Javis")

패키지를 설치했으면 그다음은 패키지를 불러와야 한다.

using Javis

역행운동을 구하기 위한 함수

애니메이션을 만들기 위해서 아래와 같이 함수를 정의했다.

  • ground : 배경을 설정하는 함수이다.
  • object : 25 픽셀 정도 되는 원을 그리는 함수다.
  • path! : 경로에 점을 찍어두는 함수다.
  • connector : 두 점을 지나는 선을 긋는 하수다.
  • extender : 안쪽 행성에서 바깥쪽 행성이 어디에 보여지를 그리는 함수다.
  • abs : 두 Point간의 거리를 구하는 함수이다.
  • getpoint : 특정 지점을 지나는 백터가 원과 접하는 점을 구하는 함수다.
function ground(args...) 
    background("white") # canvas background
    sethue("black") # pen color
end

function object(p=O, color="black")
    sethue(color)
    circle(p, 25, :fill)
    return p
end

function path!(points, pos, color)
    sethue(color)
    push!(points, pos) # add pos to points
    circle.(points, 2, :fill) # draws a circle for each point using broadcasting
end

function connector(p1, p2, color)
    sethue(color)
    line(p1,p2, :stroke)
end

function extender(points, p1, p2, r, color)
    sethue(color)
    d = p2 - p1
    p3 = getpoint(p2, d, r, O)
    line(p1, p3, :stroke)
    circle(p3, 2, :fill)
    push!(points, p3)
    if length(points) > 200
        popat!(points, 1)
    end
    circle.(points, 2, :fill)
end

import Base.abs

function abs(p::Point, p0::Point)
    d = p - p0
    r = sqrt(d.x^2 + d.y^2)
    return r
end

function getpoint(p, d, r, p0)
    λ = 0.001
    rate = 0.001
    new_p = p
    while true
        new_p = p + λ * d
        if r < abs(new_p, p0)
            break
        end
        λ += rate
    end
    return new_p
end
getpoint (generic function with 1 method)

그림을 그린다

우선 캔버스를 그린 후 붉은 행성과 파란 행성이 돌고 있다고 가정한다.

n = 1000

myvideo = Video(2000, 2000)
Background(1:n, ground)
path_of_red = Point[] 
path_of_blue = Point[]
red_ball = Object(1:n, (args...)->object(O, "#ff2211"), Point(100,0))
act!(red_ball, Action(anim_rotate_around(24π, O)))
blue_ball = Object(1:n, (args...)->object(O, "#1122ff"), Point(200,0))
act!(blue_ball, Action(anim_rotate_around(7π, O)))
Object(1:n, (args...)->connector(pos(red_ball), pos(blue_ball), "black"))
Object(1:n, (args...)->path!(path_of_red, pos(red_ball), "red"))
Object(1:n, (args...)->path!(path_of_blue, pos(blue_ball), "blue"))
points = []
Object(1:n, (args...)->extender(points, pos(red_ball), pos(blue_ball), 800, "#112233"))


render(
    myvideo;
    pathname="ghtop_images/retrograde_motion.gif"
)
Rendering frames...100%|████████████████████████████████| Time: 0:02:19
"ghtop_images/retrograde_motion.gif"

그림을 그려보면 아래와 같이 결과가 나온다.

보면 알 수 있듯이 내행성이 외행성을 빠르게 통과할 때 행성이 뒤로 가는 것처럼 보이게 된다.

retrograde_motion