νƒœκ·Έ 보관물: graphical-output

graphical-output

밖이 μ–΄λ‘‘μŠ΅λ‹ˆκΉŒ? νƒœμ–‘μ§€λ„λ₯Ό κ·Έλ¦¬μ‹­μ‹œμ˜€! λ˜λŠ” ASCII μ•„νŠΈ ν‘œν˜„μ„ 좜λ ₯ν•΄μ•Όν•©λ‹ˆλ‹€. ν”„λ‘œκ·Έλž¨μ€

우리의 κ°€μž₯ κ°€κΉŒμš΄ 별, νƒœμ–‘μ€ μ•„μ£Ό μ‹ κΈ°ν•©λ‹ˆλ‹€. μƒμŠΉ μ‹œκ°„κ³Ό μ„€μ • μ‹œκ°„μ€ ν˜„μž¬ μœ„μΉ˜μ™€ 겨울 여뢀에 따라 λ‹€λ¦…λ‹ˆλ‹€.

μš°λ¦¬λŠ” μ§€ν•˜μ‹€μ˜ μ•ˆλ½ν•¨μ„ λ– λ‚˜μ§€ μ•Šκ³  νƒœμ–‘μ΄ 외뢀에 λΉ„μΆ”λŠ”μ§€λ₯Ό μΆ”λ‘  ν•  수 있기λ₯Ό μ›ν•©λ‹ˆλ‹€. κ·Έλž˜μ„œ μš°λ¦¬λŠ” μ΅œμ‹  νƒœμ–‘μ§€λ„ (일λͺ… ​​일광지도)κ°€ ν•„μš”ν•©λ‹ˆλ‹€. 당신은 그것을 μƒμ„±ν•˜λŠ” ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜λŠ” μ‚¬λžŒμž…λ‹ˆλ‹€!

κ·œμΉ™ : κ·€ν•˜μ˜ ν”„λ‘œκ·Έλž¨μ€ ν˜„μž¬ μ•Œλ €μ§„ νƒœμ–‘μ˜ μ–΄λ–€ 뢀뢄을 λ³΄μ—¬μ£ΌλŠ” (우리의 행성에 λŒ€ν•œ) 이미지 (μ•Œλ €μ§„ ν˜•μ‹) λ˜λŠ” ASCII μ•„νŠΈ ν‘œν˜„μ„ 좜λ ₯ν•΄μ•Όν•©λ‹ˆλ‹€. ν”„λ‘œκ·Έλž¨μ€ 독창적 이고 독립적 이어야 ν•©λ‹ˆλ‹€. ν”„λ‘œκ·Έλž˜λ° μ–Έμ–΄μ˜ ν‘œμ€€ 라이브러리λ₯Ό μ œμ™Έν•œ μ½”λ“œλ₯Ό 볡사, μ‚¬μš©, 포함 λ˜λŠ” 호좜 ν•  수 μ—†μŠ΅λ‹ˆλ‹€.

μ—¬μ „νžˆ λ‚΄κ°€ λ§ν•˜λŠ” 것에 λŒ€ν•œ λ‹¨μ„œκ°€ μ—†λ‹€λ©΄ Wikipedia의 μ˜ˆκ°€ μžˆμŠ΅λ‹ˆλ‹€.

νƒœμ–‘μ§€λ„ 예

이것은 인기 μ½˜ν…ŒμŠ€νŠΈ μž…λ‹ˆλ‹€. 당신은 λ‹Ήμ‹ μ˜ 닡을 λ‹¬μ„±ν•˜κΈ° μœ„ν•΄ λ‹€μŒ 쀑 μ–΄λŠ 것을 λ‹¬μ„±ν•˜λ €κ³ ν•˜λŠ”μ§€ μ£Όλͺ©ν•΄μ•Όν•©λ‹ˆλ‹€ (μ—¬λŸ¬ κ°€μ§€ 선택 κ°€λŠ₯) :

  • 단정. κ·œμΉ™μ— β€˜κ·Όμ‚¬μΉ˜β€™λΌκ³  μ ν˜€ μžˆμŠ΅λ‹ˆλ‹€. κ·Όμ‚¬μΉ˜κ°€ μ’‹μ„μˆ˜λ‘μ΄ λ²”μ£Όμ—μ„œ 더 λ§Žμ€ 점수λ₯Ό μ–»μŠ΅λ‹ˆλ‹€. Wolfram Alpha , Time and Date λ˜λŠ” die.net 에 λŒ€ν•΄ κ΅¬ν˜„μ„ 확인할 수 μžˆμŠ΅λ‹ˆλ‹€ .

  • κΈ°λŠ₯μ„±. 예λ₯Ό λ“€μ–΄, λŒ€ν™” ν˜• μž‘μ—…μ€ μ–΄λ–»μŠ΅λ‹ˆκΉŒ? νŠΉμ • μœ„μΉ˜λ₯Ό ν‘œμ‹œ ν•˜μ‹œκ² μŠ΅λ‹ˆκΉŒ? λ‹€λ₯Έ 행성을 λ§€ν•‘?

  • λ―Έν•™. λŒ€λ₯™μ„ κ·Έλ¦¬μ‹œκ² μŠ΅λ‹ˆκΉŒ? λ³΄λ„ˆμŠ€ 포인트. 질감 λŒ€λ₯™? λ³΄λ„ˆμŠ€ 포인트. 3D μ§€κ΅¬μ—μ„œ? ꡬ름과 ν•¨κ»˜? 별? μ˜¬λ°”λ₯Έ 별? λŒ€κ·œλͺ¨ λ³΄λ„ˆμŠ€ 포인트. λ“±λ“±.

  • ν”ν•˜μ§€ μ•Šκ±°λ‚˜ μ˜€λž˜λ˜μ—ˆκ±°λ‚˜ λ‹¨μˆœν•œ 잘λͺ»λœ 기술 μ‚¬μš©. λ¬Όλ‘ , Mathematicaμ—μ„œ 이것을 μ±„μšΈ μˆ˜λŠ” μžˆμ§€λ§Œ μ‚¬μš©μ„ κ³ λ € m4ν–ˆμŠ΅λ‹ˆκΉŒ? SQL? μ•žμœΌλ‘œ? x86 μ–΄μ…ˆλΈ”λ¦¬?

  • μž₯λ‚œ. 닀이 λ§₯μ‹œ 온 ν”„λ‘œμ μ…˜ λ§΅ 을 μ‚¬μš©ν•˜κ³  μ‹Ά μŠ΅λ‹ˆκΉŒ? μ–΄μ„œ!

  • 짧은 μ½”λ“œ. 이것은 κ²°κ΅­ μ½”λ“œ 골프 SEμž…λ‹ˆλ‹€.

μ¦κΈ°μ„Έμš”!



λ‹΅λ³€

ν•˜μŠ€μΌˆ-μ €ν’ˆμ§ˆ μ½”λ“œ

λ‚΄κ°€ 이것을 μ“Έ λ•Œ λ‚˜λŠ” 맀우 ν”Όκ³€ν–ˆλ‹€.

λ‚˜λŠ” 돌기 생각을 λ„ˆλ¬΄ 멀리 갈 μˆ˜λ„, μ–΄μ¨Œλ“ , 여기에 β€˜ν”„λ‘œκ·Έλž¨μ΄ μ‚¬μš©ν•˜λŠ” νˆ¬μ‚¬μ΄μ•Ό. 기본적으둜 지ꡬ에 큐브λ₯Ό 투영 ν•œ λ‹€μŒ μ „κ°œν•˜λŠ” 것과 κ°™μŠ΅λ‹ˆλ‹€. λ˜ν•œμ΄ νˆ¬μ˜μ—μ„œ κ·Έλ¦ΌμžλŠ” μ§μ„ μœΌλ‘œ λ§Œλ“€μ–΄μ§‘λ‹ˆλ‹€.
이 ν”„λ‘œκ·Έλž¨μ€ ν˜„μž¬ λ‚ μ§œ / μ‹œκ°„μ„ μ‚¬μš©ν•˜κ³  stdoutμ—μ„œ PPM νŒŒμΌμ„ 좜λ ₯ν•©λ‹ˆλ‹€.

import Data.Time.Clock
import Data.Time.Calendar
import Control.Applicative
import Data.Fixed
import Data.Maybe

