Apakah di luar gelap? Buat peta matahari!

71

Bintang terdekat kita, matahari, cukup gelisah. Waktu naik dan set tergantung pada di mana Anda berada, dan apakah itu musim dingin atau tidak.

Kami ingin dapat menyimpulkan jika matahari bersinar di luar tanpa harus meninggalkan kenyamanan ruang bawah tanah kami - itulah sebabnya kami membutuhkan peta matahari terbaru (alias peta siang hari). Anda yang menulis program yang hanya menghasilkan itu!

Aturan: Program Anda harus menampilkan gambar (dalam format yang diketahui) atau representasi seni ASCII dari planet kita, menunjukkan (perkiraan) bagian mana yang saat ini dinyalakan oleh matahari. Program Anda harus asli dan mandiri : Anda tidak boleh menyalin, menggunakan, memasukkan atau memanggil kode apa pun kecuali perpustakaan standar bahasa pemrograman Anda.

Jika Anda masih tidak tahu apa yang saya bicarakan, berikut adalah contoh dari Wikipedia:

Contoh peta matahari

Ini adalah kontes popularitas . Anda harus mencatat dalam jawaban Anda yang mana dari hal-hal berikut yang ingin Anda capai (beberapa pilihan mungkin):

  • Ketepatan. Perhatikan bahwa aturan mengatakan 'aproksimasi' - semakin baik aproksimasi Anda, semakin banyak poin dalam kategori ini. Anda dapat memeriksa implementasi Anda terhadap Wolfram Alpha's , Time and Date's atau die.net's .

  • Fungsionalitas. Misalnya, bagaimana dengan interaktivitas? Menandai lokasi tertentu? Memetakan planet lain?

  • Estetika. Menggambar benua? Poin bonus. Benua bertekstur? Poin bonus. Di bumi 3D? Dengan awan? Bintang? Bintang yang benar ? Poin bonus besar. Dan seterusnya.

  • Menggunakan teknologi yang tidak biasa, lama, atau salah. Tentu, Anda bisa menyiapkan ini di Mathematica, tetapi apakah Anda sudah mempertimbangkan untuk menggunakan m4? SQL Keempat? perakitan x86?

  • Menyenangkan. Ingin menggunakan peta proyeksi-Dymaxion ? Lanjutkan!

  • Kode pendek. Lagipula, ini adalah Code Golf SE.

Selamat bersenang-senang!

Mengembara Nauta
sumber
3
@PeterTaylor Mungkin! Saya pikir Anda bahkan tidak perlu melakukan pencahayaan: Anda bisa menggambar bumi 3D dan memutarnya sehingga bagian siang hari (dan tidak ada yang lain) menghadap penonton. Itu tidak akan menunjukkan bagian malam hari dari planet ini, tapi itu tidak diperlukan.
Wander Nauta
30
Solusi alternatif adalah dengan menginstal windows. (Di ruang bawah tanah, maksudku.)
ossifrage mual
2
@ qwr Saya akan mengambil perakitan x86 m4setiap hari dalam seminggu untuk tugas ini ...
Wander Nauta
3
Juga: "matahari cukup gelisah karena terbit dan terbenam pada waktu yang berbeda." Jelas kesalahan matahari: P
qwr
2
@qwr Pernah berpikir tentang betapa mudahnya perhitungan waktu / tanggal jika kita memiliki 10 jam sehari, 10 hari minggu, 10 minggu bulan dan 10 bulan tahun, dan matahari antara t = 0 dan t = 5? Tapi tidak, matahari harus pergi dan menunjukkan wajahnya yang buruk di tempat yang berbeda di waktu yang berbeda dan terlalu lama untuk mengelilingi bumi. Tidak ada divisi keluhan juga. Menjijikkan.
Wander Nauta

Jawaban:

89

Haskell - kode berkualitas rendah

Saya sangat lelah ketika menulis ini.

Saya mungkin sudah terlalu jauh dengan gagasan proyeksi, bagaimanapun, inilah proyeksi yang digunakan program. Pada dasarnya seperti memproyeksikan bumi ke sebuah kubus dan kemudian membukanya. Selain itu, dalam proyeksi ini, bayangan terbuat dari garis lurus.
Program menggunakan tanggal / waktu saat ini, dan menampilkan file PPM pada stdout.

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)

Itu benar - triangular where-code, nested cases, penggunaan IO tidak valid.

