O sistema solar pode ser representado com precisão no espaço 3D usando duplos (ou longos)?

15

Eu gostaria de saber como gerenciar melhor as coordenadas em um jogo em 3D cujo objetivo é modelar realisticamente todo o sistema solar, mas ser capaz de lidar com os menores movimentos de uma "nave" (ou seja: talvez possamos considerar 1 cm o menor movimento aceitável para um quadro). Dobros de 64 bits (ou longos de 64 bits) suportam isso ou encontramos problemas de estouro? Caso contrário, devem ser utilizados longos ou duplos, ou, em caso afirmativo, qual abordagem alternativa você acha que é mais sensata para modelar posições no sistema solar em um jogo em 3D? (ou seja: mantendo apenas um pouco do sistema no visor por vez, com base na distância de envio, ou tendo o sistema de alguma forma representado em um espaço coordenado diferente, etc.)

Nicholas Hill
fonte
Qual idioma você está segmentando: C / C ++? Java? Algo mais?
Laurent Couvidou
4
@lorancou: Irrelevante, ele especificou explicitamente o tamanho de long.
DeadMG
@DeadMG Que pode ser de 32 bits em C / C ++. 64 bits é mais de um long long. Mas sim, seja como for, chame isso de nitpicking, se quiser.
Laurent Couvidou
Basta usar o BigInteger. A maioria das línguas têm alguma variante dela - um valor inteiro tamanho ilimitado (o uso é O (log (n)))
ashes999
Isso pode ser uma resposta, desde que o jogo não seja muito pesado em computação.
Laurent Couvidou

Respostas:

11

Já existe uma boa resposta sobre números inteiros, mas acho que os pontos flutuantes não devem ser eliminados. Em sua resposta, Byte56 optou pela órbita máxima de Plutão, provavelmente extraída desta planilha de excel , então vou manter isso.

Isso coloca os limites do sistema solar em:

Qual a fórmula para converter de centímetros para centímetros?

O formato de ponto flutuante de precisão dupla oferece uma precisão máxima de 15 casas decimais significativas. Então, você tem sorte: se sua origem está no centro do Sol e você usa uma posição em torno de Plutão, você pode representar todos os centímetros, por exemplo, em C ++:

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

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

Então, se você pode limitar seu jogo à órbita de Plutão, parabéns! Você tem precisão suficiente com dobras para representá-lo.

Cuidado, porém, é o suficiente para representá-lo em uma simulação , mas não espere render isso sem esforço. Você terá que converter para carros alegóricos de 32 bits, talvez alterar sua origem para obter precisão suficiente nos objetos próximos, e provavelmente precisará contar com alguns truques de buffer Z e frustum da câmera para obter tudo isso para renderizar corretamente .

Agora, se você quiser que seus astronautas visitem alguns cometas distantes na nuvem de Oort , que é bem maior, então acabou. Cerca de 10 ^ 16 cm, você começa a perder a precisão:

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

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

E piora ainda mais, é claro.

Portanto, se você estiver nesse caso, convém tentar algumas soluções mais avançadas. Sugiro que você dê uma olhada no artigo de Peter Freeze em Game Programming Gems 4: "2.3 Resolvendo problemas de precisão nas grandes coordenadas mundiais". Segundo o IIRC, ele sugere um sistema que atenda às suas necessidades, é de fato algum tipo de vários espaços coordenados diferentes.

Essas são apenas algumas dicas, você provavelmente terá que usar uma receita sua para fazer isso funcionar. Alguém que já implementou esse tipo de coisa pode ajudá-lo mais. Por que não enviar um email para os caras por trás do Kerbal Space Program, por exemplo?

Boa sorte com seu jogo!

Laurent Couvidou
fonte
11
Essa resposta é boa porque é mais fácil mapear no espaço de ponto flutuante 3D usado por pessoas como OpenGL e DirectX e tem boas referências. Portanto, eu tenho marcado como a resposta :)
Nicholas Colina
Legal :) Como um bônus, como tudo isso é muito aproximado, você encontrará informações mais detalhadas sobre carros alegóricos no blog de Bruce Dawson: randomascii.wordpress.com/2012/05/20/… .
Laurent Couvidou
17

Supondo que Plutão seja o "limite" do sistema solar (embora alguns digam que é até 3 anos-luz). Plutão, em sua órbita máxima, fica a 7.376 milhões de quilômetros do sol. Isso é 7.37600 × 10 ^ 14 centímetros. Dobre isso para obter o diâmetro e você terá 1.475.200.000.000.000.000 de centímetros. Isso está dentro do tamanho máximo de 64 bits. Como a altura do sistema solar é insignificante em comparação ao seu diâmetro, podemos ignorá-lo.

Então, sim, você poderia usar um longo para representar sua posição no sistema solar. De fato, você pode ter posições até 9,75 anos-luz com um longo contrato (o dobro para não assinado).

Observe que este não é o caso para encontrar distâncias. A distância máxima que você pode encontrar é a raiz quadrada da distância máxima para a qual você pode viajar. Isso pode ser superado usando um sistema de nível de detalhe para encontrar distâncias. Você pode fazer algumas verificações simples para adivinhar a que distância estão as distâncias (compare seus valores xey) e use incrementos de 1.000.000 quilômetros para grandes distâncias, até incrementos de centímetros para pequenas distâncias.

Claro que há a questão de, você realmente quer? 99,999% do sistema solar é um espaço vazio totalmente desinteressante. Se você está representando com precisão o sistema solar, espero que não esteja representando com precisão a física. Demora muito tempo para contornar o sistema solar. Tempo demais para a maioria das pessoas continuar interessada.

E por que ter uma precisão tão fina, a menos que você também modele os objetos no sistema solar com essa precisão? É aí que você terá problemas. O volume do sol é 1.40900 × 10 ^ 18 quilômetros cúbicos. Na escala de centímetros cúbicos, o uso de um único bit para representar que esse espaço está "ocupado" ocupa 1,4 × 10 ^ 33 bits ou 1,6 × 10 ^ 23 gigabytes. Eu acho que você não tem tanta memória RAM.

MichaelHouse
fonte
3
Belo local. Versão curta: A precisão do flutuador é a menor das suas preocupações.
Aaaaaaaaaaaa
11
Você vai obter transborda com inteiros, mesmo 64-bit. Nave espacial orbita em torno de Plutão. Tenta calcular a distância da nave espacial ao sol. Quadratura. Estrondo.
Laurent Couvidou
3
Discordo totalmente da afirmação do último parágrafo - a pergunta do OP faz todo o sentido, e não é necessário esperar ter itens em cada centímetro (cúbico) para se preocupar com uma precisão de 1 cm nas posições.
Steven Stadnicki
11
@StevenStadnicki É justo, mas mesmo na escala de quilômetros, ainda é 164.029.188 gigabytes por 1 bit por quilômetro cúbico. É como pedir precisão atômica no velocímetro do seu carro. Isso é muito mais preciso do que precisa ser.
MichaelHouse
11
Bem, ir para a UA ou a escala do ano-luz é muito impreciso. Já que estamos falando do sistema solar. Anos-luz ou parsecs seriam melhores para algo maior, como uma nebulosa grande.
MichaelHouse
2

Você pode usar o BigIntegerque a sua linguagem de programação chamar. É um número inteiro de tamanho ilimitado; ele é bem dimensionado - geralmente usando log(n)armazenamento para um número inteiro de tamanho n.

Java e C # possuem; Tenho certeza que outras línguas fazem. Caso contrário, você pode descompilar e reimplementá-lo sem muita dificuldade.

ashes999
fonte