earth :: [[Int]]
earth = [[256],[256],[256],[256],[64,1,1,2,1,5,14,16,152],[56,19,3,27,1,6,50,1,2,1,90],[53,6,1,11,2,36,26,1,2,1,16,2,1,1,2,1,24,4,66],[47,2,5,14,4,35,22,7,54,2,1,3,60],[38,1,2,2,3,1,6,1,2,1,2,7,6,1,1,33,24,3,3,1,56,2,60],[34,2,1,4,2,1,3,1,1,3,3,2,15,3,3,29,57,5,19,1,2,11,17,1,1,1,34],[40,3,10,2,1,8,16,27,54,3,18,19,18,1,36],[33,6,5,3,2,3,1,3,2,2,1,5,16,21,1,2,53,2,10,1,6,19,1,7,4,3,9,2,33],[32,4,1,7,1,2,3,2,1,1,3,11,14,23,53,2,10,3,1,4,2,33,7,7,29],[8,5,25,10,5,3,2,14,10,2,1,18,1,2,31,6,18,1,7,4,1,60,22],[5,18,2,12,3,5,1,3,2,2,1,3,4,2,3,8,11,18,30,13,9,2,7,3,2,72,1,6,8],[4,36,2,1,1,4,3,7,1,4,3,9,8,15,34,18,2,2,2,17,1,78,4],[4,1,1,27,3,1,1,24,6,3,1,1,1,3,6,13,13,1,20,15,1,4,1,104,1],[3,31,1,24,1,2,4,8,10,9,12,6,18,7,3,7,1,1,2,99,3,2,2],[7,50,2,2,2,1,2,1,3,2,1,2,10,7,15,1,20,7,2,111,7,1],[4,35,1,15,9,1,1,3,4,1,12,5,34,8,3,110,10],[4,9,1,2,1,37,12,6,16,3,34,8,3,96,5,6,13],[6,6,1,1,8,32,12,6,3,1,49,9,4,2,1,86,1,3,4,2,19],[9,2,1,1,11,31,11,11,40,1,8,1,2,4,5,83,12,3,20],[8,1,16,33,9,11,39,2,8,1,2,3,3,83,13,5,19],[28,33,5,12,40,2,7,3,6,62,1,19,13,5,20],[27,36,2,15,34,3,2,2,6,71,1,22,11,2,22],[30,21,1,11,2,16,33,3,1,4,2,72,1,24,1,1,9,1,23],[31,21,1,26,39,4,1,98,1,1,33],[31,42,7,1,40,100,1,1,33],[33,25,2,15,4,4,35,102,36],[33,23,2,1,2,14,8,1,36,27,1,9,1,61,3,1,33],[33,26,5,14,42,10,1,11,2,2,2,7,3,5,1,9,1,44,38],[33,26,1,2,1,9,2,1,45,7,1,2,2,9,8,6,2,6,1,53,4,2,33],[33,26,1,4,1,6,44,8,6,2,3,7,9,5,3,56,1,1,4,3,33],[33,37,45,8,7,2,3,6,2,4,3,6,4,53,43],[33,36,46,6,6,1,4,1,2,2,3,16,3,47,1,5,8,2,34],[34,34,46,7,11,1,3,2,2,16,3,45,6,2,8,1,35],[34,33,48,5,11,1,4,1,4,16,2,49,3,2,6,2,35],[35,32,54,8,17,60,5,2,4,4,35],[36,30,50,12,18,60,8,2,1,1,38],[38,27,50,15,16,61,6,2,41],[38,25,51,18,3,4,6,62,6,1,42],[39,1,1,17,2,3,51,93,49],[40,1,1,11,9,2,49,31,1,10,2,50,49],[40,1,2,9,10,2,48,33,1,10,2,49,49],[41,1,2,8,11,1,47,34,2,10,5,44,50],[42,1,2,7,58,36,1,11,2,1,8,36,51],[46,6,58,36,2,15,7,34,2,1,49],[46,6,12,2,43,38,2,14,7,2,1,12,1,15,55],[46,6,5,2,7,2,41,38,2,14,10,10,4,10,59],[47,6,3,3,10,3,38,37,3,12,11,8,6,9,2,1,57],[49,10,51,38,3,9,13,7,8,9,9,2,48],[51,7,51,40,2,7,15,6,9,1,1,8,8,2,48],[55,7,47,41,1,6,17,4,12,8,8,1,49],[57,5,47,42,1,2,20,4,13,8,9,1,47],[59,3,8,1,38,43,22,4,13,1,2,4,10,2,46],[60,2,6,5,38,41,1,4,18,3,17,3,10,2,46],[61,2,1,1,2,3,1,7,34,45,18,2,18,1,60],[63,1,2,13,33,44,22,1,12,1,16,3,45],[66,14,33,43,22,1,13,1,14,1,1,1,46],[66,18,30,4,1,1,5,30,34,1,2,2,9,3,50],[66,19,43,27,34,2,2,1,7,3,52],[65,20,43,26,36,2,1,2,5,5,51],[65,21,42,24,39,3,4,7,2,1,1,1,1,1,44],[56,1,7,23,41,16,1,6,41,2,4,6,7,1,44],[64,25,39,16,1,5,42,3,4,5,2,1,8,1,2,1,37],[64,29,35,22,43,3,1,1,2,3,2,1,1,1,2,1,1,2,1,7,6,1,27],[63,31,35,20,45,2,11,1,9,7,4,2,26],[64,32,34,19,67,1,2,6,1,2,28],[65,31,34,12,1,6,48,4,18,6,31],[65,31,34,19,54,2,1,2,2,1,10,2,2,1,30],[66,29,36,14,1,3,57,1,19,2,28],[66,29,36,14,1,4,63,1,42],[67,27,36,15,1,4,63,5,3,2,33],[67,26,37,20,5,2,53,2,1,4,4,2,33],[68,25,37,20,4,3,52,9,3,3,32],[70,23,36,20,3,4,53,11,1,4,31],[71,22,37,17,5,4,51,18,31],[71,22,37,16,7,3,50,20,30],[71,21,39,15,6,3,5,1,42,24,29],[71,20,40,15,6,3,47,26,28],[71,17,43,15,6,3,46,28,27],[71,16,45,13,8,1,48,27,27],[71,16,45,12,58,28,26],[71,16,45,12,58,28,26],[70,16,47,10,59,28,26],[70,15,49,9,60,27,26],[70,14,50,7,62,7,6,13,27],[70,13,51,6,63,6,8,1,1,9,28],[70,10,138,10,28],[69,12,139,7,29],[69,11,141,5,19,3,8],[69,8,167,3,9],[69,8,166,1,1,1,10],[70,5,149,2,16,2,12],[69,6,166,3,12],[68,6,166,2,14],[68,5,166,3,14],[68,6,182],[67,6,183],[68,4,184],[68,4,6,2,176],[69,4,183],[70,5,20,1,160],[256],[256],[256],[256],[256],[256],[78,1,1,1,109,1,65],[75,2,115,1,23,1,39],[72,3,80,1,1,5,20,42,32],[74,1,70,1,4,21,5,52,2,1,25],[67,1,2,2,1,4,64,28,4,62,21],[69,9,34,1,1,1,1,1,1,1,2,48,3,69,15],[50,1,5,1,16,5,34,130,14],[32,1,1,2,4,1,3,1,4,29,32,128,18],[20,1,1,54,32,128,20],[17,49,34,137,19],[9,1,2,54,20,4,6,143,17],[16,51,18,5,10,135,21],[11,1,4,54,25,140,21],[12,66,4,155,19],[12,231,13],[0,6,9,5,2,234],[0,256],[0,256]]
main = do
    header
    mapM_ line [0..299]
    where
        header = do
            putStrLn "P3"
            putStrLn "# Some PPM readers expect a comment here"
            putStrLn "400 300"
            putStrLn "2"
        line y = mapM_ (\x -> pixel x y >>= draw) [0..399]
            where
                draw (r, g, b) = putStrLn $ (show r) ++ " " ++ (show g) ++ " " ++ (show b)
                pixel x y = fromMaybe (return (1, 1, 1)) $
                    mapRegion (\x y -> (50, -x, y)) (x - 50) (y - 50)
                    <|> mapRegion (\x y -> (-x, -50, y)) (x - 150) (y - 50)
                    <|> mapRegion (\x y -> (-x, y, 50)) (x - 150) (y - 150)
                    <|> mapRegion (\x y -> (-50, y, -x)) (x - 250) (y - 150)
                    <|> mapRegion (\x y -> (y, 50, -x)) (x - 250) (y - 250)
                    <|> mapRegion (\x y -> (y, -x, -50)) (x - 350) (y - 250)
                    where
                        mapRegion f x y = if x >= -50 && y >= -50 && x < 50 && y < 50 then
                            Just $ fmap (worldMap . shade) getCurrentTime
                            else Nothing
                                where
                                    t (x, y, z) = (atan2 y z) / pi
                                    p (x, y, z) = asin (x / (sqrt $ x*x+y*y+z*z)) / pi * 2
                                    rotate o (x, y, z) = (x, y * cos o + z * sin o, z * cos o - y * sin o)
                                    tilt o (x, y, z) = (x * cos o - y * sin o, x * sin o + y * cos o, z)
                                    shade c = ((t $ rotate yearAngle $ tilt 0.366 $ rotate (dayAngle - yearAngle) $ f x y)) `mod'` 2 > 1
                                        where
                                            dayAngle = fromIntegral (fromEnum $ utctDayTime c) / 43200000000000000 * pi + pi / 2
                                            yearAngle = (fromIntegral $ toModifiedJulianDay $ utctDay c) / 182.624 * pi + 2.5311
                                    worldMap c = case (c, index (t $ f x y) (p $ f x y)) of
                                            (False, False) -> (0, 0, 0)
                                            (False, True) -> (0, 0, 1)
                                            (True, False) -> (2, 1, 0)
                                            (True, True) -> (0, 1, 2)
                                            where
                                                index x y = index' (earth !! (floor $ (y + 1) * 63)) (floor $ (x + 1) * 127) True
                                                    where
                                                        index' [] _ p = False
                                                        index' (x:d) n p
                                                            | n < x = p
                                                            | otherwise = index' d (n - x) (not p)