mniip
sumber
Itu adalah karya jenius bengkok. Satu saran, fromIntegral (fromEnum $ utctDayTime c)lebih rapi (realToFrac $ utctDayTime c). (Saya hanya belajar ini saat menulis jawaban saya)
bazzargh
8
Saya bisa menonton .gif sepanjang hari.
MikeTheLiar
mnlip, saya setuju dengan @mikeTheLiar. Anda harus menyematkan gif itu tepat di atas jawaban Anda, Anda akan mendapatkan semua suara.
bazzargh
1
Saya memilih hanya pada gif aneh. Itu hanya cara memutar untuk melihat dunia.
Allen Gould
sedikit
tersandung
61

Haskell, dalam kategori 'karena itu ada'

Saya penasaran jadi saya menulis satu. Rumusnya cukup akurat [1], tapi kemudian saya pergi dan menggunakan beberapa seni ascii alih-alih peta Plate Carrée yang tepat, karena itu terlihat lebih bagus (cara saya mengonversi piksel ke lat / panjang hanya berfungsi dengan benar untuk 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"]

Contoh output, dari waktu yang lebih menarik tahun ini (kami berada di dekat titik balik, sehingga gumpalan persegi panjang Wander Nauta cukup akurat :)) - ini untuk Jan 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] mereka sama dengan yang akan Anda temukan di tempat lain, kecuali tanpa kerja ekstra untuk menjaga derajat antara 0 dan 360, jam antara 0 dan 24, dan radian antara 0 dan 2pi. Saya pikir itu adalah peninggalan dari hari-hari kami menggunakan aturan slide; Fungsi trigonometri bekerja dengan baik di luar rentang tersebut ...

bazzargh
sumber
7
Cemerlang! Saya suka bahwa Anda masih bisa melihat peta melalui 'gelap'. Juga, matematika terlihat solid. Bisakah Anda menambahkan tanggal yang Anda gunakan untuk contoh, sehingga orang lain dapat membandingkan solusi mereka dengan Anda?
Wander Nauta
Saya melihat bahwa Anda telah menambahkan tanggal, terima kasih!
Wander Nauta
1
Ya. Saya suka itu di gambar Anda dapat dengan jelas melihat bahwa itu musim dingin di belahan bumi utara, membuatnya lebih mudah untuk percaya pada tanggal itu! Saya senang Anda memposting jawaban sebelum saya, menyelamatkan saya tanpa henti faff mencoba untuk melakukan versi golf, tidak ada cara saya akan mengalahkan Anda untuk itu.
bazzargh
39

Animasi

.

Bash, 882 * karakter

Ini adalah entri kedua saya, kali ini dalam kategori Aesthetics , Weird tech , Fun dan Short code . Ini terinspirasi oleh entri Ram Narasimhan dan komentar Peter Taylor.

Script pertama-tama menghasilkan tekstur beresolusi rendah di dunia, dibundel sebagai data yang di-encode base64. Ini kemudian menghasilkan 24 adegan PovRay yang mengandung bola dengan tekstur itu, masing-masing diputar untuk 'menghadapi matahari'. Akhirnya, frame digabungkan menjadi animasi GIF menggunakan ImageMagick. Ini artinya Anda harus menginstal PovRay dan ImageMagick agar skrip berfungsi - jangan sungkan untuk mengabaikan entri ini jika Anda pikir itu akan mendiskualifikasi.

Seperti entri Ram, dan entri pertama saya, ini tidak memperhitungkan perubahan musiman, yang berarti tidak terlalu tepat. Namun, ini lebih pendek, lebih cantik dan lebih tepat daripada entri pertama saya - dan tidak seperti entri Ram, data peta dan kode untuk menghasilkan animasi GIF disertakan.

                               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;

Sebagai bonus , inilah GIF yang menggunakan gambar Blue Marble NASA alih-alih tekstur hemat 1-bit, yaitu seperti apa hasilnya tanpa batasan ukuran: http://i.imgur.com/AnahEIu.gif

*: 882 karakter tidak termasuk spasi putih dekoratif, total 1872 karakter.

Mengembara Nauta
sumber
5
+1 untuk menjadikan semuanya serba lengkap. Dan juga untuk membuat kode referensi-sendiri yang terlihat seperti peta dunia. Kerja bagus.
Ram Narasimhan
1
argh! banyak masukan. Sekarang saya kehilangan alasan saya untuk tidak melakukan yang gila ...
bazzargh
1
Itu sakit! Suka.
pandubear
Heh, saya sadar sekarang bahwa saya bisa menggunakan format kode itu sendiri sebagai sumber untuk peta dunia (dengan spasi = lautan, segalanya = daratan) dan benar-benar mendapatkan resolusi yang lebih baik dengan lebih sedikit karakter. Oh well ...
Wander Nauta
2
Ini terlihat seperti Minecraft.
Kaz Wolfe
25

