밖이 어둡습니까? 태양지도를 그리십시오!


71

우리의 가장 가까운 별, 태양은 아주 신기합니다. 상승 시간과 설정 시간은 현재 위치와 겨울 여부에 따라 다릅니다.

우리는 지하실의 안락함을 떠나지 않고 태양이 외부에 비추는지를 추론 할 수 있기를 원합니다. 그래서 우리는 최신 태양지도 (일명 ​​일광지도)가 필요합니다. 당신은 그것을 생성하는 프로그램을 작성하는 사람입니다!

규칙 : 귀하의 프로그램은 현재 알려진 태양의 어떤 부분을 보여주는 (우리의 행성에 대한) 이미지 (알려진 형식) 또는 ASCII 아트 표현을 출력해야합니다. 프로그램은 독창적 이고 독립적 이어야 합니다. 프로그래밍 언어의 표준 라이브러리를 제외한 코드를 복사, 사용, 포함 또는 호출 할 수 없습니다.

여전히 내가 말하는 것에 대한 단서가 없다면 Wikipedia의 예가 있습니다.

태양지도 예

이것은 인기 콘테스트 입니다. 당신은 당신의 답을 달성하기 위해 다음 중 어느 것을 달성하려고하는지 주목해야합니다 (여러 가지 선택 가능) :

  • 단정. 규칙에 '근사치'라고 적혀 있습니다. 근사치가 좋을수록이 범주에서 더 많은 점수를 얻습니다. Wolfram Alpha , Time and Date 또는 die.net 에 대해 구현을 확인할 수 있습니다 .

  • 기능성. 예를 들어, 대화 형 작업은 어떻습니까? 특정 위치를 표시 하시겠습니까? 다른 행성을 매핑?

  • 미학. 대륙을 그리시겠습니까? 보너스 포인트. 질감 대륙? 보너스 포인트. 3D 지구에서? 구름과 함께? 별? 올바른 별? 대규모 보너스 포인트. 등등.

  • 흔하지 않거나 오래되었거나 단순한 잘못된 기술 사용. 물론, Mathematica에서 이것을 채울 수는 있지만 사용을 고려 m4했습니까? SQL? 앞으로? x86 어셈블리?

  • 장난. 다이 맥시 온 프로젝션 맵 을 사용하고 싶 습니까? 어서!

  • 짧은 코드. 이것은 결국 코드 골프 SE입니다.

즐기세요!


3
@PeterTaylor 아마! 조명을 할 필요조차 없다고 생각합니다. 3D 지구를 그려서 일광 부분 (및 그 밖의 다른 것)이 뷰어를 향하도록 회전시킬 수 있습니다. 그것은 행성의 야간 부분을 보여주지는 않지만 필수는 아닙니다.
Wander Nauta

30
다른 해결책은 단순히 창을 설치하는 것입니다. (지하실에서 나는 의미한다.)
ossifrage

2
@qwr m4이 작업을 위해 요일에 x86 어셈블리를 사용 합니다 ...
Wander Nauta

3
또한 : "태양은 다른 시간에 일어나서지기 때문에 아주 신기합니다." 확실히 태양의 잘못 : P
qwr

2
@qwr 10 시간 일, 10 일 주, 10 주 개월 및 10 개월 년, 태양이 t = 0에서 t = 5 사이 인 경우 시간 / 날짜 계산이 얼마나 쉬운 지 생각해 본 적이 있습니까? 그러나 아닙니다. 태양은 다른 시간에 다른 장소에서 추한 얼굴을 보여야하고 지구를 돌아 다니기에는 너무 오래 걸립니다. 불만 부서도 없습니다. 역겨운.
Wander Nauta

답변:


89

하스켈-저품질 코드

내가 이것을 쓸 때 나는 매우 피곤했다.

나는 돌기 생각을 너무 멀리 갈 수도, 어쨌든, 여기에 '프로그램이 사용하는 투사이야. 기본적으로 지구에 큐브를 투영 한 다음 전개하는 것과 같습니다. 또한이 투영에서 그림자는 직선으로 만들어집니다.
이 프로그램은 현재 날짜 / 시간을 사용하고 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 사용 이 맞습니다 .


