Skocz do zawartości

Implementacja Sidereal time w programie - Program na Iphone


Rekomendowane odpowiedzi

Witam,  w ramach nauki programowania w Swifcie założyłem sobie pewien plan wykonania aplikacji oczywiście na własne potrzeby jednak utknąłem na wyliczeniach astronomicznych. Finalnie potrzebuję wyliczyć Sidereal time dla teraźniejszej daty i mojej lokalizacji i wychodzą mi błedne wyniki. Może ktoś z Was obeznany w tego typu algorytmach byłby w stanie zerknąć co robię nie tak. Daty jakie mi wychodzą to np. data -4711.03.12 czyli coś przed naszą erą :icon_eek:. Próbowałem różnych algorytmów bo jest ich całkiem sporo w internecie ale wszystkie pokazują mi podobny wynik finalny.

 

Funkcja zwracająca liczbę dni juliańskich od początku okresu juliańskiego - z moich wyliczeń wygląda że działa dobrze :icon_cool:

func toJulian (date date: NSDate) -> Double
	{
        let daySeconds : Double = 60 * 60 * 24
        let J1970 = 2440588.0                       //wartość juliańska dla 1.01.1970
        return date.timeIntervalSince1970 / daySeconds - 0.5 + J1970       
    }

 

funkcja liczy ilość dni od podanej daty w argumencie od roku 2000.01.01

func daysSinceJan12000 (date date: NSDate) -> Double
	{
      	let J2000 = 2451545.0				//wartość juliańska dla 1.01.2000
        return toJulian(date: date) - J2000
    }

 

Główna funkcja licząca sidereal time. Longitude dla mojej lokalizacji (Częstochowa) to 19.06. Tutaj nie jestem pewien bo powinno być wartość na zachód od głównego południka ale ta wartość jest dla wyniku końcowego nieznacząca na tyle że bruździ mi wyniki od ponad 5000 lat.

func siderealTime (daysSinceJan12000 daysSinceJan12000: Double, longitude: Double) -> Double
	{   
        return (280.16 + 360.9856235 * daysSinceJan12000) - longitude
    }

Może ktoś z Was zauważy gdzie mam błąd ? Może wszystko jest zwalone :flirt:

Edytowane przez coy_coyote
Odnośnik do komentarza
Udostępnij na innych stronach

Nie znam się na Swifcie (bardziej C++), ale domyślam się, że kolejność działań jest taka sama, jak w matematyce?

11 minut temu, coy_coyote napisał:

return date.timeIntervalSince1970 / daySeconds - 0.5 + J1970

To jest jakieś podejrzane dla mnie, skąd to 0.5? Na pewno nie w nawiasie w mianowniku? Ale nie znam się na latach juliańskich itp. :)

daySeconds nie jest raczej  23 godziny 56 minut i 4,1 sekundy?

Ogólnie proponuję zrobić testy:

wymyśl kilka wartości argumentów Twoich funkcji (w szczególności "toJulian" i "daysSinceJan12000"), oblicz "ręcznie" albo sprawdź w necie poprawne wartości,

następnie napisz krótki program w którym używasz tych funkcji z tymi argumentami i sprawdź (np. wydrukuj na ekran wartości oczekiwane i obliczone), czy zwracają oczekiwane wartości.

Kilka przykładów do sprawdzenia:

toJulian(NSDate = 1.1.1970 ) = 0?

daysSinceJan12000(NSDate = 1.1.2000) = 0?

daysSinceJan12000(NSDate = 1.1.1970) = 10957? (2451545.0 - 2440588.0)

 

dodatkowo, co to są za liczby:

280.16?

360.9856235?

Proszę je ładnie nazwać a nie używać gołych liczb, to taka rada na przyszłość :)

Pozdrawiam!

 

Odnośnik do komentarza
Udostępnij na innych stronach

Licz roznice dni w UNIX time. Stosowne "kalendarze" powinny juz byc zaimplementowane w jezyku programowania.

4 godziny temu, Behlur_Olderys napisał:

