M42/docs: view doc:50/v8

M42의 로고마크를 만들기 위한 연구

v1Ossia
v2Ossia
v3Ossia
v4Ossia
v5Ossia
v6Ossia
v7Ossia
v8Ossia
요약

M42의 로고마크를 만들기 위한 연구입니다.

아이디어

2017년 추석 오전 5시(2017-10-04T05:00:00+09)에 서울 부근(37.5908, 127.0292)에서 M42를 보았을 때 보이는 오리온 자리의 모양(α, β, γ, δ, ε, ζ, κ Ori를 이은 것)을 로고마크로 하려고 한다.

좌표의 계산

import astropy.units as u
from astropy.time import Time
from astropy.coordinates import SkyCoord, EarthLocation, AltAz

location = EarthLocation(lat=37.5908*u.deg, lon=127.0292*u.deg)
time = Time('2017-10-04T05:00:00') - 9 * u.hour
star_names = ['M42', 'alpha ori', 'beta ori', 'gamma ori', 'delta ori', 'epsilon ori', 'zeta ori', 'kappa ori']
print([SkyCoord.from_name(name).transform_to(AltAz(obstime=time, location=location)) for name in star_names])
[
    (173.73551283, 46.84306689),
    (162.06947888, 58.66289377),
    (181.23271073, 44.22017205),
    (176.58999249, 58.73144979),
    (174.33127561, 51.98557433),
    (172.78083327, 50.99118912),
    (171.13556489, 50.12738586),
    (170.11343254, 42.23919504)
]

방위각은 북에서 동으로 잰다. 각각을 (azimuth, altitude) (Ai,ai)(A_i, a_i)라 하자. M42를 바라보도록 좌표계 변환을 해야 하는데, 일단 M42의 방위각을 180°180\degree로 맞추는 것은 간단하다.

[
    (180., 46.84306689), 
    (168.33396605, 58.66289377), 
    (187.4971979, 44.22017205), 
    (182.85447966, 58.73144979), 
    (180.59576278, 51.98557433), 
    (179.04532044, 50.99118912), 
    (177.40005206, 50.12738586), 
    (176.37791971, 42.23919504)
]

이것을 반지름을 11로 하고 (0,0)(0, 0)xx, (270°,0)(270\degree, 0)yy, (0,90°)(0, 90\degree)zz로 하는 직교좌표계로 만들자.

xi=cosaicosAiyi=cosaisinAizi=sinai \begin{aligned} x_i &= \cos a_i\cos A_i \\ y_i &= -\cos a_i\sin A_i \\ z_i &= \sin a_i \end{aligned}
[
    (-0.68399898, 0., 0.72948297), 
    (-0.50932916, -0.10516215, 0.8541222), 
    (-0.71053852, 0.09350882, 0.69741746), 
    (-0.518406, 0.02584841, 0.85474387), 
    (-0.61582656, 0.00640361, 0.78785572), 
    (-0.62935252, -0.01048743, 0.77704918), 
    (-0.64042295, -0.02908085, 0.76747166), 
    (-0.73886604, -0.04677138, 0.6722272)
]

이것을 yy축을 기준으로 a0-a_0 만큼 회전변환 하자. 회전변환행렬은

[cos(a0)0sin(a0)010sin(a0)0cos(a0)]=[cosa00sina0010sina00cosa0]=[x00z0010z00x0] \begin{bmatrix} \cos(-a_0) & 0 & \sin(-a_0) \\ 0 & 1 & 0 \\ -\sin(-a_0) & 0 & \cos(-a_0) \end{bmatrix} = \begin{bmatrix} \cos a_0 & 0 & -\sin a_0 \\ 0 & 1 & 0 \\ \sin a_0 & 0 & \cos a_0 \end{bmatrix} = \begin{bmatrix} -x_0 & 0 & -z_0 \\ 0 & 1 & 0 \\ z_0 & 0 & -x_0 \end{bmatrix}

이 된다.

[
    (-1., 0., 0.),
    (-0.97144822, -0.10516211,  0.21267178),
    (-0.99476177,  0.09350888, -0.04129289),
    (-0.97811026,  0.02584845,  0.20647561),
    (-0.99595207,  0.00640366,  0.08965754),
    (-0.99732062, -0.01048738,  0.07239892),
    (-0.99790615, -0.0290808 ,  0.05777222),
    (-0.99576191, -0.04677132, -0.07918745)
]