그것은 꼬인 천재의 작품입니다. 한 가지 제안 fromIntegral (fromEnum $ utctDayTime c)은으로 깔끔합니다 (realToFrac $ utctDayTime c). (나는 답을 쓰는 동안에 만 이것을 배웠다)
bazzargh

8
하루 종일 .gif를 볼 수 있습니다.
MikeTheLiar

mnlip, @mikeTheLiar에 동의합니다. 답의 맨 위에 gif를 포함시켜야합니다. 모든 투표권을 얻게됩니다.
bazzargh

1
나는 엉뚱한 gif에만 투표했다. 그것은 세상을 보는 비틀어 진 방법 일뿐입니다.
Allen Gould

너무 약간 trippy
Pharap

61

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 사이의 라디안을 유지하기위한 추가 작업이 없다면 다른 곳에서 찾을 수 있습니다. 나는 그것이 슬라이드 규칙을 사용했던 시절부터 이월 된 것이라고 생각합니다. 삼각 함수는 그 범위 밖에서 잘 작동합니다 ...


7
훌륭한! 나는 여전히 '어두운'을 통해지도를 볼 수 있다는 것을 좋아합니다. 또한 수학은 견고 해 보입니다. 다른 사람들이 자신의 솔루션을 귀하의 솔루션과 비교할 수 있도록 예제에 사용한 날짜를 추가 할 수 있습니까?
Wander Nauta

날짜를 추가 한 것을 확인했습니다. 감사합니다.
Wander Nauta

1
네. 나는 이미지에서 그것이 북반구의 겨울임을 분명히 알 수있어 그 날짜를 믿기가 더 쉬워졌습니다! 나는 당신이 내 앞에 답을 게시하고 골프 버전을하려고하는 끝없는 멍청이를 구해 줬기 때문에 기쁘다.
bazzargh

39

생기

.

배쉬, 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 자


5
모두 독립형으로 만든 +1 또한 세계지도처럼 보이는 자체 참조 코드를 작성합니다. 잘 했어.
Ram Narasimhan

1
아아! 여러 항목. 지금 나는 화 내지 않는 것에 대한 변명을 잃고있다.
bazzargh

1
아파요! 그것을 사랑하십시오.
pandubear

허, 나는 코드 자체의 형식을 세계지도 (공백 = 바다, 그 밖의 모든 것 = 육지 포함)의 소스로 사용할 수 있었고 실제로 적은 문자로 더 나은 해상도를 얻을 수 있음을 알고 있습니다. 오 잘 ...
Wander Nauta

2
이것은 마인 크래프트처럼 보입니다.
Kaz Wolfe

25

나는 짧은 코드 카테고리 에서 내 자신의 항목으로 콘테스트를 시작하기로 결정했습니다 . 줄 바꿈을 제외하고 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로 변환 된 출력 예입니다 ( 대형 버전 ).

출력 예

* : 남극 대륙을 제외한 전 세계, 그러나 그곳에 사는 사람은 ...


1
좋은 결과물, 어두운 부분이 구부러져 있으면 더 좋을 것입니다.
qwr

1
네! 출력이 구부러진다는 것은 삼각법을 수행해야한다는 것을 의미하므로 훨씬 길어집니다. (또는 올바른 모서리를 둥글게하여 오른쪽처럼 보이게 할 수 있다고 생각합니다 ...)
Wander Nauta

1
@WanderNauta 당신이 그들을 고려하지 않았다는 속임수를 느끼게 될 펭귄을 심하게 화나게 할 것입니다.
WallyWest

@WallyWest 펭귄처럼 기둥에 살면 자정의 태양과 그 밖의 모든 프로그램이 필요하지 않습니다.
Wander Nauta

22

Haskell-해머 타임입니다.

여기에 이미지 설명을 입력하십시오

나는 또 하나를했다. 이전 버전에서 수정 된이 모델은 비스듬한 Hammer 투영 을 사용하여 두 극을 동시에 표시합니다 (사실 각 프레임에서 지구 전체를보고 있음). 비트 맵을 직접 사용하는 대신 이상한 점을 추가 하기 위해 나선따라 지구를 샘플링하여 거의 동일한 면적을 제공했습니다. 이것이 지구를 왜곡시키고 쉽게 회전시킬 수있는 것입니다. 해머의 투영도 같은 면적입니다. 내 생각은이 두 가지를 쌍으로 묶으면 간격을 채울 때 왜곡이 줄어 듭니다. Bresenham의 알고리즘 을 사용하여 선을 그리면서 투영에도 계수 선을 표시합니다 . 지구와 터미네이터 라인은 하루 종일 움직입니다.

