2010-03-26 35 views
29

Có ai biết thuật toán tính giai đoạn mặt trăng hoặc tuổi vào một ngày nhất định hoặc tìm ngày tháng cho các mặt trăng mới/đầy đủ trong một năm nhất định không?Thuật toán giai đoạn mặt trăng/mặt trăng

Googling cho tôi biết câu trả lời nằm trong một số cuốn sách Thiên văn học, nhưng tôi thực sự không muốn mua toàn bộ cuốn sách khi tôi chỉ cần một trang duy nhất.

Cập nhật:

tôi nên đã đủ điều kiện tuyên bố của tôi về googling tốt hơn một chút. Tôi đã tìm ra các giải pháp chỉ làm việc trên một số tập hợp thời gian (như những năm 1900); và các giải pháp dựa trên trig sẽ đắt hơn tính toán tôi muốn.

S Lott trong cuốn sách Python của ông có một số thuật toán để tính toán lễ Phục sinh trong một năm nhất định, hầu hết dưới mười dòng mã và một số công việc cho tất cả các ngày trong lịch Gregorian. Tìm kiếm trăng tròn vào tháng 3 là một phần quan trọng trong việc tìm kiếm lễ Phục sinh vì vậy tôi đã tìm ra một thuật toán không đòi hỏi phải có trig và hoạt động cho tất cả các ngày trong lịch Gregorian.

+0

Vấn đề tương tự là ở đây các chùm lần ẩn trong vấn đề xác định ngày lễ Phục Sinh, Lint, Thứ Sáu Tuần Thánh, và/hoặc lễ Vượt Qua. – nategoose

+5

Một mô hình thiên văn chính xác là không thể tránh khỏi phức tạp; tính toán cho trăng tròn mà từ đó ngày lễ Phục Sinh được bắt nguồn (xem http://en.wikipedia.org/wiki/Paschal_full_moon) sử dụng một mô hình đơn giản. –

+1

Sử dụng tuyệt vời cho moon.py được trích dẫn trong câu trả lời đã chọn là viết một ứng dụng GUI (tôi sẽ đi với GTK) để hiển thị giai đoạn mặt trăng với hình ảnh mặt trăng (thực ra tôi đang cố gắng làm điều này, trở nên dễ dàng hơn với câu hỏi này và câu trả lời của nó ...) – heltonbiker

Trả lời

15

Tôi đã chuyển một số mã sang Python trong thời gian này. Tôi sẽ chỉ liên kết với nó, nhưng nó chỉ ra rằng nó rơi ra khỏi web trong khi chờ đợi, vì vậy tôi đã phải đi bụi nó đi và tải nó lên một lần nữa. Xem moon.py có nguồn gốc từ John Walker's moontool.

Tôi không thể tìm thấy tài liệu tham khảo cho điều này cho khoảng thời gian nào nó chính xác cho một trong hai, nhưng có vẻ như các tác giả khá nghiêm ngặt. Có nghĩa là có, nó sử dụng trig, nhưng tôi không thể tưởng tượng những gì bạn sẽ sử dụng heck này cho rằng sẽ làm cho nó tính toán nghiêm cấm. Hàm chi phí cuộc gọi hàm Python có thể nhiều hơn chi phí của các hoạt động của trig. Máy tính khá nhanh ở tính toán.

Các thuật toán sử dụng trong mã được rút ra từ các nguồn sau:

Meeus, Jean. Thuật toán thiên văn. Richmond: Willmann-Bell, 1991. ISBN 0-943396-35-2.

Phải có; nếu bạn chỉ mua một cuốn sách, hãy đảm bảo nó là cuốn sách này. Các thuật toán được trình bày bằng toán học, không phải là các chương trình máy tính, nhưng mã nguồn thực hiện nhiều thuật toán trong sách có thể được đặt riêng biệt với nhà xuất bản trong QuickBasic, Turbo Pascal hoặc C. Meeus cung cấp nhiều ví dụ về tính toán cần thiết để gỡ lỗi mã của bạn, và thường xuyên trình bày một số thuật toán với sự cân bằng khác nhau giữa độ chính xác, tốc độ, độ phức tạp và giá trị lâu dài (thế kỷ và thiên niên kỷ).

Duffett-Smith, Peter. Thực tế Thiên văn học với máy tính của bạn. Ed thứ 3 Cambridge: Nhà in Đại học Cambridge, 1981. ISBN 0-521-28411-2.

Mặc dù từ tính trong tiêu đề; đây là một tài liệu tham khảo có giá trị nếu bạn quan tâm đến việc phát triển phần mềm tính toán vị trí hành tinh, quỹ đạo, nhật thực và những thứ tương tự. Thông tin cơ bản hơn được đưa ra hơn là trong Meeus, giúp những người không thông thạo thiên văn học học thuật ngữ thường khó hiểu. Các thuật toán được đưa ra đơn giản và kém chính xác hơn so với các thuật toán được cung cấp bởi Meeus, nhưng phù hợp cho hầu hết các công việc thực tế.

+14

"Máy tính hoạt động khá nhanh." - Tôi thích nó! Tôi có thể phải trích dẫn điều đó. –

+0

Tôi đang làm việc trên một hệ thống lịch cho Oracle và Postgres. Tôi muốn có thể tìm thấy ngày dựa trên giai đoạn mặt trăng. Và điều đó có thể có nghĩa là thực hiện phép tính này trong một loạt các ngày. Và tốn kém tính toán = lượt truy cập từ DBA. :) –