dodatkowo, co to są za liczby:

280.16?

360.9856235?

Przeliczenie rektascensji na miare katowa?

Napisalem na szybko i troche niestarannie w C++. Wynik podany jest w minutach. Rezultat sprawdzalem na http://tycho.usno.navy.mil/sidereal.html

#include <iostream>
#include <cmath>

double daysSinceJan12000();
double siderealTime(double);

main()
{
  double longitude = 20;
  std::cout << "Days since 1/1/2000 12:00: " << daysSinceJan12000() << "\nSideral time: " << siderealTime(longitude) << " minutes\n";
}

double daysSinceJan12000()
{
  time_t rawtime;
  struct tm* timeinfo;

  int year = 2000, month = 1, day = 1, hour = 12, min = 0, sec = 0;

  time(&rawtime);
  timeinfo = localtime(&rawtime);

  timeinfo->tm_year = year - 1900;
  timeinfo->tm_mon = month - 1; // months since January - [0,11]
  timeinfo->tm_mday = day;      // day of the month - [1,31]
  timeinfo->tm_hour = hour;     // hours since midnight - [0,23]
  timeinfo->tm_min = min;       // minutes after the hour - [0,59]
  timeinfo->tm_sec = sec;       // seconds after the minute - [0,59]

  unsigned long date = timegm(timeinfo);
  double days = (double)(time(NULL) - date) / (double)(24 * 60 * 60);
  return days;
}

double siderealTime(double lng)
{
  double sideral = (double)18.697374558 + (double)24.06570982441908 * (double)daysSinceJan12000() + (double)12*lng/180.0;
  sideral = sideral - (double)24 * (floor)(sideral / 24);
  return 60*sideral;
}
Edytowane przez r.ziomber
  • Lubię 2
Odnośnik do komentarza
Udostępnij na innych stronach

wybaczcie Panowie, jestem na początku drogi w  Swifcie, poza tym mam dawne naleciałości z Pascala i Delphi ale to też było lata temu.

C++, Objective-C to dla mnie na razie nowość stąd mam jeszcze spore braki. Pewnie znajomość C++ dużo by mi pomogła.

Zamiana na dni juliańskie jest u mnie OK +/- 1 godzina, sprawdzałem wczoraj z algorytmem Piotra Brycha i innymi dostępnymi w internecie.

Do sprawdzenia mam pozostałe funkcje. Te wartości o których pisałeś  @Behlur_Olderys są wzięte z innego algorytmu i jak słucznie zauważył Radek są to wartości kątowe bo ogólnie sideRealTime będą docelowo w radianach. Program ma pokazywać pozycję gwiazdy Polarnej na osi godzinowej.

Dlatego tam wrzucając swoją funkcję popełniłem mały błąd w funkcji sideRealTime bo tam powinno być:

let rad = Double.pi/180
return rad * (280.16 + 360.9856235 * daysSinceJan12000) - longitude //longitude w radianach

Radek, Twój kod to zbawienie (tak mi się wydaje :emotion-5:). Jeżeli sprawdzałeś go z tym kalkulatorem, który podlinkowałeś to będzie OK. Jeżeli u mnie to nie pójdzie teraz będę wiedział gdzie szukać błedu. Możliwe właśnie że w konwersji mojego typu daty w klasie NSDate.

Bardzo Ci dziękuję, dzisiaj postaram się go przerobić na Swifta i spróbować Twojego sposobu. Zobaczymy co z tego wyjdzie.

Wrzuciłem Twój kod tak na szybko do DEV C++ ale wyrzuca mi błąd " [Error] 'timegm' was not declared in this scope" pomimo że zaimportowałem dodatkowo <time.h>. Bardzo Cię proszę jeszcze raz o wyrozumiałość na moje braki w tym temacie - nie wiem czy nie porywam się na zbyt wysokie progi :flirt: ale próbuję.

 

Odnośnik do komentarza
Udostępnij na innych stronach

43 minuty temu, coy_coyote napisał:

