Bên ngoài có tối không? Vẽ bản đồ mặt trời!


71

Ngôi sao gần nhất của chúng ta, mặt trời, khá bồn chồn. Thời gian nó tăng và thiết lập tùy thuộc vào nơi bạn ở, và đó có phải là mùa đông hay không.

Chúng tôi muốn có thể suy luận nếu mặt trời chiếu sáng bên ngoài mà không phải rời khỏi các tiện nghi của tầng hầm - đó là lý do tại sao chúng tôi cần một bản đồ mặt trời cập nhật (còn gọi là bản đồ ánh sáng ban ngày). Bạn là người viết chương trình tạo ra điều đó!

Quy tắc: Chương trình của bạn sẽ xuất ra một hình ảnh (ở định dạng đã biết) hoặc đại diện nghệ thuật ASCII của hành tinh chúng ta, hiển thị (gần đúng) những phần nào hiện đang được chiếu sáng bởi mặt trời. Chương trình của bạn phải là bản gốckhép kín : bạn không được phép sao chép, sử dụng, bao gồm hoặc gọi bất kỳ mã nào ngoại trừ các thư viện chuẩn của ngôn ngữ lập trình của bạn.

Nếu bạn vẫn không biết tôi đang nói gì, thì đây là một ví dụ từ Wikipedia:

Ví dụ bản đồ mặt trời

Đây là một cuộc thi phổ biến . Bạn nên lưu ý trong câu trả lời của mình về những điều sau đây bạn đang cố gắng đạt được (có thể có nhiều lựa chọn):

  • Đúng. Lưu ý rằng các quy tắc nói 'một xấp xỉ' - xấp xỉ của bạn càng tốt, càng nhiều điểm trong danh mục này. Bạn có thể kiểm tra việc triển khai của mình đối với Wolfram Alpha , Thời gian và Ngày hoặc die.net .

  • Chức năng. Ví dụ, những gì về tương tác? Đánh dấu địa điểm cụ thể? Vẽ bản đồ các hành tinh khác?

  • Tính thẩm mỹ. Vẽ lục địa? Điểm thưởng. Kết cấu lục địa? Điểm thưởng. Trên trái đất 3D? Có mây? Sao? Sao đúng ? Điểm thưởng lớn. Và như vậy.

  • Sử dụng công nghệ không phổ biến, cũ, hoặc chỉ đơn giản là sai. Chắc chắn, bạn có thể đánh nó trong Mathicala, nhưng bạn đã cân nhắc sử dụng m4chưa? SQL? Forth? lắp ráp x86?

  • Vui vẻ. Bạn muốn sử dụng bản đồ chiếu Dymaxion ? Hãy tiếp tục!

  • Mã ngắn. Đây là Code Golf SE, sau tất cả.

Chúc vui vẻ!


3
@PeterTaylor Có lẽ! Tôi nghĩ bạn thậm chí không cần phải chiếu sáng: bạn có thể vẽ một trái đất 3D và xoay nó để phần ánh sáng ban ngày (và không có gì khác) đối diện với người xem. Nó sẽ không hiển thị phần ban đêm của hành tinh, nhưng điều đó không bắt buộc.
Đi lang thang Nauta

30
Một giải pháp thay thế đơn giản là cài đặt windows. (Trong tầng hầm, ý tôi là.)
squossish ossifrage

2
@qwr Tôi sẽ thực hiện lắp ráp x86 vào m4bất kỳ ngày nào trong tuần cho nhiệm vụ này ...
Wander Nauta

3
Ngoài ra: "mặt trời khá bồn chồn vì nó mọc và lặn vào những thời điểm khác nhau." Chắc chắn là lỗi của mặt trời: P
qwr 17/03/2016