삼각 whereμ½”λ“œ, 쀑첩 case, μœ νš¨ν•˜μ§€ μ•Šμ€ IO μ‚¬μš© 이 λ§žμŠ΅λ‹ˆλ‹€ .


λ‹΅λ³€

Haskell, β€˜μ™œλƒν•˜λ©΄β€™μΉ΄ν…Œκ³ λ¦¬μ—μ„œ

κΆκΈˆν•΄μ„œ 책을 μΌμŠ΅λ‹ˆλ‹€. 곡식은 ν•©λ¦¬μ μœΌλ‘œ μ •ν™•ν•˜μ§€λ§Œ [1] 그런 λ‹€μŒ μ μ ˆν•œ Plate CarrΓ©e λ§΅ λŒ€μ‹  μ•„μŠ€ν‚€ μ•„νŠΈλ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€. 픽셀이 μœ„λ„ / κ²½λ„λ‘œ λ³€ν™˜λ˜λŠ” 방식은 Plate CarrΓ©e에 λŒ€ν•΄μ„œλ§Œ μ˜¬λ°”λ₯΄κ²Œ μž‘λ™ν•©λ‹ˆλ‹€.

import Data.Time
d=pi/180
tau=2*pi
m0=UTCTime(fromGregorian 2000 1 1)(secondsToDiffTime(12*60*60))
dark lat long now =
  let
    time=(realToFrac$diffUTCTime now m0)/(60*60*24)
    hour=(realToFrac$utctDayTime now)/(60*60)
    mnlong=280.460+0.9856474*time
    mnanom=(357.528+0.9856003*time)*d
    eclong=(mnlong+1.915*sin(mnanom)+0.020*sin(2*mnanom))*d
    oblqec=(23.439-0.0000004*time)*d
    ra=let num=cos(oblqec)*sin(eclong)
           den=cos(eclong) in
       if den<0 then atan(num/den)+pi else atan(num/den)
    dec=asin(sin(oblqec)*sin(eclong))
    gmst =6.697375+0.0657098242*time+hour
    lmst=(gmst*15*d)+long
    ha=(lmst-ra)
    el=asin(sin(dec)*sin(lat)+cos(dec)*cos(lat)*cos(ha))
  in
  el<=0

td x = fromIntegral x :: Double
keep="NSEW"++['0'..'9']
pixel p dk=if dk && p`notElem`keep then if p==' ' then '#' else '%' else p
showMap t= do
  let w=length(worldmap!!0)
      h=length worldmap
  putStrLn (worldmap!!0)
  putStrLn (worldmap!!1)
  mapM_(\y->do
           mapM_(\x->let
                    lat=(0.5-td y/td h)*pi
                    long=(0.5-td x/td w)*tau
                    in
                     putStr [pixel ((worldmap!!(y+2))!!x) (dark lat long t)]) [0..(w-1)]
           putStrLn "") [0..(h-4)]
  putStrLn (last worldmap)

main = do {t<-getCurrentTime; showMap t}

worldmap=[
 "180 150W  120W  90W   60W   30W  000   30E   60E   90E   120E  150E 180",
 "|    |     |     |     |     |    |     |     |     |     |     |     |",
 "+90N-+-----+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+",
 "|          . _..::__:  ,-\"-\"._       |7       ,     _,.__             |",
 "|  _.___ _ _<_>`!(._`.`-.    /        _._     `_ ,_/  '  '-._.---.-.__|",
 "|.{     \" \" `-==,',._\\{  \\  / {)     / _ \">_,-' `                mt-2_|",
 "+ \\_.:--.       `._ )`^-. \"'      , [_/(                       __,/-' +",
 "|'\"'     \\         \"    _L       oD_,--'                )     /. (|   |",
 "|         |           ,'         _)_.\\\\._<> 6              _,' /  '   |",
 "|         `.         /          [_/_'` `\"(                <'}  )      |",
 "+30N       \\\\    .-. )          /   `-'\"..' `:._          _)  '       +",
 "|   `        \\  (  `(          /         `:\\  > \\  ,-^.  /' '         |",
 "|             `._,   \"\"        |           \\`'   \\|   ?_)  {\\         |",
 "|                `=.---.       `._._       ,'     \"`  |' ,- '.        |",
 "+000               |    `-._        |     /          `:`<_|h--._      +",
 "|                  (        >       .     | ,          `=.__.`-'\\     |",
 "|                   `.     /        |     |{|              ,-.,\\     .|",
 "|                    |   ,'          \\   / `'            ,\"     \\     |",
 "+30S                 |  /             |_'                |  __  /     +",
 "|                    | |                                 '-'  `-'   \\.|",
 "|                    |/                                        \"    / |",
 "|                    \\.                                            '  |",
 "+60S                                                                  +",
 "|                     ,/           ______._.--._ _..---.---------._   |",
 "|    ,-----\"-..?----_/ )      _,-'\"             \"                  (  |",
 "|.._(                  `-----'                                      `-|",
 "+90S-+-----+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+",
 "Map 1998 Matthew Thomas. Freely usable as long as this line is included"]

보닀 ν₯미둜운 연쀑 μ‹œκ°„μ˜ 예제 좜λ ₯ (μš°λ¦¬λŠ” μΆ˜λΆ„ κ·Όμ²˜μ— μžˆμœΌλ―€λ‘œ Wander Nauta의 μ‚¬κ°ν˜• λͺ¨μ–‘은 μƒλ‹Ήνžˆ μ •ν™•ν•©λ‹ˆλ‹€ :))-이것은 1 μ›” 16 일 13:55:51 UTC 2014μž…λ‹ˆλ‹€.