Wrzuciłem Twój kod tak na szybko do DEV C++ ale wyrzuca mi błąd " [Error] 'timegm' was not declared in this scope" pomimo że zaimportowałem dodatkowo <time.h>.

Przed chwila sprawdzilem, moj kod kompiluje sie poprzez g++ sideral.cpp

Nawet nie trzeba flag dla linkera.

Zwroc uwage na linijke

  sideral = sideral - (double)24 * (floor)(sideral / 24);

usuwam tu "pelne obroty nieba" i pozostawiam reszte. Brakuje tego w Twoim kodzie.

PS. Gdy pisze proste rzeczy nawet nie uruchamiam ich u siebie na komputerze. Wiele krotkich algorytmow testowalem na "kompilatorach online". Z drugiej strony specjalnie ich nie polecam, bo po zawieszeniu sie przegladarki (czasem nawet z ich powodu) tracilem swoja prace.

https://www.onlinegdb.com/online_c++_compiler

http://cpp.sh

PPS. DevC++ jest taki sobie. Code::Blocks jest lepszy, a i jego pokonuje Qt Creator czy Eclipse C++.

  • Lubię 1
Odnośnik do komentarza
Udostępnij na innych stronach

Ja korzystam z jeszcze innego algorytmu, trochę podobnego do tego, co przedstawił r.ziomber, gdyż też liczy się liczbę dni, która upłynęła od 1 stycznia 2000. Na wstępie trzeba znać tylko długość geograficzną (+ na wschód od południka 0, -  na zachód)  czas UT, czas urzędowy  i strefę czasową. A resztę się oblicza:

 

1. Najpierw wielkości a, b, c i d, gdzie d, to właśnie liczba dni od 1 stycznia 2000 (ja to mam napisane w skrypcie PHP):

			$c = (int)(($month + 9)/12);
			$a = (int)((7*($year + $c))/4);
			$b = (int)((275*$month)/9);

			$d = 367*$year - $a +$b + $day - 730530;

 

2. obliczanie elementów orbitalnych: w - długość peryhelium, M - anomalia średnia:

			$w = 282.9404 + 4.70935E-05*$d;
			$M = 356.0470 + 0.9856002585*$d;
			$M = $M - floor($M/360.0)*360.0;

 

3. Obliczenie średniej długości ekliptycznej Słońca L:

 

			$L = $w + $M - floor(($w + $M)/360.0)*360.0;

 

4. obliczenie czasu gwiazdowego na południku 0, o godz. 0:00 (obliczony, jako ułamek, można przeliczyć na godziny i minuty w razie potrzeby):

 

			$gmst = ($L + 180.0);
			$gmst = $gmst - floor($gmst/360.0)*360.0; 
			$gmst = $gmst/15.0;

 

5. Obliczanie czasu gwiazdowego na interesującej nas długości geograficznej:

 

			$timeoffset = $hour + $minutes/60.0;  // czas, który upłynął od północy czasu Greenwich

			$sidtime = $gmst + $timeoffset + $lon/15.0; // tutaj oczywiście lon, to długość geograficzna  w stopniach (jako ułamek)

 

Jeszcze trzeba się zabezpieczyć przed tym, aby godzina nie wyszła większa od 24 lub mniejsza od 0:

 

			if($sidtime < 0) $sidtime+=24;
			if($sidtime > 24) $sidtime-=24;

 

 

Przeliczyć to z ułamka na godziny, minuty i sekundy można np. tak:

 

			$sidtime_h = (int) $sidtime;  // godzina
			$sidtime_min = (($sidtime - floor($sidtime))*60);
			$sidtime_m = (int) (($sidtime - floor($sidtime))*60);	//minuty
			$sidtime_s = ($sidtime_min - floor($sidtime_min))*60;	//sekundy

//ewentualnie, jeśli wystarczy dokładność do całkowitej liczby sekund:
			$sidtime_s_int = (int)$sidtime_s;

 

 

 

Edytowane przez majer
literówka
  • Lubię 3
Odnośnik do komentarza
Udostępnij na innych stronach