2
@qwr Bạn đã bao giờ nghĩ về việc tính toán thời gian / ngày sẽ dễ dàng như thế nào nếu chúng ta có các ngày 10 giờ, tuần 10 ngày, tháng 10 tuần và năm 10 tháng và mặt trời giữa t = 0 và t = 5? Nhưng không, mặt trời phải đi và thể hiện khuôn mặt xấu xí của nó ở những nơi khác nhau vào những thời điểm khác nhau và mất quá nhiều thời gian để đi vòng quanh trái đất. Không có khiếu nại phân chia. Kinh tởm
Đi lang thang Nauta

Câu trả lời:


89

Haskell - mã chất lượng thấp

Tôi đã vô cùng mệt mỏi khi tôi viết điều này.

Tôi có thể đã đi quá xa với ý tưởng dự đoán, dù sao, đây là dự đoán mà chương trình sử dụng. Về cơ bản giống như chiếu trái đất lên một khối lập phương và sau đó mở ra nó. Bên cạnh đó, trong phép chiếu này, bóng được tạo thành từ các đường thẳng.
Chương trình sử dụng ngày / giờ hiện tại và xuất ra tệp PPM trên thiết bị xuất chuẩn.

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)

Điều đó đúng - wheremã hình tam giác , cases lồng nhau , sử dụng IO không hợp lệ.


Đó là một tác phẩm của thiên tài xoắn. Một đề nghị, fromIntegral (fromEnum $ utctDayTime c)là gọn gàng hơn (realToFrac $ utctDayTime c). (Tôi chỉ học được điều này trong khi viết câu trả lời của mình)
bazzargh 17/03/2016

8
Tôi có thể xem .gif cả ngày.
MikeTheLiar

mnlip, tôi đồng ý với @mikeTheLiar. Bạn nên nhúng gif đó ngay đầu câu trả lời của bạn, bạn sẽ nhận được tất cả các phiếu bầu.
bazzargh 17/03/2016

1
Tôi đã bỏ phiếu duy nhất trên gif lập dị. Đó chỉ là một cách xoắn để nhìn thế giới.
Allen Gould

bao giờ hơi quá nhanh
Pharap 17/03/2016

61

Haskell, trong danh mục 'bởi vì nó có'

Tôi tò mò vì vậy tôi đã viết một. Các công thức có độ chính xác hợp lý [1], nhưng sau đó tôi đi và sử dụng một số nghệ thuật ascii thay vì bản đồ Tấm Carrée thích hợp, bởi vì nó trông đẹp hơn (cách tôi chuyển đổi pixel thành lat / long chỉ hoạt động chính xác cho Tấm 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"]

Ví dụ đầu ra, từ một thời điểm thú vị hơn trong năm (chúng ta đang ở gần điểm cân bằng, vì vậy các đốm hình chữ nhật của Wander Nauta khá chính xác :)) - đây là ngày 16 tháng 1 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] chúng giống như bạn sẽ tìm thấy ở nơi khác, ngoại trừ không có công việc phụ để giữ độ trong khoảng từ 0 đến 360, giờ từ 0 đến 24 và radian trong khoảng từ 0 đến 2pi. Tôi nghĩ đó là những sự nắm giữ từ những ngày chúng ta sử dụng quy tắc trượt; chức năng trig hoạt động tốt ngoài phạm vi đó ...


7
Xuất sắc! Tôi thích rằng bạn vẫn có thể nhìn thấy bản đồ thông qua 'bóng tối'. Ngoài ra, toán học có vẻ vững chắc. Bạn có thể thêm ngày bạn sử dụng làm ví dụ để người khác có thể so sánh các giải pháp của họ với bạn không?
Đi lang thang Nauta

Tôi thấy rằng bạn đã thêm ngày, cảm ơn!
Đi lang thang Nauta

1
Vâng. Tôi thích điều đó trong hình ảnh bạn có thể thấy rõ rằng đó là mùa đông ở Bắc bán cầu, khiến ngày đó dễ tin hơn! Tôi rất vui vì bạn đã đăng câu trả lời trước tôi, đã cứu tôi vô tận khi cố gắng làm một phiên bản chơi gôn, không có cách nào tôi sẽ đánh bại bạn vì điều đó.
bazzargh

39

Hoạt hình

.