180 150W  120W  90W   60W   30W  000   30E   60E   90E   120E  150E 180
|    |     |     |     |     |    |     |     |     |     |     |     |
%90N%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%##########%#%%%%%%%%##%%%%%%%#######%7#######%#####%%%%%#############%
%##%%%%%#%#%%%%%%%%%%%%%%####%########%%%#####%%#%%%##%##%%%%%%%%%%%%%%
%%%#####%#%#%%%%%%%%%%%##%##%#%%#####%#%#%%%%%%#%################%%%2%%
%#%%%%%%%#######%%%#%%%%%#%%######, [_/(         ##############%%%%%%#%
%%%%#####%#########%####%%#####  oD_,--'            ####%#####%%#%%###%
%#########%###########%%#####    _)_.\\._<> 6        ######%%%#%##%###%
%#########%%#########%######    [_/_'` `"(             ###%%%##%######%
%30N#######%%####%%%#%#####     /   `-'"..' `:._       ###%%##%#######%
%###%########%##%##%%#####     /         `:\  > \  ,-^. #%%#%#########%
%#############%%%%###%%###     |           \`'   \|   ?_)##%%#########%
%################%%%%%%%#      `._._       ,'     "`  |' %%#%%########%
%000###############%####`-._        |     /          `:`<_%%%%%%######%
%##################%####    >       .     | ,          `=.%%%%%%%#####%
%###################%%#    /        |     |{|              %%%%%#####%%
%####################%#  ,'          \   / `'            ,"#####%#####%
%30S#################%  /             |_'                |  %%##%#####%
%####################% |                                 '-'##%%%###%%%
%####################|/                                      ##%####%#%
%####################\.                                       #####%##%
%60S################                                          ########%
%##################   ,/           ______._.--._ _..---.-------%%%%###%
%####%%%%%%%%%%%%%--_/ )      _,-'"             "                ##%##%
%%%%%###########       `-----'                                    ##%%%
%90S%%%%%%%%%----+-----+-----+----+-----+-----+-----+-----+-----+----%%
Map 1998 Matthew Thomas. Freely usable as long as this line is included

[1] 0μ—μ„œ 360 μ‚¬μ΄μ˜ 각도, 0μ—μ„œ 24 μ‚¬μ΄μ˜ μ‹œκ°„, 0μ—μ„œ 2pi μ‚¬μ΄μ˜ λΌλ””μ•ˆμ„ μœ μ§€ν•˜κΈ°μœ„ν•œ μΆ”κ°€ μž‘μ—…μ΄ μ—†λ‹€λ©΄ λ‹€λ₯Έ κ³³μ—μ„œ 찾을 수 μžˆμŠ΅λ‹ˆλ‹€. λ‚˜λŠ” 그것이 μŠ¬λΌμ΄λ“œ κ·œμΉ™μ„ μ‚¬μš©ν–ˆλ˜ μ‹œμ ˆλΆ€ν„° 이월 된 것이라고 μƒκ°ν•©λ‹ˆλ‹€. 삼각 ν•¨μˆ˜λŠ” κ·Έ λ²”μœ„ λ°–μ—μ„œ 잘 μž‘λ™ν•©λ‹ˆλ‹€ …


λ‹΅λ³€

.

배쉬, 882 * 자

μ΄λ²ˆμ—λŠ” Aesthetics , Weird tech , Fun and Short μ½”λ“œ λ²”μ£Όμ˜ 두 번째 ν•­λͺ© μž…λ‹ˆλ‹€. Ram Narasimhan의 μž‘ν’ˆκ³Ό Peter Taylor의 μ˜κ²¬μ—μ„œ μ˜κ°μ„ λ°›μ•˜μŠ΅λ‹ˆλ‹€.

이 μŠ€ν¬λ¦½νŠΈλŠ” λ¨Όμ € base64 인코딩 λ°μ΄ν„°λ‘œ λ²ˆλ“€λ‘œ μ œκ³΅λ˜λŠ” 저해상도 ν…μŠ€μ²˜λ₯Ό μƒμ„±ν•©λ‹ˆλ‹€. 그런 λ‹€μŒ ν…μŠ€μ²˜κ°€μžˆλŠ” ꡬ체λ₯Ό ν¬ν•¨ν•˜λŠ” 24 개의 PovRay μž₯면을 μƒμ„±ν•©λ‹ˆλ‹€. 각 κ΅¬μ²΄λŠ” β€˜νƒœμ–‘μ„ ν–₯ν•˜λ„λ‘β€™νšŒμ „ν•©λ‹ˆλ‹€. λ§ˆμ§€λ§‰μœΌλ‘œ ν”„λ ˆμž„μ€ ImageMagick을 μ‚¬μš©ν•˜μ—¬ GIF μ• λ‹ˆλ©”μ΄μ…˜μœΌλ‘œ κ²°ν•©λ©λ‹ˆλ‹€. 즉, μŠ€ν¬λ¦½νŠΈκ°€ μž‘λ™ν•˜λ €λ©΄ PovRay와 ImageMagick을 λͺ¨λ‘ μ„€μΉ˜ν•΄μ•Όν•©λ‹ˆλ‹€. μžκ²©μ„ μƒμ‹€ν•œλ‹€κ³  μƒκ°λ˜λ©΄μ΄ ν•­λͺ©μ„ λ¬΄μ‹œν•΄λ„λ©λ‹ˆλ‹€.

Ram의 ν•­λͺ© 및 첫 번째 ν•­λͺ©κ³Ό 같이 κ³„μ ˆ λ³€ν™”λ₯Ό μ„€λͺ…ν•˜μ§€ μ•ŠμœΌλ―€λ‘œ 맀우 μ •ν™•ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ 첫 번째 ν•­λͺ©λ³΄λ‹€ μ§§κ³  예쁘고 μ •ν™•ν•©λ‹ˆλ‹€. Ram의 ν•­λͺ©κ³Ό 달리지도 데이터와 GIF μ• λ‹ˆλ©”μ΄μ…˜ 생성 μ½”λ“œκ°€ ν¬ν•¨λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€.

                               echo '
                    iVBO  Rw0KGgoAAAA       NS
              UhE  U g      AAAEgAAAA                     kAQMAAAAQFe4lAAAABlB
    MVEUAFFwAbxKgAD63 AAAA   AWJLR0                  QAiAUdSAAAAAlwSFlzAAALEwAACx
 MB AJqcGAAAAAd0SU1FB9  4DE  hUWI   op      Fp5MAAADDSURBVBhXrcYhTsNQGADgr3ShE4Qi
    h4BeYQFBgqAJN8Lh    +r                jBb rArIJHPobgAgkzgeSQkVHT7MWThAHzq44
           /j/jezy6jSH  M6fB           gd  9T Nbxdl99R4Q+XpdNRISj4dlFRCz
            oI11FxIpup4uIRDe5           fokp0Y2W25jQFDfrGNGsDNsoqBaGj34D2
             bA7TcAwnmRoDZM             5tLkePUJb6uIT2rEq7hKaUhUHCXWpv7Q
             PqEv1rsuoc7X              RbV Bn2d   kGTYKMQ3C7H8z2+wc/eMd S
              QW39v8kAAA               AA      SUVOR K5CYII='|base64 \
               -di>t;for                X in     {0..23};do R=$((90-(\
                $X*15)                )); echo "camera{location <0,
                 0,                   -5> angle 38 }    light_source{
                  <0,0,               -1000> rgb < 2,2,   2>} sphere
                    {<0              ,0,0> 1 pigment      {
                      /**/            image_map{\"t\"        map_type
                        1}}                rotate           <0,$R,0>
                        }">s               ;povray             +Is +H300\
                        +Of$X.png          +W400
                        mogrify            -fill                     white    \
                        -annotate           +0+10                    "$X:00" \
                         -gravity           south                    f$X.png
                         done;              convert                -delay     \
                         100                -loop                 0 $(ls f*  \
                         |sort               -V)                  ani.gif
                        exit;

A와 λ³΄λ„ˆμŠ€ , 여기에 κ²°κ³Όκ°€ μ–΄λ–€ 크기의 μ œν•œμ—†μ΄μ²˜λŸΌ λ³΄μ˜€μ„ κ²ƒμž…λ‹ˆλ‹€ 무슨 즉, 곡간 μ ˆμ•½ν˜• 1 λΉ„νŠΈ 질감, λŒ€μ‹  NASA의 블루 λ§ˆλΈ” 이미지λ₯Ό μ‚¬μš©ν•˜λŠ” GIFμž…λ‹ˆλ‹€ : http://i.imgur.com/AnahEIu.gif

* : μž₯식 곡백을 ν¬ν•¨ν•˜μ§€ μ•ŠλŠ” 882 자, 총 1872 자


λ‹΅λ³€

λ‚˜λŠ” 짧은 μ½”λ“œ μΉ΄ν…Œκ³ λ¦¬ μ—μ„œ λ‚΄ μžμ‹ μ˜ ν•­λͺ©μœΌλ‘œ μ½˜ν…ŒμŠ€νŠΈλ₯Ό μ‹œμž‘ν•˜κΈ°λ‘œ κ²°μ •ν–ˆμŠ΅λ‹ˆλ‹€ . 쀄 λ°”κΏˆμ„ μ œμ™Έν•˜κ³  923 자 κΈΈμ΄μž…λ‹ˆλ‹€.