50 minut temu, r.ziomber napisał:

usuwam tu "pelne obroty nieba" i pozostawiam reszte. Brakuje tego w Twoim kodzie.

tak Radek, właśnie się w to wgryzłem. Nie pomyślałem również o tym  :lol: Mnie chyba zabiło to że niepotrzebnie moja funkcja zwraca w wyniku format Data/Czas i ani data nie była prawidłowa ani czas. Dostawałem na wyjściu wynik -4713 rok lub podobny

P.S. Faktycznie mój kompilator nie poradził sobie natomiast on-line działa znakomicie. 

Dziękuję również koledze @majer na pewno przetestuję oba Wasze kody. Pozostaje mi wgryźć się jeszcze w ogólny algorytm co skąd się bierze bo nie chcę korzystać z gotowca 1:1

Aby teraz obliczyć pozycję gwiazdy Polarnej na osi godzinowej wystarczy obliczyć HA które będzie wynikiem odejomowania Ra gwiazdy i sideRealTime ?

Program wygląda na razie w taki sposób. Wiem że takich podobnych jest pewnie sporo ale nie będzie to program komercyjny. Na upiększanie przyjdzie pora :-)

 

Spoiler

5F674EBF-A0E3-4810-B3A6-B63BDE629C58.thumb.png.877e95cc4087da0f470a26f99f3f552f.png

 

Edytowane przez coy_coyote
dodane zdjęcie
  • Lubię 1
Odnośnik do komentarza
Udostępnij na innych stronach

Godzinę temu, coy_coyote napisał:

Pozostaje mi wgryźć się jeszcze w ogólny algorytm co skąd się bierze bo nie chcę korzystać z gotowca 1:1

 

Cały algorytm  jest opisany (z przykładami) np. tutaj: http://www2.arnes.si/~gljsentvid10/sidereal.htm

 

Godzinę temu, coy_coyote napisał:

Aby teraz obliczyć pozycję gwiazdy Polarnej na osi godzinowej wystarczy obliczyć HA które będzie wynikiem odejomowania Ra gwiazdy i sideRealTime ?

 

Raczej odwrotnie: od czasu gwiazdowego odejmuje się rektascensję.

  • Lubię 1
Odnośnik do komentarza
Udostępnij na innych stronach

kurcze, przeleciałem cały internet ale na ten opis nie trafiłem. Widocznie słabo szukałem :flirt:

2 minuty temu, majer napisał:

Raczej odwrotnie: od czasu gwiazdowego odejmuje się rektascensję.

Jak dalej będę takie bugi sadził to okaże się że za mnie ten program napisaliście. Dzięki @majer :Beer:

 

Odnośnik do komentarza
Udostępnij na innych stronach

Nie ma za co.

 

Dam jeszcze link do fajnego symulatora, gdzie można zobaczyć i przećwiczyć, co jest czym i jak położenie obserwatora na Ziemi wpływa na widoczność obiektu. Trochę przeszkadza, że pokazuje kąt ujemny, a raczej powinno być od 0 do 24 godzin, ale poza tym jest ok:

 

http://astro.unl.edu/classaction/animations/200level/siderealTimeAndHourAngleDemo.html

  • Lubię 2
Odnośnik do komentarza
Udostępnij na innych stronach

jestem na razie po pierwszych testach obu sposobów i przykład Radka trafiony jest w punkt - wszystkie kalkulatory pokazują zgodność czasu z tą funkcją, natomiast drugi algorytm proponowany przez @majer śpieszy o niecałą godzinę. Będę go jeszcze testował posiłkując się teorią z podlinkowanego sposobu. Proszę nie szukajcie przyczyny, muszę do tego dojść sam :flirt: Nie jestem pewnien na tą chwilę że ja coś nie sknociłem przy okazji stąd chcę poszukać gdzie jest bug i oczywiście się tym pochwalę. Dzisiaj może uda mi się wrzucić funkcję w program (na razie testy były w tzw.Play Background - środowisko do testowania kodu w Swift) i też pokażę jak działa szkielet programu.