이미지를 더 높은 해상도로 변경하지만 기본 비트 맵이 더 조잡하게 변경되도록 편집하여 나선의 효과를 볼 수 있습니다. 이것은 5000 포인트 ( ~ 260000 에서 샘플링 됨 )를 사용하며 50x100 비트 맵과 동일하지만 극보다 적도에 더 많은 해상도를 제공합니다.

코드를 사용하려면 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)    

3
이건 ... 광기 야 절대 광기. 나는 그것을 좋아한다.
Wander Nauta

1
이것에 대한 변환을 얻는 데 너무 오래 걸렸습니다 . 나선형 비트 맵만으로도 재미 있습니다.
bazzargh

다시 "확실히 확장됩니다"-고해상도 GIF를 쉽게 만들 수 있다는 의미입니까?
Wander Nauta

예. 꽤 큰. 계수 선을 엉망으로 만드는 동안 코드를 조금 꺼 냈습니다. 시간이 조금 지나면 다시 넣고 더 나은 이미지를 업로드합니다.
bazzargh

1
거기 당신은 간다-crazytown의 멋진 큰 이미지
bazzargh

21

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);\
                                         }

아주 예뻐요! 나는 그것을 좋아한다.
Wander Nauta

18

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로 연결했습니다.


좋아 보인다! 그래도 여름과 겨울을 올바르게 처리합니까? 나는 R을 잘 모르지만 적도는 항상 이미지의 중심에있는 것처럼 보입니다.
Wander Nauta

그래 너가 옳아. 나는 적도를 유일한 위도로 사용하여 빠르고 더러운 구현을했습니다. (대신 애니메이션에 초점을 맞췄습니다.) 프로젝트에 사용하지 않는 많은 기능이 있습니다. 계절에 따라 위도를 변경하는 방법을 보여주는 참조가 있다면 기꺼이 사용해 보시기 바랍니다.
Ram Narasimhan

여기 R, Ram에 대한 참조가 있습니다.-사실 여기가 stackoverflow.com/questions/8708048/…
bazzargh

@bazzargh 감사합니다! 방위각에 대해 많은 것을 배우는 것 같습니다.
Ram Narasimhan

9

JavaScript – Martin Kleppe ( http://aem1k.com/ )

나는 이것이 나의 작품이 아니라 Martin Kleppe의 작품이라는 것을 강조하고 싶다. 나는 그것이 너무 완벽하게 맞아 여기에 빠지지 않아야한다고 생각합니다.

온라인 데모 (또는 콘솔에 붙여 넣기)

eval(z='p="<"+"pre>"/*        ######## */;for(y in n="zw24l6k\
4e3t4jnt4qj24xh2 x/*    *############### */42kty24wrt413n243n\
9h243pdxt41csb yz/*  #################### */43iyb6k43pk7243nm\
r24".split(4)){/*     *#################*   */for(a in t=pars\
eInt(n[y],36)+/*          ###############*   */(e=x=r=[]))for\
(r=!r,i=0;t[a/*               ############*   */]>i;i+=.05)wi\
th(Math)x-= /*                #############    */.05,0<cos(o=\
new Date/1e3/*                #########*       */-x/PI)&&(e[~\
~(32*sin(o)*/*                     ####*       */sin(.5+y/7))\
+60] =-~ r);/*                         *###    */for(x=0;122>\
x;)p+="   *#"/*                        #####  */[e[x++]+e[x++\
]]||(S=("eval"/*                      *##### */+"(z=\'"+z.spl\
it(B = "\\\\")./*      ###*           ####  */join(B+B).split\
(Q="\'").join(B+Q/*                  ###* */)+Q+")//m1k")[x/2\
+61*y-1]).fontcolor/*               ##   */(/\\w/.test(S)&&"#\
03B");document.body.innerHTML=p+=B+"\\n"}setTimeout(z)')//m1k\

2
그것이 당신의 일이 아니라면 답을 커뮤니티 위키로 바꿔야합니다.
Kyle Kanos

1
팁 주셔서 감사합니다. 끝난!
Ingo Bürk
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.