Bash, 882 * ký tự

Đây là mục thứ hai của tôi, lần này là trong các danh mục thẩm mỹ , Công nghệ kỳ lạ , Vui nhộnNgắn . Nó lấy cảm hứng từ bài viết của Ram Narasimhan và bình luận của Peter Taylor.

Kịch bản đầu tiên tạo ra kết cấu độ phân giải thấp của thế giới, được đóng gói dưới dạng dữ liệu được mã hóa base64. Sau đó, nó tạo ra 24 cảnh PovRay chứa một hình cầu có kết cấu đó, mỗi cảnh quay để 'đối mặt với mặt trời'. Cuối cùng, các khung được kết hợp thành một hình ảnh động GIF bằng ImageMagick. Điều này có nghĩa là bạn sẽ phải cài đặt cả PovRay và ImageMagick để tập lệnh hoạt động - hãy bỏ qua mục này nếu bạn nghĩ rằng điều đó không đủ tiêu chuẩn.

Giống như mục nhập của Ram và mục nhập đầu tiên của tôi, điều này không tính đến sự thay đổi theo mùa, điều đó có nghĩa là nó không chính xác lắm. Tuy nhiên, nó ngắn hơn, đẹp hơn và chính xác hơn mục nhập đầu tiên của tôi - và không giống như mục nhập của Ram, dữ liệu bản đồ và mã để tạo hoạt hình GIF được bao gồm.

                               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;

Như một phần thưởng , đây là một GIF sử dụng hình ảnh Blue Marble của NASA thay vì kết cấu 1 bit tiết kiệm không gian, tức là kết quả sẽ trông như thế nào mà không bị giới hạn kích thước: http://i.imgur.com/AnahEIu.gif

*: 882 ký tự không tính khoảng trắng trang trí, tổng cộng 1872 ký tự.


5
+1 để làm cho tất cả khép kín. Và cũng để tạo mã tự tham chiếu giống như bản đồ thế giới. Công việc tốt đẹp.
Ram Narasimhan

1
argh nhiều mục. Bây giờ tôi đang mất lý do để không làm điều điên rồ ...
bazzargh

1
Thật buồn nôn! Yêu nó.
Đại bàng

Heh, tôi nhận ra rằng bây giờ tôi có thể sử dụng định dạng của mã làm nguồn cho bản đồ thế giới (với khoảng cách = đại dương, mọi thứ khác = đất) và thực sự có độ phân giải tốt hơn với ít ký tự hơn. Ôi
chà

2
Điều này trông giống như Minecraft.
Kaz Wolfe

25

Tôi quyết định khởi động cuộc thi với một mục của riêng tôi, trong thể loại mã ngắn . Nó dài 923 ký tự, không tính dòng mới.

C: 923 ký tự

Đây là mã:

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

Đây là cách nó hoạt động:

Một bitmap thô của thế giới * được mã hóa theo chiều dài chạy dưới dạng chuỗi. Mỗi ký tự trong chuỗi biểu thị một chuỗi các pixel trên mặt đất hoặc trên biển. Các chuỗi dài của biển được chia thành một vùng biển, sau đó là 0 pixel trên mặt đất, sau đó là một lần chạy trên biển khác, để tránh bao gồm các ký tự không thể in được trong chuỗi. Kịch bản Python tôi đã viết để chuyển đổi các tệp PBM sang định dạng này có ở đây .

Sau đó, tôi sử dụng thời gian () để tìm hiểu có bao nhiêu giây đã trôi qua ở Greenwich kể từ nửa đêm, ngày 1 tháng 1 năm 1970. Tôi điều chỉnh để tìm hiểu xem hôm nay đã trôi qua bao nhiêu giây, sử dụng thông tin đó để định vị phần ánh sáng của bản đồ nhiều hơn- hoặc ít hơn cho phù hợp (tôi hy vọng).

Đúng là một trò đùa. Không có toán học nào cả. Mã giả định trái đất là một hình trụ (ngày / đêm hình khối), rằng mặt trời nằm ngay trên đường xích đạo (không có mùa hè / mùa đông) và bạn thích màu xám (không màu).

