Czy układ słoneczny może być dokładnie odwzorowany w przestrzeni 3D za pomocą podwójnych (lub długich)?

15

Chciałbym wiedzieć, jak najlepiej zarządzać współrzędnymi w grze 3D, której celem jest realistyczne modelowanie całego układu słonecznego, a jednocześnie być w stanie poradzić sobie z najmniejszymi ruchami na „statku” (tj. Być może możemy uznać, że 1 cm jest najmniejszy dopuszczalny ruch ramy). Czy 64-bitowe podwójne (lub 64-bitowe długie) to obsługują, czy też występują problemy z przepełnieniem? Jeśli nie, to czy należy zastosować długi lub podwójny, a jeśli tak, to jakie alternatywne podejście według ciebie jest najbardziej odpowiednie do modelowania pozycji w Układzie Słonecznym w grze 3D? (tj .: trzymanie tylko części systemu na wyświetlaczu w czasie zależnym od odległości do statku lub posiadanie systemu w jakiś sposób reprezentowanej w innej przestrzeni współrzędnych itp.)

Nicholas Hill
źródło
W jakim języku celujesz: C / C ++? Jawa? Coś innego?
Laurent Couvidou
4
@lorancou: Bez znaczenia, wyraźnie określił rozmiar long.
DeadMG
@DeadMG Który może być 32-bitowy w C / C ++. 64-bit to więcej long long. Ale tak, cokolwiek, nazwij to dręczeniem, jeśli chcesz.
Laurent Couvidou
Wystarczy użyć BigInteger. Większość języków ma jakiś wariant - wartość całkowitą o nieograniczonym rozmiarze (użycie to O (log (n)))
ashes999
To może być odpowiedź, pod warunkiem, że gra nie jest zbyt obciążająca.
Laurent Couvidou

Odpowiedzi:

11

Jest już dobra odpowiedź na temat liczb całkowitych, ale wydaje mi się, że zmiennoprzecinkowe nie powinny być eliminowane. W swojej odpowiedzi Byte56 wybrał maksymalną orbitę Plutona, prawdopodobnie pobraną z tego arkusza programu Excel , więc pozostanę przy tym.

To stawia granice Układu Słonecznego w:

7 376 000 000 km = 7,376x10 ^ 9 km = 7,376x10 ^ 14 cm ≈ 7,4x10 ^ 14 cm

Double oferty dokładnością maksymalnie 15 znaczących miejsc po przecinku. Więc masz szczęście: jeśli twoje pochodzenie znajduje się w centrum Słońca i używasz pozycji wokół Plutona, możesz reprezentować wszystkie centymetry, np. W C ++:

printf("%.0Lf\n", 7.4e14);
printf("%.0Lf\n", 7.4e14 + 1.0);
printf("%.0Lf\n", 7.4e14 + 2.0);

Output:
-------
740000000000000
740000000000001
740000000000002

Więc jeśli możesz ograniczyć grę do orbity Plutona, gratulacje! Masz wystarczającą precyzję z podwójnymi, aby to reprezentować.

Uważaj jednak, że to wystarczy do reprezentowania go w symulacji , ale nie należy się spodziewać, aby uczynić to bezboleśnie. Będziesz musiał przekonwertować na 32-bitowe zmiennoprzecinkowe, może zmienić pochodzenie, aby uzyskać wystarczającą precyzję na bliskich obiektach i prawdopodobnie będziesz musiał polegać na buforze Z i sztuczce aparatu, aby uzyskać to wszystko, aby poprawnie renderować .

Teraz, jeśli chcesz, aby astronauci odwiedzili odległe komety w chmurze Oort , która jest znacznie większa, to koniec. Około 10 ^ 16 cm zaczyna tracić dokładność:

printf("%.0Lf\n", 1.0e16);
printf("%.0Lf\n", 1.0e16 + 1.0);
printf("%.0Lf\n", 1.0e16 + 2.0);

Output:
-------
10000000000000000
10000000000000000 <-- oops
10000000000000002

I oczywiście dalej się pogarsza.

Jeśli tak jest, możesz wypróbować bardziej zaawansowane rozwiązania. Proponuję rzucić okiem na artykuł Petera Freeze'a w Gems Programming Game 4: „2.3 Rozwiązywanie problemów z dokładnością współrzędnych dużego świata”. IIRC, sugeruje system, który może pasować do twoich potrzeb, to rzeczywiście coś w rodzaju wielu różnych współrzędnych przestrzeni.

To tylko kilka wskazówek, prawdopodobnie będziesz musiał użyć własnego przepisu, aby uruchomić to. Ktoś, kto już zaimplementował tego rodzaju rzeczy, może ci pomóc. Dlaczego na przykład nie wysłać e-maila do facetów programu kosmicznego Kerbal ?

Powodzenia w grze!