Saya memutuskan untuk memulai kontes dengan entri saya sendiri, dalam kategori kode pendek . Panjangnya 923 karakter, tidak termasuk baris baru.

C: 923 karakter

Ini kodenya:

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

Begini cara kerjanya:

Bitmap mentah dunia * dijalankan sepanjang disandikan sebagai string. Setiap karakter dalam string merepresentasikan run piksel darat atau laut. Aliran laut yang panjang dipisah menjadi alur laut, lalu 0 piksel daratan, kemudian aliran laut lainnya, untuk menghindari menyertakan karakter yang tidak patut dicetak dalam string. Skrip Python yang saya tulis untuk mengonversi file PBM ke format ini ada di sini .

Saya kemudian menggunakan waktu () untuk mencari tahu berapa detik telah berlalu di Greenwich sejak tengah malam, 1 Januari 1970. Saya memodulasi itu untuk mencari tahu berapa detik telah berlalu di sana hari ini, menggunakan informasi itu untuk memposisikan bagian cahaya dari peta lebih lanjut- atau kurang sesuai (saya harap).

Kebenaran adalah lelucon. Tidak ada matematika sama sekali. Kode ini mengasumsikan bumi adalah sebuah silinder (berbentuk siang / malam), bahwa matahari berada tepat di atas garis khatulistiwa (tidak ada musim panas / musim dingin), dan Anda menyukai warna abu-abu (tanpa warna).

Di sisi positifnya, saya menggambar benua.

Outputnya dalam format Portable Graymap (PGM), yang kemudian dapat dikonversi ke PNG oleh sesuatu seperti ImageMagick atau GIMP.

Berikut ini contoh output, dikonversi ke PNG ( versi lebih besar ):

Contoh output

*: Seluruh dunia kecuali Antartika, tetapi siapa yang tinggal di sana ...

Mengembara Nauta
sumber
1
Output bagus, akan lebih baik jika area gelap melengkung
qwr
1
Ya! Memiliki output menjadi melengkung berarti Anda harus melakukan beberapa trigonometri, yang akan membuatnya lebih lama. (Atau saya kira Anda bisa memutari sudut yang benar agar terlihat benar ...)
Wander Nauta
1
@WanderNauta Akan ada beberapa penguin yang sangat kesal yang akan merasa tertipu karena Anda tidak mempertimbangkannya, k ...
WallyWest
@WallyWest Jika Anda tinggal di kutub, seperti penguin Anda, Anda tidak memerlukan program ini - matahari tengah malam dan sebagainya.
Wander Nauta
22

Haskell - saatnya Hammer.

masukkan deskripsi gambar di sini

Saya melakukan satu lagi. Diadaptasi dari versi saya sebelumnya, yang ini menggunakan proyeksi Hammer miring untuk menunjukkan kedua kutub pada saat yang sama (sebenarnya Anda melihat seluruh bumi di setiap frame). Hanya untuk menambah keanehan, alih-alih menggunakan bitmap secara langsung, saya mencicipi bumi dengan spiral untuk memberikan cakupan area yang kira-kira sama; inilah yang memungkinkan saya mengubah bumi dan memutarnya dengan mudah. Proyeksi Hammer adalah area yang sama juga; ide saya adalah bahwa memasangkan kedua hal ini akan mengurangi distorsi ketika saya mengisi kekosongan. Saya menampilkan graticule pada proyeksi juga, menggunakan algoritma Bresenham untuk menggambar garis. Garis globe dan terminator bergerak sepanjang hari.

Diedit untuk mengubah gambar ke resolusi yang lebih tinggi tetapi bitmap yang mendasari lebih kasar, sehingga Anda dapat melihat efek spiral. Ini menggunakan 5000 poin (sampel dari ~ 260000 ), setara dengan bitmap 50x100, tetapi memberikan resolusi lebih ke khatulistiwa daripada ke kutub.