C : 923 자

μ½”λ“œλŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

i;j;w=160;f=40;t;b;p;s;e;k;d=86400;q=599;
char* m="M('+z EDz :!#\"!*!8S$[\"!$!#\"\")\"!3R)V$'!!()1M./!F)\"!!!!)'/GE5@\"\"!&%.3&,Y$D\"!!%$)5i\"\"\"F\"%&&6%!e'A#!#!!#&$5&!f&A'$*\"5&!c-#'3''8\"$!!#\"U'\"=5$'8#$$\"S(#=7!*5\"!\"#['!A@6#!^H=!#6bH;!!!\"6_!!I;<&!&\"!!$\"F\"!I8;&\"#\"$&#\"C#\"I7<%#!\"/\"BP5=$*,\"=#\"$!L4A%&\"\"G\"\"\"#M1@)*F\"%P/@,!N#!S(E;!@W'E=!!!<Y&D7!&!\"$7\\$D8!)$4_$C8!('&#&!!a&@9!&(%$&g$>9!$*#(%h\">:!!-\"(%&!b!$&5:!\"+\"(!!#$!!!c+5<-!'!'!#!e)5:.!(!&!\"\"e,:25!!!\"!\"\"h-;07#\"$h.9/:\"\"$!!#\"a17-;'!\"$!!\"$!X46,<\"%\"&$\\45,>#&!$$#!W45,C!!!'!\"!$!V26,H\"#!$!\"!\"!S17-#!A!!#\"!_07,\"#A&!\"`.7+#\"A*.!Q.7*$\">/^-9)$\"=0^*<)$!>1]*<(D1])>&E2\\)>&F&!)\\)@#G$%(\\'w%]'x#,\"P%z .\"P%z .!R$z -\"S$z b#z c#z d#z 3";
main(){
t=(time(0)%d*160)/d;
printf("P2\n%d 62\n5\n",w);
for(;i<q;i++){
for(j=m[i]-' ';j>0;j--){
p=k%w,s=(t-f),e=(t+f);
printf("%c ","1324"[b*2+((p>s&&p<e)||(p>s+w&&p<e+w)||(p>s-w&&p<e-w))]);
k++;
}
b=!b;
}
}

μž‘λ™ 방식은 λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

μ„Έκ³„μ˜ μ›μœ  λΉ„νŠΈ λ§΅ *λŠ” λ¬Έμžμ—΄λ‘œ 인코딩 된 μ‹€ν–‰ – κΈΈμ΄μž…λ‹ˆλ‹€. λ¬Έμžμ—΄μ˜ λͺ¨λ“  λ¬ΈμžλŠ” μœ‘μ§€ λ˜λŠ” λ°”λ‹€ ν”½μ…€μ˜ λŸ°μ„ λ‚˜νƒ€λƒ…λ‹ˆλ‹€. κΈ΄ λ°”λ‹€λŠ” 바닀에 런 λ‹€μŒ 0 개의 λžœλ“œ ν”½μ…€, 그리고 또 λ‹€λ₯Έ 바닀에 μͺΌκ°œμ Έ 인쇄 ν•  μˆ˜μ—†λŠ” λ¬Έμžκ°€ λ¬Έμžμ—΄μ— ν¬ν•¨λ˜μ§€ μ•Šλ„λ‘ν•©λ‹ˆλ‹€. PBM νŒŒμΌμ„μ΄ ν˜•μ‹μœΌλ‘œ λ³€ν™˜ν•˜κΈ° μœ„ν•΄ μž‘μ„±ν•œ Python μŠ€ν¬λ¦½νŠΈλŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€ .

그런 λ‹€μŒ time ()을 μ‚¬μš©ν•˜μ—¬ 1970 λ…„ 1 μ›” 1 일 μžμ • 이후 κ·Έλ¦¬λ‹ˆμΉ˜μ—μ„œ λͺ‡ μ΄ˆκ°€ μ§€ λ‚¬λŠ”μ§€ μ•Œ 수 μžˆμŠ΅λ‹ˆλ‹€. μ˜€λŠ˜μ€ λͺ‡ μ΄ˆκ°€ μ§€ λ‚¬λŠ”μ§€ μ•Œ 수 μžˆμŠ΅λ‹ˆλ‹€. λ˜λŠ” 그에 따라 (λ‚˜λŠ” λ°”λžλ‹ˆλ‹€).

정확성은 λ†λ‹΄μž…λ‹ˆλ‹€. μ „ν˜€ μˆ˜ν•™μ΄ μ—†μŠ΅λ‹ˆλ‹€. 이 μ½”λ“œλŠ” 지ꡬ가 원기λ‘₯ (블둝 λͺ¨μ–‘μ˜ μ£Όμ•Όκ°„)이고 νƒœμ–‘μ΄ 적도 λ°”λ‘œ μœ„μ— 있으며 (여름 / 겨울 μ—†μŒ), νšŒμƒ‰ (색 μ—†μŒ)을 μ’‹μ•„ν•œλ‹€κ³  κ°€μ •ν•©λ‹ˆλ‹€.

λ”ν•˜κΈ° μΈ‘λ©΄μ—μ„œλŠ” λŒ€λ₯™μ„ κ·Έλ¦½λ‹ˆλ‹€.

좜λ ₯은 PGM (Portable Graymap) ν˜•μ‹μ΄λ©°, ImageMagick λ˜λŠ” GIMP와 같은 λ°©λ²•μœΌλ‘œ PNG둜 λ³€ν™˜ ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

λ‹€μŒμ€ PNG둜 λ³€ν™˜ 된 좜λ ₯ μ˜ˆμž…λ‹ˆλ‹€ ( λŒ€ν˜• 버전 ).

* : 남극 λŒ€λ₯™μ„ μ œμ™Έν•œ μ „ 세계, κ·ΈλŸ¬λ‚˜ 그곳에 μ‚¬λŠ” μ‚¬λžŒμ€ …


λ‹΅λ³€

Haskell-ν•΄λ¨Έ νƒ€μž„μž…λ‹ˆλ‹€.

λ‚˜λŠ” 또 ν•˜λ‚˜λ₯Όν–ˆλ‹€. 이전 λ²„μ „μ—μ„œ μˆ˜μ • 된이 λͺ¨λΈμ€ λΉ„μŠ€λ“¬ν•œ Hammer 투영 을 μ‚¬μš©ν•˜μ—¬ 두 극을 λ™μ‹œμ— ν‘œμ‹œν•©λ‹ˆλ‹€ (사싀 각 ν”„λ ˆμž„μ—μ„œ 지ꡬ 전체λ₯Όλ³΄κ³  있음). λΉ„νŠΈ 맡을 직접 μ‚¬μš©ν•˜λŠ” λŒ€μ‹  μ΄μƒν•œ 점을 μΆ”κ°€ ν•˜κΈ° μœ„ν•΄ λ‚˜μ„  을 따라 지ꡬλ₯Ό μƒ˜ν”Œλ§ν•˜μ—¬ 거의 λ™μΌν•œ 면적을 μ œκ³΅ν–ˆμŠ΅λ‹ˆλ‹€. 이것이 지ꡬλ₯Ό μ™œκ³‘μ‹œν‚€κ³  μ‰½κ²Œ νšŒμ „μ‹œν‚¬ μˆ˜μžˆλŠ” κ²ƒμž…λ‹ˆλ‹€. ν•΄λ¨Έμ˜ νˆ¬μ˜λ„ 같은 λ©΄μ μž…λ‹ˆλ‹€. λ‚΄ 생각은이 두 κ°€μ§€λ₯Ό 쌍으둜 묢으면 간격을 μ±„μšΈ λ•Œ μ™œκ³‘μ΄ 쀄어 λ“­λ‹ˆλ‹€. Bresenham의 μ•Œκ³ λ¦¬μ¦˜ 을 μ‚¬μš©ν•˜μ—¬ 선을 κ·Έλ¦¬λ©΄μ„œ νˆ¬μ˜μ—λ„ κ³„μˆ˜ 선을 ν‘œμ‹œν•©λ‹ˆλ‹€ . 지ꡬ와 터미넀이터 라인은 ν•˜λ£¨ 쒅일 μ›€μ§μž…λ‹ˆλ‹€.