각각을 원점과 이었을 때 x=1x=-1과 만나는 점을 구한다. 이미 거의 1-1이기는 하다.

[
    (0.0, 0.0),
    (-0.10825291990642123, 0.2189224017746473),
    (0.09400127691763133, -0.041510326969010296),
    (0.02642693266897339, 0.21109645394247914),
    (0.006429686270859082, 0.09002194408057741),
    (-0.01051555581999568, 0.07259342846922238),
    (-0.029141819265636422, 0.05789343911761977),
    (-0.04697038877373099, -0.07952448164500331)
]

결론적으로 코드는 다음과 같이 된다.

import numpy as np
import matplotlib.pyplot as plt
import astropy.units as u
from astropy.time import Time
from astropy.coordinates import SkyCoord, EarthLocation, AltAz

location = EarthLocation(lat=37.5908*u.deg, lon=127.0292*u.deg)
time = Time('2017-10-04T05:00:00') - 9 * u.hour
star_names = ['M42', 'alpha ori', 'beta ori', 'gamma ori', 'delta ori', 'epsilon ori', 'zeta ori', 'kappa ori']
a = [SkyCoord.from_name(name).transform_to(AltAz(obstime=time, location=location)) for name in star_names]
dA = a[0].az - 180 * u.deg
b = [(x.az - dA, x.alt) for x in a]
c = [(np.cos(x[1]) * np.cos(x[0]), -np.cos(x[1]) * np.sin(x[0]), np.sin(x[1])) for x in b]
m = np.array([[-c[0][0], 0, -c[0][2]], [0, 1, 0], [c[0][2], 0, -c[0][0]]])
d = [m.dot(x) for x in c]
e = [(x[1] / -x[0], x[2] / -x[0]) for x in d]

print(e)
plt.plot([p[0] for p in e], [p[1] for p in e], 'ro')
plt.axis([-.3, .3, -.3, .3])
plt.show()

matplot 출력 결과: https://imgur.com/8ixr6HG

SVG 생성

로고마크를 만들기 위해 사용한 코드는 다음과 같다.

import numpy as np
import matplotlib.pyplot as plt
import astropy.units as u
from astropy.time import Time
from astropy.coordinates import SkyCoord, EarthLocation, AltAz

location = EarthLocation(lat=37.5908*u.deg, lon=127.0292*u.deg)
time = Time('2017-10-04T05:00:00') - 9 * u.hour
star_names = ['M42', 'zeta ori', 'alpha ori', 'gamma ori', 'delta ori', 'zeta ori', 'kappa ori', 'beta ori', 'delta ori']
a = [SkyCoord.from_name(name).transform_to(AltAz(obstime=time, location=location)) for name in star_names]
dA = a[0].az - 180 * u.deg
b = [(x.az - dA, x.alt) for x in a]
c = [(np.cos(x[1]) * np.cos(x[0]), -np.cos(x[1]) * np.sin(x[0]), np.sin(x[1])) for x in b]
m = np.array([[-c[0][0], 0, -c[0][2]], [0, 1, 0], [c[0][2], 0, -c[0][0]]])
d = [m.dot(x) for x in c]
e = [(x[1] / -x[0], x[2] / -x[0]) for x in d]
f = [(x[0] * 1300 + 256 + 17, (x[1] - .1) * 1300 + 256 + 41) for x in e]

print('<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512">')

for i in range(1, len(f) - 1):
	print('<line x1="' + str(f[i][0]) + '" y1="' + str(512 - f[i][1]) + '" x2="' + str(f[i + 1][0]) + '" y2="' + str(512 - f[i + 1][1]) + '" stroke="white" stroke-width="65" />')

print('\n'.join(['<circle cx="' + str(x[0]) + '" cy="' + str(512 - x[1]) + '" r="60" fill="white" />' for x in f]))

for i in range(1, len(f) - 1):
	print('<line x1="' + str(f[i][0]) + '" y1="' + str(512 - f[i][1]) + '" x2="' + str(f[i + 1][0]) + '" y2="' + str(512 - f[i + 1][1]) + '" stroke="#222" stroke-width="25" />')

print('<circle cx="' + str(f[0][0]) + '" cy="' + str(512 - f[0][1]) + '" r="40" fill="#222" />')
print('\n'.join(['<circle cx="' + str(x[0]) + '" cy="' + str(512 - x[1]) + '" r="40" fill="#222" />' for x in f[1:]]))
print('</svg>')

가운데에 있는 것은 뺐다.