Untuk menggunakan kode, kompilasi dengan ghc, jalankan dengan parameter numerik opsional yang merupakan offset jam; file dihasilkan seperti '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)    
bazzargh
sumber
3
Ini adalah kegilaan. Kegilaan mutlak. Aku menyukainya.
Wander Nauta
1
Ini Took saya begitu lama untuk mendapatkan transformasi yang tepat yang satu ini. Bitmap spiral itu sendiri lucu.
bazzargh
re "ini meningkatkan skala cukup baik" - maksud Anda, Anda dapat dengan mudah membuat GIF resolusi lebih tinggi?
Wander Nauta
Iya. jauh lebih besar. Saya mengambil kode itu sebentar sementara saya mengacaukan graticule, ketika saya mendapatkan waktu sedikit kemudian saya akan memasukkannya kembali dan mengunggah gambar yang lebih baik
bazzargh
1
begitulah
bazzargh
21

C, menggunakan gambar pnm

Jawaban terlambat, fokus pada kebenaran dan estetika . Outputnya merupakan perpaduan dari dua gambar input (siang.pnm dan night.pnm), termasuk garis senja. Saya menggunakan gambar berdasarkan NASA blue marble di sini.

Kode menggunakan img.h saya sendiri untuk kejelasan (bayangkan saja itu dimasukkan kata demi kata dalam .c untuk kepatuhan aturan yang ketat ...). Semua yang ada di sana diimplementasikan melalui makro C. Animasi dibangun dengan konversi imagemagick dari banyak frame - program itu sendiri hanya akan menghasilkan gambar statis. Kode di bawah ini.

Sekarang: (13 Agustus, ~ 13:00 CEST)

keluaran

Suatu hari: (1 Januari)

suatu hari

Satu tahun: (12:00 UTC)

satu tahun

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

  #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);\
                                         }
Manuel Kasten
sumber
Sangat cantik! Saya suka itu.
Mengembara Nauta
18

R: Menggunakan proyeksi ggplot2 dan Map

masukkan deskripsi gambar di sini

Terinspirasi oleh pos @ mniip, saya memutuskan untuk mencoba menggunakan paket mapproj R, di mana kita dapat mengarahkan dunia dengan menentukan di mana Kutub Utara seharusnya berada ketika menghitung proyeksi.

Berdasarkan waktu GMT saat ini, saya menghitung garis bujur di mana saat ini siang hari dan menjadikan titik itu sebagai pusat peta. Kami melihat Bumi dari "sudut pandang Sun" sehingga apa pun yang terlihat adalah di siang hari.

Sebagian besar kode hanyalah estetika. Satu-satunya bagian saya harus mencari tahu adalah untuk menghitung "Siang Bujur," itu adalah nilai bujur di mana itu siang hari diberikan waktu 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

Saya kemudian menggunakan paket animasi R untuk menghasilkan 24 gambar dan menjahitnya menjadi satu GIF.

Ram Narasimhan
sumber
Tampak hebat! Apakah itu menangani musim panas dan musim dingin dengan benar? Saya tidak tahu R dengan baik, tetapi sepertinya ekuator Anda selalu di tengah gambar.
Wander Nauta
Ya kamu benar. Saya melakukan implementasi cepat dan kotor menggunakan garis khatulistiwa sebagai satu-satunya garis lintang. (Sebagai gantinya fokus pada animasi.) Proyek ini memiliki banyak fitur yang tidak saya gunakan. Jika ada referensi yang menunjukkan bagaimana memvariasikan garis lintang dengan musim, saya akan dengan senang hati mencobanya.
Ram Narasimhan
Berikut ini adalah referensi dalam R, Ram - sebenarnya ini adalah di mana saya menerjemahkan formula dalam entri saya dari stackoverflow.com/questions/8708048/…
bazzargh
@bazzargh Terima kasih! Sepertinya saya harus banyak belajar tentang sudut azimuth.
Ram Narasimhan
9

JavaScript - oleh Martin Kleppe ( http://aem1k.com/ )

Saya ingin menekankan bahwa ini bukan pekerjaan saya, tetapi karya Martin Kleppe. Saya hanya berpikir itu sangat cocok sehingga tidak boleh hilang di sini:

Demo Online (atau cukup rekatkan ke konsol)

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\
Ingo Bürk
sumber
2
Jika ini bukan pekerjaan Anda, Anda harus mengubah jawaban Anda menjadi wiki komunitas.
Kyle Kanos
1
Terima kasih atas tipnya, tidak pernah memperhatikan kotak centang itu sebelumnya. Selesai!
Ingo Bürk