이미지λ₯Ό 더 높은 ν•΄μƒλ„λ‘œ λ³€κ²½ν•˜μ§€λ§Œ κΈ°λ³Έ λΉ„νŠΈ 맡이 더 μ‘°μž‘ν•˜κ²Œ λ³€κ²½λ˜λ„λ‘ νŽΈμ§‘ν•˜μ—¬ λ‚˜μ„ μ˜ 효과λ₯Ό λ³Ό 수 μžˆμŠ΅λ‹ˆλ‹€. 이것은 5000 포인트 ( ~ 260000 μ—μ„œ μƒ˜ν”Œλ§ 됨 )λ₯Ό μ‚¬μš©ν•˜λ©° 50Γ—100 λΉ„νŠΈ λ§΅κ³Ό λ™μΌν•˜μ§€λ§Œ 극보닀 적도에 더 λ§Žμ€ 해상도λ₯Ό μ œκ³΅ν•©λ‹ˆλ‹€.

μ½”λ“œλ₯Ό μ‚¬μš©ν•˜λ €λ©΄ ghc둜 μ»΄νŒŒμΌν•˜κ³  μ‹œκ°„ μ˜€ν”„μ…‹ 인 선택적 숫자 맀개 λ³€μˆ˜λ₯Ό μ‚¬μš©ν•˜μ—¬ μ‹€ν–‰ν•˜μ‹­μ‹œμ˜€. νŒŒμΌμ€ β€˜earth0.pgm’, β€˜earth1.pgm’과 같이 μƒμ„±λ©λ‹ˆλ‹€.

import System.Environment
import Data.List (intercalate,unfoldr)
import qualified Data.Set as Set
import Data.List.Split
import Data.List
import Data.Maybe (catMaybes)
import qualified Data.Map as Map
import Data.Time
import Debug.Trace
d=pi/180
tau=2*pi
m0=UTCTime(fromGregorian 2000 1 1)(secondsToDiffTime(12*60*60))
dark::Double->Double->UTCTime->Bool
dark lat long now =
  let
    time=(realToFrac$diffUTCTime now m0)/(60*60*24)
    hour=(realToFrac$utctDayTime now)/(60*60)
    mnlong=280.460+0.9856474*time
    mnanom=(357.528+0.9856003*time)*d
    eclong=(mnlong+1.915*sin(mnanom)+0.020*sin(2*mnanom))*d
    oblqec=(23.439-0.0000004*time)*d
    ra=let num=cos(oblqec)*sin(eclong)
           den=cos(eclong) in
       if den<0 then atan(num/den)+pi else atan(num/den)
    dec=asin(sin(oblqec)*sin(eclong))
    gmst =6.697375+0.0657098242*time+hour
    lmst=(gmst*15*d)+long
    ha=(lmst-ra)
    el=asin(sin(dec)*sin(lat)+cos(dec)*cos(lat)*cos(ha))
  in
  el<=0
infill(open, known)=
  if null open then known else infill gen
  where
    neighbours (x,y)=catMaybes $ map ((flip Map.lookup) known) [(x+1,y),(x-1,y),(x,y+1),(x,y-1),(x+1,y+1),(x-1,y+1),(x-1,y-1),(x-1,y-1)]
    vote a= if null a then Nothing
             else Just ((sum a)`div`(length a))
    fill x (open',  known')=
      case vote (neighbours x) of
        Nothing->(x:open',known')
        Just c->(open',(x,c):known')
    gen=(\(o,k)->(o,Map.fromList k))$foldr fill ([], Map.toList known) open