+0

Các bit quan trọng ở đây, tất nhiên, là mã của keturn và mã của John Walker đều chứa tham chiếu đến các nguồn có thẩm quyền mà mã của chúng có thể được kiểm tra. Các nguồn này được liệt kê [ở đây] (http://www.fourmilab.ch/moontoolw/moontool16.html). – Richard

11
+2

@Jack: WOW! +1 ... Bộ nhớ. Tôi không thể biết tôi đã biết cái tên đó từ đâu: "Ben Daglish". Ông là một trong những nhà soạn nhạc giỏi nhất (tôi đã nói * một *;) về nhạc 8 bit trên C64 trong những ngày qua. Tuyệt vời để tìm một liên kết đến anh ta cho một cái gì đó hoàn toàn không liên quan (tôi đã phải tìm kiếm trough trang web của mình cho đến khi tôi tìm thấy các liên kết C64 để nhớ nơi tôi biết rằng tên từ). – SyntaxT3rr0r

+5

-1 Một trong những tính năng tốt đẹp của StackOverflow là mọi người có thể đến đây để tìm câu trả lời, thay vì liên kết đến câu trả lời. Ngoài ra, liên kết hàng đầu của bạn bị hỏng, liên kết thứ hai của bạn không có trích dẫn nào để thuyết phục một lập trình viên cẩn thận rằng các thuật toán được liệt kê trong đó là chính xác, liên kết thứ ba của bạn có trích dẫn, nhưng mã đã bị thay đổi từ bản gốc. Liên kết thứ tư cũng có vấn đề tương tự. – Richard

+1

Google của ai? Các hit là REALLY khác nhau cho những người khác nhau. – jkj

-1

Một google nhanh chóng tiết lộ this.

+0

Tôi tìm thấy điều này, hoặc là rất dễ dàng hơn mặc dù rất giống với kết quả moon.py (trên câu trả lời đã chọn). – heltonbiker

+1

-1 Một trong những tính năng tốt đẹp của StackOverflow là mọi người có thể đến đây để tìm câu trả lời, thay vì liên kết đến câu trả lời. Ngoài ra, mã bạn liên kết đến không có tham chiếu nào để thuyết phục một lập trình viên cẩn thận rằng mã đó là chính xác. – Richard

0

Tôi biết rằng bạn đang tìm kiếm Python nhưng nếu bạn có thể hiểu C# có một dự án nguồn mở có tên là Chronos XP, điều này rất tốt.

+0

Tôi có thể đọc khá nhiều thứ ngoài Perl. LOL. Nhưng Chronos XP có vẻ là một ứng dụng chiêm tinh hơn là thiên văn học. –

+1

Tìm trong tệp có tên LunarPhase.cs. Lớp đó về cơ bản làm những gì nó nói. Đó là một trong những triển khai tốt hơn tôi đã tìm thấy, điều này thật không may vì nó vẫn phức tạp. Nếu bạn không muốn tải xuống toàn bộ mã nguồn, hãy tìm kiếm tên tệp đó trên Google Code. –

-1

Nếu bạn không cần độ chính xác cao, bạn luôn có thể (ab) sử dụng lớp lịch âm (hoặc lunisolar) (ví dụ: HijriCalendar hoặc ChineseLunisolarCalendar trong Microsoft .NET) để tính giai đoạn mặt trăng (gần đúng) của bất kỳ ngày nào , là thuộc tính "ngày trong tháng" của lịch, là ngày dương lịch (hoặc âm lịch), luôn tương ứng với giai đoạn mặt trăng (ví dụ, ngày 1 là mặt trăng mới, ngày 15 là trăng tròn, v.v.)

+3

-1 để đề cập đến .NET – klemens

10

Nếu bạn giống tôi, bạn cố gắng trở thành một lập trình viên cẩn thận. Vì vậy, nó làm cho bạn lo lắng khi bạn thấy mã ngẫu nhiên rải rác trên internet mà purports để giải quyết một vấn đề thiên văn phức tạp, nhưng không giải thích tại sao giải pháp là chính xác.

Bạn tin rằng phải có các nguồn có thẩm quyền như sách chứa các giải pháp cẩn thận và đầy đủ. Ví dụ:

Meeus, Jean. Thuật toán thiên văn. Richmond: Willmann-Bell, 1991. ISBN 0-943396-35-2.

Duffett-Smith, Peter. Thực tế Thiên văn học với máy tính của bạn. Ed thứ 3 Cambridge: Nhà in Đại học Cambridge, 1981. ISBN 0-521-28411-2.

Bạn đặt niềm tin của mình vào các thư viện nguồn mở được kiểm tra rộng rãi, được kiểm tra rộng rãi, có thể sửa lỗi (không giống như các trang web tĩnh). Sau đó, là giải pháp Python cho câu hỏi của bạn dựa trên thư viện PyEphem, sử dụng giao diện Phases of the Moon.

#!/usr/bin/python 
import datetime 
import ephem 

def get_phase_on_day(year,month,day): 
    """Returns a floating-point number from 0-1. where 0=new, 0.5=full, 1=new""" 
    #Ephem stores its date numbers as floating points, which the following uses 
    #to conveniently extract the percent time between one new moon and the next 
    #This corresponds (somewhat roughly) to the phase of the moon. 

    #Use Year, Month, Day as arguments 
    date=ephem.Date(datetime.date(year,month,day)) 

    nnm = ephem.next_new_moon (date) 
    pnm = ephem.previous_new_moon(date) 

    lunation=(date-pnm)/(nnm-pnm) 

    #Note that there is a ephem.Moon().phase() command, but this returns the 
    #percentage of the moon which is illuminated. This is not really what we want. 

    return lunation 

def get_moons_in_year(year): 
    """Returns a list of the full and new moons in a year. The list contains tuples 
of either the form (DATE,'full') or the form (DATE,'new')""" 
    moons=[] 

    date=ephem.Date(datetime.date(year,01,01)) 
    while date.datetime().year==year: 
    date=ephem.next_full_moon(date) 
    moons.append((date,'full')) 

    date=ephem.Date(datetime.date(year,01,01)) 
    while date.datetime().year==year: 
    date=ephem.next_new_moon(date) 
    moons.append((date,'new')) 

    #Note that previous_first_quarter_moon() and previous_last_quarter_moon() 
    #are also methods 

    moons.sort(key=lambda x: x[0]) 

    return moons 

print get_phase_on_day(2013,1,1) 

print get_moons_in_year(2013) 

này trả

0.632652265318 

[(2013/1/11 19:43:37, 'new'), (2013/1/27 04:38:22, 'full'), (2013/2/10 07:20:06, 'new'), (2013/2/25 20:26:03, 'full'), (2013/3/11 19:51:00, 'new'), (2013/3/27 09:27:18, 'full'), (2013/4/10 09:35:17, 'new'), (2013/4/25 19:57:06, 'full'), (2013/5/10 00:28:22, 'new'), (2013/5/25 04:24:55, 'full'), (2013/6/8 15:56:19, 'new'), (2013/6/23 11:32:15, 'full'), (2013/7/8 07:14:16, 'new'), (2013/7/22 18:15:31, 'full'), (2013/8/6 21:50:40, 'new'), (2013/8/21 01:44:35, 'full'), (2013/9/5 11:36:07, 'new'), (2013/9/19 11:12:49, 'full'), (2013/10/5 00:34:31, 'new'), (2013/10/18 23:37:39, 'full'), (2013/11/3 12:49:57, 'new'), (2013/11/17 15:15:44, 'full'), (2013/12/3 00:22:22, 'new'), (2013/12/17 09:28:05, 'full'), (2014/1/1 11:14:10, 'new'), (2014/1/16 04:52:10, 'full')] 
1

Pyephem theo mặc định sử dụng phối hợp phổ quát (UTC) thời gian. Tôi muốn một chương trình sẽ tạo ra một danh sách các mặt trăng đầy đủ sẽ chính xác trong múi giờ Thái Bình Dương. Đoạn mã dưới đây sẽ tính toàn bộ các mặt trăng trong một năm nhất định và sau đó điều chỉnh bằng cách sử dụng phương thức ephem.localtime() để hiệu chỉnh theo múi giờ mong muốn. Nó cũng xuất hiện để đúng tài khoản cho thời gian tiết kiệm ánh sáng ban ngày là tốt. Cảm ơn Richard, mã này tương tự như những gì anh viết.

#!/usr/bin/python 
import datetime 
import ephem 
import os 
import time 

# Set time zone to pacific 
os.environ['TZ'] = 'US/Pacific' 
time.tzset() 

print("Time zone calibrated to", os.environ['TZ']) 

def get_full_moons_in_year(year): 
    """ 
    Generate a list of full moons for a given year calibrated to the local time zone 
    :param year: year to determine the list of full moons 
    :return: list of dates as strings in the format YYYY-mm-dd 
    """ 
    moons = [] 

    date = ephem.Date(datetime.date(year - 1, 12, 31)) 
    end_date = ephem.Date(datetime.date(year + 1, 1, 1)) 

    while date <= end_date: 
     date = ephem.next_full_moon(date) 

     # Convert the moon dates to the local time zone, add to list if moon date still falls in desired year 
     local_date = ephem.localtime(date) 
     if local_date.year == year: 
      # Append the date as a string to the list for easier comparison later 
      moons.append(local_date.strftime("%Y-%m-%d")) 

    return moons 

moons = get_full_moons_in_year(2015) 
print(moons) 

Đoạn mã trên sẽ trở lại:

Time zone calibrated to US/Pacific 
['2015-01-04', '2015-02-03', '2015-03-05', '2015-04-04', '2015-05-03', '2015-06-02', '2015-07-01', '2015-07-31', '2015-08-29', '2015-09-27', '2015-10-27', '2015-11-25', '2015-12-25'] 
Các vấn đề liên quan