Về mặt tích cực, tôi vẽ các châu lục.

Đầu ra ở định dạng Portable Graymap (PGM), sau đó có thể được chuyển đổi thành PNG bằng một cái gì đó như ImageMagick hoặc GIMP.

Đây là một ví dụ đầu ra, được chuyển đổi thành PNG ( phiên bản lớn hơn ):

Ví dụ đầu ra

*: Toàn bộ thế giới ngoại trừ Nam Cực, nhưng dù sao cũng sống ở đó ...


1
Đẹp ra, nó sẽ là tốt hơn nếu vùng tối được cong mặc dù
qwr

1
Vâng! Có đầu ra bị cong có nghĩa là bạn sẽ phải thực hiện một số lượng giác, điều đó sẽ làm cho nó dài hơn nhiều. (Hoặc tôi đoán bạn có thể chỉ cần làm tròn các góc chính xác để làm cho nó trông đúng ...)
Wander Nauta

1
@WanderNauta Sẽ có một số chim cánh cụt nổi giận dữ dội sẽ cảm thấy bị lừa dối mà bạn đã không xem xét chúng, bro ...
WallyWest 17/03/2016

@WallyWest Nếu bạn sống ở các cực, như chim cánh cụt của bạn, bạn không cần chương trình này - nửa đêm và tất cả.
Đi lang thang Nauta

22

Haskell - đó là thời gian Búa.

nhập mô tả hình ảnh ở đây

Tôi đã làm một cái khác. Được chuyển thể từ phiên bản trước của tôi, phiên bản này sử dụng phép chiếu Búa xiên để hiển thị cả hai cực cùng một lúc (thực tế là bạn đang nhìn thấy toàn bộ trái đất trong mỗi khung hình). Chỉ để thêm sự kỳ lạ, thay vì sử dụng trực tiếp một bitmap, tôi đã lấy mẫu trái đất dọc theo hình xoắn ốc để đưa ra diện tích bao phủ gần bằng nhau; đây là những gì cho phép tôi làm biến dạng trái đất và xoay nó dễ dàng. Hình chiếu của búa cũng có diện tích bằng nhau; ý tưởng của tôi là việc ghép hai thứ này sẽ dẫn đến ít biến dạng hơn khi tôi điền vào các khoảng trống. Tôi cũng hiển thị một lưới trên hình chiếu, sử dụng thuật toán của Bresenham để vẽ các đường. Cả thế giới và dòng terminator đều di chuyển trong suốt cả ngày.

Đã chỉnh sửa để thay đổi hình ảnh thành độ phân giải cao hơn nhưng (cố tình) thô hơn bitmap bên dưới, để bạn có thể thấy hiệu ứng của hình xoắn ốc. Điều này sử dụng 5000 điểm (được lấy mẫu từ ~ 260000 ), tương đương với bitmap 50x100, nhưng mang lại độ phân giải nhiều hơn cho đường xích đạo so với các cực.

Để sử dụng mã, biên dịch với ghc, chạy với một tham số số tùy chọn là phần bù giờ; các tệp được tạo như '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
Đây là ... sự điên rồ. Sự điên rồ tuyệt đối. Tôi thích nó.
Đi lang thang Nauta

1
Tôi đã mất rất lâu để có được sự biến đổi ngay trên cái này. Các bitmap xoắn ốc một mình là vui nhộn.
bazzargh

lại "nó tăng quy mô khá tốt" - ý bạn là bạn có thể dễ dàng tạo một GIF có độ phân giải cao hơn?
Đi lang thang Nauta

Đúng. khá lớn hơn nhiều Tôi đã lấy mã đó ra một chút trong khi tôi rối tung với mạng lưới, khi tôi có thời gian một
lát

1
có bạn đi - hình ảnh lớn đẹp của crazytown
bazzargh

21

C, sử dụng hình ảnh pnm