mpoint (a,b)=case a of Nothing->Nothing;Just c->Just(c,b)
grid w h n g lut= map (\y->map (\x->if Set.member (x,y) g then 3 else case Map.lookup (x,y) lut of Nothing->7;Just c->c) [1..w]) [1..h]
unknowns w h lut=concatMap (\y->concatMap (\x->let z=1-(2*x//w-1)^2-(2*y//h-1)^2 in case Map.lookup (x,y) lut of Nothing->if z<0 then [] else [(x,y)];_->[]) [1..w]) [1..h]
main=do
  args <- getArgs
  let off = if null args then 0 else read(args!!0)
  actual <- getCurrentTime
  let now=((fromIntegral off)*60*60) `addUTCTime` actual
  let tod=realToFrac(utctDayTime now)/86400+0.4
  let s=5000
  let w=800
  let h=400
  let n=6
  -- pbm <- readFile "earth.pbm"
  -- let bits=ungrid s$parsepbm pbm
  let bits=[0,23,4,9,1,3,1,2,6,10,1,10,4,1,3,7,10,7,4,2,2,1,2,6,12,1,1,2,1,5,4,1,8,1,3,
            1,21,7,2,2,35,1,4,3,2,2,2,2,16,1,25,1,2,8,1,4,1,2,13,3,2,1,26,1,1,10,3,3,8,
            2,3,6,1,3,25,2,1,10,15,5,1,6,2,3,30,10,15,19,32,11,16,20,35,11,1,2,14,22,27,
            1,8,14,16,22,2,1,22,1,1,2,1,1,2,1,2,1,3,16,14,25,1,2,21,1,6,1,2,1,1,2,3,17,
            14,26,1,2,1,1,26,1,1,3,3,1,1,19,13,28,4,1,26,6,6,21,11,35,40,21,11,37,41,20,
            2,4,4,1,1,39,19,1,6,1,16,19,2,4,5,40,18,2,7,1,17,19,1,1,1,1,1,2,3,46,7,1,5,
            4,25,16,3,1,1,3,5,44,1,4,5,4,3,6,4,1,19,22,5,46,2,3,4,6,2,9,22,22,2,50,1,5,
            2,1,1,6,1,8,24,15,5,1,2,51,2,5,1,1,1,5,1,10,23,14,9,55,1,4,2,17,16,1,4,14,9,
            57,4,1,3,17,13,20,11,54,2,1,3,1,2,20,12,18,13,47,4,3,8,21,10,17,15,44,5,1,1,
            4,1,3,2,22,10,15,16,46,4,3,1,2,2,25,9,17,15,47,1,1,3,30,9,18,13,46,2,1,4,25,
            2,1,11,16,13,46,8,24,2,2,9,16,11,45,12,22,1,3,7,17,10,45,12,21,1,3,7,19,8,
            43,12,25,6,19,8,41,12,25,5,20,7,40,11,25,4,20,6,40,5,3,2,48,6,38,3,54,4,30,
            1,6,2,55,2,29,1,5,1,53,3,28,1,55,3,49,1,30,2,76,1,284,3,4,1,15,1,17,10,1,9,
            7,1,13,21,4,4,1,2,6,17,2,8,3,63]
  let t(phi,lambda)=unitsphere$rx (-pi/4)$rz (-tod*4*pi)$sphereunit(phi, lambda)
  let hmr=(fmap (\(x,y)->(floor((fl w)*(x+4)/8),floor((fl h)*(y+2)/4)))).hammer.t
  let g=graticule hmr n
  let lut = Map.fromList$ catMaybes $map mpoint$map (\((lat,long),bit)->(hmr(lat,long),bit*4+2-if dark lat long now then 2 else 0))  $zip (spiral s) (rld bits)
  -- let lut = Map.fromList$ catMaybes $map mpoint$map (\((lat,long),bit)->(hmr(lat,long),bit))$zip (spiral s) (rld bits)
  let lut' = infill ((unknowns w h lut), lut)
  let pgm = "P2\n"++((show w)++" "++(show h)++" 7\n")++(intercalate "\n" $ map (intercalate " ")$chunksOf 35 $ map show(concat$grid w h n g lut'))++"\n"
  writeFile ("earth"++(show off)++".pgm") pgm

fl=fromIntegral
spiral::Int->[(Double,Double)]
spiral n=map (\k-> let phi=acos(((2*(fl k))-1)/(fl n)-1) in rerange(pi/2-phi,sqrt((fl n)*pi)*phi)) [1..n]
rld::[Int]->[Int]
rld bits=concat$rld' (head bits) (tail bits)
  where
   rld' bit []=[]
   rld' bit (run:xs) = (replicate run bit):(rld' (case bit of 1->0;_->1) xs)
rle::[Int]->[Int]
rle bits=(head bits):(map length$group bits)
sample::Int->Int->Int->[(Int,Int)]
sample n w h = map (\(phi, theta)->((floor((fl h)*((phi-(pi/2))/pi)))`mod`h, (floor((fl w)*(theta-pi)/(tau)))`mod`w )) $ spiral n
ungrid::Int->[[Int]]->[Int]
ungrid n g = rle $ map (\(y, x)->(g!!y)!!x) (sample n w h)
  where w = length$head g
        h = length g
parsepbm::[Char]->[[Int]]
parsepbm pbm=
    let header = lines pbm
        format = head header
        [width, height] = map read$words (head$drop 1 header)
        rest = drop 2 header
        d = ((map read).concat.(map words)) rest
    in chunksOf width d
rerange(phi,lambda)
 | abs(phi)>pi = rerange(phi - signum(phi)*tau, lambda)
 | abs(phi)>pi/2 = rerange(phi-signum(phi)*pi, lambda+pi)
 | abs(lambda)>pi = rerange(phi, lambda - signum(lambda)*tau)
 | otherwise = (phi, lambda)
laea(phi,lambda)=if isInfinite(z) then Nothing else Just (z*cos(phi)*sin(lambda),z*sin(phi)) where z=4/sqrt(1+cos(phi)*cos(lambda))
hammer(phi,lambda)=case laea(phi, lambda/2) of Nothing->Nothing; Just(x,y)->Just (x, y/2)
bresenham :: (Int, Int)->(Int, Int)->[(Int, Int)]
bresenham p0@(x0,y0) p1@(x1,y1)
  | abs(dx)>50||abs(dy)>50=[]
  | x0>x1 = map h$ bresenham (h p0) (h p1)
  | y0>y1 = map v$ bresenham (v p0) (v p1)
  | (x1-x0) < (y1-y0) = map f$ bresenham (f p0) (f p1)
  | otherwise = unfoldr (\(x,y,d)->if x>x1 then Nothing else Just((x,y),(if 2*(d+dy)<dx then(x+1,y,d+dy)else(x+1,y+1,d+dy-dx)))) (x0,y0,0)
      where
        h(x,y)=(-x,y)
        v(x,y)=(x,-y)
        f(x,y)=(y,x)
        dx=x1-x0
        dy=y1-y0
globe n k=
  (concatMap (\m->map (meridian m) [k*(1-n)..k*(n-1)]) [k*(1-2*n),k*(2-2*n)..k*2*n])
  ++(concatMap (\p->map (parallel p) [k*(-2*n)..k*2*n]) [k*(1-n),k*(2-n)..k*(n-1)])
  where
  meridian m p=(radians(p,m),radians(p+1,m))
  parallel p m=(radians(p,m),radians(p,m+1))
  radians(p,m)=rerange((p//(k*n))*pi/2,(m//(k*n))*pi/2)
graticule f n=Set.fromList $ concatMap (\(a,b)->case (f a,f b) of (Nothing,_)->[];(_,Nothing)->[];(Just c,Just d)->bresenham c d) (globe n 4)
rx theta (x,y,z) = (x, y*(cos theta)-z*(sin theta), y*(sin theta)+z*(cos theta))
ry theta (x,y,z) = (z*(sin theta)+x*(cos theta), y, z*(cos theta)-x*(sin theta))
rz theta (x,y,z) = (x*(cos theta)-y*(sin theta), x*(sin theta)+y*(cos theta), z)
sphereunit (phi, theta) = (rz theta (ry (-phi) (1,0,0)))
unitsphere (x,y,z) = (asin z, atan2 y x)
x//y=(fromIntegral x)/(fromIntegral y)

λ‹΅λ³€

C, pnm 이미지 μ‚¬μš©

μ •ν™•μ„± κ³Ό λ―Έν•™ 에 쀑점을 λ‘” λŠ¦μ€ λ‹΅λ³€ . 좜λ ₯은 ν™©ν˜Όμ˜ μŠ€νŠΈλΌμ΄ν”„λ₯Ό ν¬ν•¨ν•˜μ—¬ 두 개의 μž…λ ₯ 이미지 (day.pnm 및 night.pnm)κ°€ ν˜Όν•©λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€. NASA의 νŒŒλž€μƒ‰ λŒ€λ¦¬μ„μ„ 기반으둜 ν•œ 이미지λ₯Ό μ‚¬μš©ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.

μ½”λ“œλŠ” λͺ…확성을 μœ„ν•΄ λ‚΄ μžμ‹ μ˜ img.hλ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€ (μ—„κ²©ν•œ κ·œμΉ™ μ€€μˆ˜λ₯Ό μœ„ν•΄ .c에 κ·ΈλŒ€λ‘œ ν¬ν•¨λ˜μ–΄ μžˆλ‹€κ³  μƒμƒν•΄λ³΄μ‹­μ‹œμ˜€ …). κ±°κΈ°μ—μžˆλŠ” λͺ¨λ“  것은 C 맀크둜λ₯Ό 톡해 κ΅¬ν˜„λ©λ‹ˆλ‹€. μ• λ‹ˆλ©”μ΄μ…˜μ€ μ—¬λŸ¬ ν”„λ ˆμž„μ—μ„œ λ³€ν™˜ 된 imagemagicks둜 λΉŒλ“œλ©λ‹ˆλ‹€. ν”„λ‘œκ·Έλž¨ μžμ²΄λŠ” 정적 이미지 만 좜λ ₯ν•©λ‹ˆλ‹€. μ½”λ“œλŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

μ§€κΈˆ : (8 μ›” 13 일 ~ 13 : 00 CEST)

ν•˜λ£¨ : (1 μ›” 1 일)

1 λ…„ : (12:00 UTC)

sun.c

  #include <math.h>
  #include <time.h>

  #include "img.h"

  #ifndef M_PI
  #define M_PI 3.14159265359
  #endif

  double deg2rad(double x) {return x / 180.0 * M_PI;}
  double rad2deg(double x) {return x * 180.0 / M_PI;}

  double  sind(double x) {return  sin(deg2rad(x));}
  double  cosd(double x) {return  cos(deg2rad(x));}
  double asind(double x) {return rad2deg(asin(x));}

  double elevation(double latitude, double longitude, int yday, int hour, int min, int sec)
  {
     double fd = (hour + (min + sec / 60.0) / 60.0) / 24.0;
     double fyd = 360.0 * (yday + fd) / 366.0;

     double m = fyd - 3.943;
     double ta = -1.914 * sind(m) + 2.468 * sind(2 * m + 205.6);
     double hourangle = (fd - 0.5) * 360.0 + longitude + ta;
     double decl = 0.396 - 22.913 * cosd(fyd) + 4.025 * sind(fyd) - 0.387 * cosd(2 * fyd) + 0.052 * sind(2 * fyd) - 0.155 * cosd(3 * fyd) + 0.085 * sind(3 * fyd);

     return asind(cosd(hourangle) * cosd(decl) * cosd(latitude) + sind(decl) * sind(latitude));
  }

  int main(int argc, char* argv[])
  {
     Image day, night, out;
     int x, y;
     time_t t = time(0);
     struct tm* utc = gmtime(&t);
     int yday = utc->tm_yday, hour = utc->tm_hour, min = utc->tm_min, sec = utc->tm_sec;

     imgLoad(day, "day.pnm");
     imgLoad(night, "night.pnm");
     imgLoad(out, "day.pnm");
     for(y = 0; y < day.height; ++y)
     {
        double latitude = 90.0 - 180.0 * (y + 0.5) / day.height;
        for(x = 0; x < day.width; ++x)
        {
           double longitude = -180.0 + 360.0 * (x + 0.5) / day.width;
           double elev = elevation(latitude, longitude, yday, hour, min, sec);
           double nf = elev > -0.8 ? 0.0 : elev > -6.0 ? 0.5 : 1.0;
           double df = 1.0 - nf;
           Color dc = imgGetColor(day, x, y);
           Color nc = imgGetColor(night, x, y);
           imgDotC3(out, x, y, df * dc.r + nf * nc.r, df * dc.g + nf * nc.g, df * dc.b + nf * nc.b);
        }
     }
     imgSave(out, "out.pnm");
  }

img.h

  #include <stdlib.h>
  #include <stdio.h>
  #include <string.h>

  typedef struct
  {
     unsigned char r;
     unsigned char g;
     unsigned char b;
  } Color;

  typedef struct
  {
     Color* data;
     int width;
     int height;
     Color c;
  } Image;

  #define imgCreate(img, w, h)           {\
                                            int length;\
                                            (img).width = (w);\
                                            (img).height = (h);\
                                            length = (img).width * (img).height * sizeof(Color);\
                                            (img).data = malloc(length);\
                                            memset((img).data, 0, length);\
                                            (img).c.r = (img).c.g = (img).c.b = 0;\
                                         }

  #define imgDestroy(img)                {\
                                            free((img).data);\
                                            (img).width = 0;\
                                            (img).height = 0;\
                                            (img).c.r = (img).c.g = (img).c.b = 0;\
                                         }

  #define imgSetColor(img, ur, ug, ub)   {\
                                            (img).c.r = (ur);\
                                            (img).c.g = (ug);\
                                            (img).c.b = (ub);\
                                         }

  #define imgDot(img, x, y)              {\
                                            (img).data[(int)(x) + (int)(y) * (img).width] = (img).c;\
                                         }

  #define imgDotC3(img, x, y, ur, ug, ub) {\
                                            (img).data[(int)(x) + (int)(y) * (img).width].r = (ur);\
                                            (img).data[(int)(x) + (int)(y) * (img).width].g = (ug);\
                                            (img).data[(int)(x) + (int)(y) * (img).width].b = (ub);\
                                         }

  #define imgDotC(img, x, y, c)          {\
                                            (img).data[(int)(x) + (int)(y) * (img).width] = (c);\
                                         }

  #define imgGetColor(img, x, y)         ((img).data[(int)(x) + (int)(y) * (img).width])

  #define imgLine(img, x, y, xx, yy)     {\
                                            int x0 = (x), y0 = (y), x1 = (xx), y1 = (yy);\
                                            int dx =  abs(x1 - x0), sx = x0 < x1 ? 1 : -1;\
                                            int dy = -abs(y1 - y0), sy = y0 < y1 ? 1 : -1;\
                                            int err = dx + dy, e2;\
                                            \
                                            for(;;)\
                                            {\
                                               imgDot((img), x0, y0);\
                                               if (x0 == x1 && y0 == y1) break;\
                                               e2 = 2 * err;\
                                               if (e2 >= dy) {err += dy; x0 += sx;}\
                                               if (e2 <= dx) {err += dx; y0 += sy;}\
                                            }\
                                         }

  #define imgSave(img, fname)            {\
                                            FILE* f = fopen((fname), "wb");\
                                            fprintf(f, "P6 %d %d 255\n", (img).width, (img).height);\
                                            fwrite((img).data, sizeof(Color), (img).width * (img).height, f);\
                                            fclose(f);\
                                         }

  #define imgLoad(img, fname)            {\
                                            FILE* f = fopen((fname), "rb");\
                                            char buffer[16];\
                                            int index = 0;\
                                            int field = 0;\
                                            int isP5 = 0;\
                                            unsigned char c = ' ';\
                                            while(field < 4)\
                                            {\
                                               do\
                                               {\
                                                  if(c == '#') while(c = fgetc(f), c != '\n');\
                                               } while(c = fgetc(f), isspace(c) || c == '#');\
                                               index = 0;\
                                               do\
                                               {\
                                                  buffer[index++] = c;\
                                               } while(c = fgetc(f), !isspace(c) && c != '#' && index < 16);\
                                               buffer[index] = 0;\
                                               switch(field)\
                                               {\
                                                  case 0:\
                                                     if (strcmp(buffer, "P5") == 0) isP5 = 1;\
                                                     else if (strcmp(buffer, "P6") == 0) isP5 = 0;\
                                                     else fprintf(stderr, "image format \"%s\" unsupported (not P5 or P6)\n", buffer), exit(1);\
                                                     break;\
                                                  case 1:\
                                                     (img).width = atoi(buffer);\
                                                     break;\
                                                  case 2:\
                                                     (img).height = atoi(buffer);\
                                                     break;\
                                                  case 3:\
                                                     index = atoi(buffer);\
                                                     if (index != 255) fprintf(stderr, "image format unsupported (not 255 values per channel)\n"), exit(1);\
                                                     break;\
                                               }\
                                               field++;\
                                            }\
                                            imgCreate((img), (img).width, (img).height);\
                                            if (isP5)\
                                            {\
                                               int length = (img).width * (img).height;\
                                               for(index = 0; index < length; ++index)\
                                               {\
                                                  (img).data[index].r = (img).data[index].g = (img).data[index].b = fgetc(f);\
                                               }\
                                            }\
                                            else\
                                            {\
                                               fread((img).data, sizeof(Color), (img).width * (img).height, f);\
                                            }\
                                            fclose(f);\
                                         }