Laurent Couvidou
źródło
1
Ta odpowiedź jest dobra, ponieważ łatwiej odwzorowuje trójwymiarową przestrzeń zmiennoprzecinkową używaną przez OpenGL i DirectX i ma dobre referencje. Dlatego zaznaczyłem to jako odpowiedź :)
Nicholas Hill
Fajnie :) Jako bonus, ponieważ jest to bardzo przybliżone, znajdziesz więcej szczegółowych informacji o pływakach na blogu Bruce'a Dawsona: randomascii.wordpress.com/2012/05/20/… .
Laurent Couvidou
17

Zakładając, że Pluton jest „krawędzią” Układu Słonecznego (choć niektórzy twierdzą, że jest on oddalony nawet o 3 lata świetlne). Pluton, na maksymalnej orbicie, znajduje się około 7 376 000 000 kilometrów od Słońca. To 7.37600 × 10 ^ 14 centymetrów. Podwój to, aby uzyskać średnicę, a otrzymasz 1 475 200 000 000 000 centymetrów. To mieści się w maksymalnym rozmiarze 64 bitów. Ponieważ wysokość Układu Słonecznego jest nieznaczna w porównaniu do jego średnicy, możemy to zignorować.

Więc tak, możesz użyć długiej, aby przedstawić swoją pozycję w Układzie Słonecznym. W rzeczywistości możesz mieć pozycje do 9,75 lat świetlnych z podpisaną długością (podwójna dla niepodpisanego).

Pamiętaj, że nie dotyczy to określania odległości. Maksymalna odległość, jaką możesz znaleźć, to pierwiastek kwadratowy maksymalnej odległości, którą możesz przebyć. Można temu zaradzić, stosując system szczegółowego określania odległości. Możesz wykonać kilka prostych sprawdzeń, aby odgadnąć, jak daleko są odległości (porównaj ich wartości xi wartości y), a następnie użyj przyrostów 1 000 000 km dla dużych odległości do przyrostów centymetrowych dla małych odległości.

Oczywiście jest pytanie, czy naprawdę chcesz? 99,999% Układu Słonecznego to zupełnie nieciekawa pusta przestrzeń. Jeśli dokładnie reprezentujesz Układ Słoneczny, mam nadzieję, że nie reprezentujesz dokładnie fizyki. Obejście Układu Słonecznego zajmuje dużo czasu. Zbyt długo, aby większość ludzi była zainteresowana.

A dlaczego nawet mieć tak dokładną dokładność, chyba że zamierzasz również modelować obiekty w Układzie Słonecznym z tą dokładnością? Tam wpadniesz w kłopoty. Objętość Słońca wynosi 1,40900 × 10 ^ 18 kilometrów sześciennych. W skali centymetra sześciennego użycie pojedynczego bitu, który oznacza, że ​​przestrzeń jest „zajęta”, zajmuje 1,4 × 10 ^ 33 bitów lub 1,6 × 10 ^ 23 gigabajtów. Myślę, że nie masz tyle pamięci RAM.

MichaelHouse
źródło
3
Niezłe miejsce na. Krótka wersja: Dokładność pływaka to najmniejszy problem.
aaaaaaaaaaaa
1
Państwo będzie dostać przepełnienia z liczb całkowitych, a nawet 64-bit. Statek kosmiczny krąży wokół Plutona. Próbuje obliczyć odległość od statku kosmicznego do słońca. Kwadrat Bum.
Laurent Couvidou
3
Zdecydowanie nie zgadzam się z twierdzeniem z ostatniego akapitu - pytanie OP ma jak najbardziej sensowny sens i nie trzeba oczekiwać, że faktycznie będą mieć przedmioty na każdym (sześciennym) centymetrze, aby dbać o dokładność 1 cm na pozycjach.
Steven Stadnicki
1
@StevenStadnicki Wystarczająco, ale nawet w skali kilometrowej jest to wciąż 164 029 188 gigabajtów za 1 bit na kilometr sześcienny. Jest to podobne do pytania o precyzję atomową w prędkościomierzu samochodowym. Jest to po prostu znacznie dokładniejsze, niż musi być.
MichaelHouse
1
Cóż, przejście do skali AU lub roku świetlnego jest zbyt nieprecyzyjne. Ponieważ mówimy o Układzie Słonecznym. Lata świetlne lub parseki byłyby lepsze dla czegoś większego, takiego jak duża mgławica.
MichaelHouse
2

Możesz używać BigInteger, jakkolwiek nazywa to Twój język programowania. Jest to liczba całkowita nieograniczona; dobrze się skaluje - ogólnie używając log(n)pamięci dla liczby całkowitej n.

Java i C # mają to; Jestem pewien, że robią to inne języki. Jeśli nie, możesz go dekompilować i ponownie wdrożyć bez nadmiernych trudności.

ashes999
źródło