Trả lời muộn, tập trung vào tính chính xácthẩm mỹ . Đầu ra là sự pha trộn của hai hình ảnh đầu vào (day.pnm và night.pnm), bao gồm một dải màu chạng vạng. Tôi đang sử dụng hình ảnh dựa trên đá cẩm thạch màu xanh của NASAs tại đây.

Mã này sử dụng img.h của riêng tôi để rõ ràng (chỉ cần tưởng tượng nó được đưa vào nguyên văn trong .c để tuân thủ quy tắc nghiêm ngặt ...). Tất cả mọi thứ trong đó được thực hiện thông qua các macro C. Các hình ảnh động được xây dựng với hình ảnh chuyển đổi từ nhiều khung - bản thân chương trình sẽ chỉ xuất hình ảnh tĩnh. Mã dưới đây.

Bây giờ: (13 tháng 8, ~ 13: 00 CEST)

đầu ra

Một ngày: (ngày 1 tháng 1)

một ngày

Một năm: (12:00 UTC)

một năm

mặt trời

  #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ất đẹp! Tôi thích nó.
Đi lang thang Nauta

18

R: Sử dụng ggplot2 và phép chiếu Map

nhập mô tả hình ảnh ở đây

Lấy cảm hứng từ bài đăng của @ mniip, tôi quyết định thử sử dụng gói mapproj của R, trong đó chúng ta có thể định hướng toàn cầu bằng cách chỉ định vị trí của Bắc Cực khi tính toán phép chiếu.

Dựa trên thời gian GMT hiện tại, tôi tính toán kinh độ hiện tại là buổi trưa và biến điểm đó thành trung tâm của bản đồ. Chúng ta đang nhìn Trái đất từ ​​"quan điểm của Mặt trời" để mọi thứ có thể nhìn thấy được là vào ban ngày.

Phần lớn mã chỉ là tính thẩm mỹ. Phần duy nhất tôi phải tìm ra là tính toán "Kinh độ buổi trưa", đó là giá trị kinh độ mà buổi trưa được đưa ra vào bất kỳ thời gian GMT nào.

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

Sau đó, tôi đã sử dụng gói hoạt hình R để tạo 24 hình ảnh và ghép chúng vào một GIF.


Trông thật tuyệt! Liệu nó có xử lý chính xác mùa hè và mùa đông không? Tôi không biết R rõ lắm, nhưng có vẻ như đường xích đạo của bạn luôn ở trung tâm của hình ảnh.
Đi lang thang Nauta

Vâng, bạn đúng. Tôi đã thực hiện một cách nhanh chóng và bẩn thỉu bằng cách sử dụng đường xích đạo làm vĩ độ duy nhất. (Tập trung vào hoạt hình thay thế.) Dự án có rất nhiều tính năng mà tôi không sử dụng. Nếu có một tài liệu tham khảo cho thấy cách thay đổi vĩ độ theo mùa, tôi sẽ rất vui khi dùng thử.
Ram Narasimhan

Đây là một tài liệu tham khảo trong R, Ram - thực tế đây là nơi tôi đã dịch các công thức trong mục nhập của mình từ stackoverflow.com/questions/8708048/ trên
bazzargh 18/03/2016

@bazzargh Cảm ơn! Có vẻ như tôi có rất nhiều học hỏi về góc phương vị để làm.
Ram Narasimhan

9

JavaScript - của Martin Kleppe ( http://aem1k.com/ )

Tôi muốn nhấn mạnh rằng đây không phải là công việc của tôi, mà là công việc của Martin Kleppe. Tôi chỉ nghĩ rằng nó phù hợp hoàn hảo đến mức không nên thiếu ở đây:

Demo trực tuyến (hoặc chỉ cần dán nó vào bảng điều khiển)

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
Nếu đó không phải là công việc của bạn, bạn nên biến câu trả lời của mình thành wiki cộng đồng.
Kyle Kanos

1
Cảm ơn các mẹo, không bao giờ nhận thấy rằng hộp kiểm tra trước. Làm xong!
Ingo Bürk
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.