λ‹΅λ³€

R : ggplot2 및 λ§΅ ν”„λ‘œμ μ…˜ μ‚¬μš©

@mniip의 κ²Œμ‹œλ¬Όμ—μ„œ μ˜κ°μ„ 얻은 R의 mapproj νŒ¨ν‚€μ§€λ₯Ό μ‚¬μš©ν•˜κΈ°λ‘œ κ²°μ •ν–ˆμŠ΅λ‹ˆλ‹€. νˆ¬μ˜μ„ 계산할 λ•Œ 뢁극이 μžˆμ–΄μ•Όν•˜λŠ” μœ„μΉ˜λ₯Ό μ§€μ •ν•˜μ—¬ 지ꡬ λ°©ν–₯을 μ§€μ •ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

ν˜„μž¬ GMT μ‹œκ°„μ„ κΈ°μ€€μœΌλ‘œ ν˜„μž¬ μ •μ˜€μ˜ 경도λ₯Ό κ³„μ‚°ν•˜κ³  κ·Έ μ§€μ μ„μ§€λ„μ˜ μ€‘μ‹¬μœΌλ‘œ λ§Œλ“­λ‹ˆλ‹€. μš°λ¦¬λŠ” β€œνƒœμ–‘μ˜ κ΄€μ β€μ—μ„œ 지ꡬλ₯Όλ³΄κ³  μžˆμŠ΅λ‹ˆλ‹€.

μ½”λ“œμ˜ λŒ€λΆ€λΆ„μ€ λ―Έν•™μž…λ‹ˆλ‹€. λ‚΄κ°€ μ•Œμ•„ λ‚΄μ•Ό ν•  μœ μΌν•œ 뢀뢄은 β€œμ •μ˜€ 경도”λ₯Ό κ³„μ‚°ν•˜λŠ” 것이 μ—ˆμŠ΅λ‹ˆλ‹€. μ΄λŠ” GMT μ‹œκ°„μ΄ μ£Όμ–΄μ§„ μ •μ˜€ 인 경도 κ°’μž…λ‹ˆλ‹€.

library(ggplot2);library(maps);library(ggmap)
world <- map_data("world")# a lat-long dataframe from the maps package
worldmap <- ggplot(world, aes(x=long, y=lat, group=group)) +
  geom_path(color="orange") +
  theme(panel.background= element_rect("black"),
        axis.text.y=element_blank(),
        axis.ticks=element_blank(),
        axis.title.x=element_blank(),
        axis.title.y=element_blank(),
        panel.grid.major = element_line(colour="blue", size=0.75),
        panel.grid.minor = element_line(colour="blue")
  )

#Create a function that takes in the current GMT time
print_3d_coordmap <- function (current_gmt_time) {
  curr_gmt_mins <- as.POSIXlt(current_gmt_time)$hour*60 + as.POSIXlt(current_gmt_time)$min
  noon_longitude <- 180 - (curr_gmt_mins * 360/1440)
  #centered at wherever longitude where it is Noon now on (lat:equator)
  worldmap + coord_map("ortho", orientation=c(0, noon_longitude, 0))
}

#test it out
print_3d_coordmap(Sys.time() + 7*60*60) # my location is 7 hours behind UTC

그런 λ‹€μŒ R μ• λ‹ˆλ©”μ΄μ…˜ νŒ¨ν‚€μ§€ λ₯Ό μ‚¬μš©ν•˜μ—¬ 24 개의 이미지λ₯Ό μƒμ„±ν•˜κ³  ν•˜λ‚˜μ˜ GIF둜 μ—°κ²°ν–ˆμŠ΅λ‹ˆλ‹€.