Odnośnik do komentarza
Udostępnij na innych stronach

30 minut temu, coy_coyote napisał:

wszystkie kalkulatory pokazują zgodność czasu z tą funkcją, natomiast drugi algorytm proponowany przez @majer śpieszy o niecałą godzinę. Będę go jeszcze testował posiłkując się teorią z podlinkowanego sposobu. Proszę nie szukajcie przyczyny, muszę do tego dojść sam :flirt:

Nie wolno zagladac Ci do ramki ponizej ;-)

Spoiler

Czas UTC+1h? Specjalnie uzylem funkcji timegm(), by liczyc czas w UTC.

 

Edytowane przez r.ziomber
  • Lubię 1
Odnośnik do komentarza
Udostępnij na innych stronach

  • 1 miesiąc temu...

Ostatnio z braku czasu nie miałem kiedy pobawić się programem, ale wczoraj siadłem do niego i coś mi się nie zgadza. Obliczenie HA GP mija mi się z wyliczeniami o około 11.65 godziny licząc tak na szybko. Robię obliczenia w taki sposób:

raGP = 2h31m50s czyli:

raGP = 2+(31/60)+(50/3600)

HA = sideRealTime(since, 19.06) - raGP

Sidereal time odblicza super, niezależnie który algorytm użyję jednak HA gwiazdy Polarnej wychodzi inna niż oczekiwana. Czy powinienem uwzględnić w algorytnie nutację i refrakcję ewentualnie ? Jak myślicie ?

Odnośnik do komentarza
Udostępnij na innych stronach

  • 5 miesięcy temu...
7 godzin temu, r.ziomber napisał:

Znalazlem swietna ksiazke.

Duffett-Smith, Peter; Zwart, Jonathan; Duffett-Smith, Peter. Practical astronomy with your calculator

https://archive.org/details/Practical_Astronomy_with_your_Calculator_or_Spreadsheet_4th_edition_by_Peter_Duf

Wow, ależ to dobroć jest. Zapisałem ją sobie i przerobię całą w pythonie, albo w swifcie, bo właśnie się go uczę. 

  • Lubię 1
Odnośnik do komentarza
Udostępnij na innych stronach

57 minut temu, szuu napisał:

Wim... ale książka jest fajna, bo buduje kontekst krok po kroku. Dla takiego ignoranta jak ja, to dobrze :P Trochę astronomii się człowiek nauczy i pewnie coś dodatkowo zrozumie. Biblioteki są dobre do używania, ale niekoniecznie do nauki.

Odnośnik do komentarza
Udostępnij na innych stronach

11 minut temu, szuu napisał:

ano racja. fascynujące że ktoś to naprawdę wklepywał do excela i robił skriny. tego nie zastąpi nawet najlepsza gotowa biblioteka :D

Przyznaję - lekko irracjonalne. Z drugiej zaś strony, nie widziałem lepszego materiału do nauki metod numerycznych w astronomii (podstawy, topografia, etc.).

Odnośnik do komentarza
Udostępnij na innych stronach

Dołącz do dyskusji

Możesz dodać zawartość już teraz a zarejestrować się później. Jeśli posiadasz już konto, zaloguj się aby dodać zawartość za jego pomocą.

Gość
Dodaj odpowiedź do tematu...

×   Wklejono zawartość z formatowaniem.   Usuń formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Odnośnik został automatycznie osadzony.   Przywróć wyświetlanie jako odnośnik

×   Przywrócono poprzednią zawartość.   Wyczyść edytor

×   Nie możesz bezpośrednio wkleić grafiki. Dodaj lub załącz grafiki z adresu URL.

×
×
  • Dodaj nową pozycję...

Powiadomienie o plikach cookie

Umieściliśmy na Twoim urządzeniu pliki cookie, aby pomóc Ci usprawnić przeglądanie strony. Możesz dostosować ustawienia plików cookie, w przeciwnym wypadku zakładamy, że wyrażasz na to zgodę.