Может ли солнечная система быть точно представлена ​​в трехмерном пространстве, используя двойные (или длинные)?

15

Я хотел бы знать, как наилучшим образом управлять координатами в трехмерной игре, цель которой состоит в том, чтобы реалистично моделировать всю солнечную систему, и при этом иметь возможность обрабатывать наименьшие движения на «корабле» (то есть: возможно, мы можем считать 1 см самым маленьким приемлемое движение для кадра). Поддерживают ли это 64-битные двойные (или 64-битные), или мы сталкиваемся с проблемами переполнения? Если нет, то следует ли использовать длинные или двойные или, если да, то какой альтернативный подход, по вашему мнению, является наиболее подходящим для моделирования позиций в солнечной системе в трехмерной игре? (то есть: только удержание части системы на дисплее за раз, основанное на расстоянии до корабля, или представление системы каким-либо другим образом в другом координатном пространстве и т. д.)

Николас Хилл
источник
На какой язык вы ориентируетесь: C / C ++? Джава? Что-то другое?
Лоран Кувиду
4
@lorancou: не имеет значения, он явно указал размер long.
DeadMG
@DeadMG, который может быть 32-битным в C / C ++. 64-разрядный - это больше long long. Но да, как угодно, называй это придиркой, если хочешь.
Лоран Кувиду
Просто используйте BigInteger. У большинства языков есть какой-то вариант - целочисленное значение неограниченного размера (используется O (log (n)))
ashes999
Это может быть ответом, если игра не слишком сложна для вычислений.
Лоран Кувиду

Ответы:

11

Уже есть хороший ответ о целых числах, но я чувствую, что плавающие точки не должны быть устранены. В своем ответе Byte56 выбрал максимальную орбиту Плутона, возможно, взятую из этого листа Excel , поэтому я буду придерживаться этого.

Это ставит границы солнечной системы на:

7 376 000 000 км = 7,376x10 ^ 9 км = 7,376x10 ^ 14 см ≈ 7,4x10 ^ 14 см

Формат Double-Precision с плавающей точкой предлагает максимальную точность 15 значащих десятичных знаков. Так что вам повезло: если ваш источник находится в центре Солнца, и вы используете положение вокруг Плутона, вы можете представить все сантиметры, например, в C ++:

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

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

Так что если вы можете ограничить свою игру орбитой Плутона, то поздравляю! У вас достаточно точности с двойными числами, чтобы представить это.

Остерегайтесь , однако, что это достаточно , чтобы представить его в симуляции , но не ждите , чтобы оказывать это безболезненно. Вам придется конвертировать в 32-битные числа с плавающей точкой, возможно, изменить свое происхождение, чтобы получить достаточную точность при закрытии объектов, и вам, вероятно, придется полагаться на некоторый трюк с Z-буфером и усечением камеры, чтобы все это отображалось правильно ,

Теперь, если вы хотите, чтобы ваши астронавты посещали какие-то дальние кометы в облаке Оорта , которое намного больше, тогда все кончено. Примерно через 10 ^ 16 см вы начинаете терять точность:

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

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

И, конечно, в дальнейшем все ухудшается.

Так что если вы в этом случае, вы можете попробовать некоторые более продвинутые решения. Я предлагаю вам взглянуть на статью Питера Фриза в Game Programming Gems 4: «2.3. Решение проблем точности в больших мировых координатах». IIRC, он предлагает систему, которая может удовлетворить ваши потребности, это действительно несколько разных координатных пространств.

Это всего лишь несколько советов, вам, вероятно, придется использовать какой-то собственный рецепт, чтобы запустить его. Кто-то, кто уже реализовал такие вещи, может помочь вам больше. Почему бы, например, не отправить электронное письмо ребятам из космической программы Kerbal ?

Удачи в вашей игре!

Лоран Кувиду
источник
1
Этот ответ хорош, потому что он более легко отображается в трехмерное пространство с плавающей точкой, используемое подобными OpenGL и DirectX, и имеет хорошие ссылки. Поэтому я пометил это как ответ :)
Николас Хилл
Круто :) В качестве бонуса, поскольку все это очень приблизительно, вы найдете более подробную информацию о поплавках в блоге Брюса Доусона: randomascii.wordpress.com/2012/05/20/… .
Лоран Кувиду
17

Предположим, Плутон является «краем» солнечной системы (хотя некоторые говорят, что до 3 световых лет). Плутон на своей максимальной орбите находится на расстоянии 7 376 000 000 километров от Солнца. Это 7,37600 × 10 ^ 14 сантиметров. Удвойте это, чтобы получить диаметр, и вы получите 1 475 200 000 000 000 сантиметров. Это хорошо в пределах максимального размера 64-битной длины. Поскольку высота солнечной системы незначительна по сравнению с ее диаметром, мы можем это игнорировать.

Так что да, вы могли бы использовать long, чтобы представить свою позицию в Солнечной системе. На самом деле, вы можете иметь позиции до 9,75 световых лет с длинным знаком (двойным для без знака).

Обратите внимание, что это не относится к поиску расстояний. Максимальное расстояние, которое вы можете найти, является квадратным корнем максимального расстояния, на которое вы можете проехать. Это может быть преодолено с помощью системы уровня детализации для определения расстояний. Вы можете сделать несколько простых проверок, чтобы угадать, как далеко находятся расстояния (сравнить их значения x и y), а затем использовать шаг в 1 000 000 километров для больших расстояний до сантиметровых шагов для малых расстояний.

Конечно, есть вопрос, вы действительно хотите? 99,999% солнечной системы - совершенно неинтересное пустое пространство. Если вы точно представляете Солнечную систему, я надеюсь, что вы не совсем точно представляете физику. Обход Солнечной системы занимает много времени. Слишком долго для большинства людей оставаться заинтересованными.

И почему даже такая высокая точность, если вы не собираетесь моделировать объекты в солнечной системе с такой точностью? Вот где вы попадете в беду. Объем Солнца составляет 1.40900 × 10 ^ 18 кубических километров. В масштабе кубического сантиметра использование одного бита для представления о том, что это пространство «занято», занимает 1,4 × 10 ^ 33 бит или 1,6 × 10 ^ 23 гигабайт. Я думаю, что у вас не так много оперативной памяти.

MichaelHouse
источник
3
Хорошее место на. Короткая версия: Точность поплавка - наименьшее из ваших беспокойств.
аааааааааааа
1
Вы будете получать переполняется с целыми числами, даже 64-бит. Космический корабль вращается вокруг Плутона. Пытается вычислить расстояние от космического корабля до Солнца. Возводя. Boom.
Лоран Кувиду
3
Я категорически не согласен с утверждением в последнем абзаце - вопрос ОП имеет смысл в том виде, в каком он есть, и не нужно ожидать, что на самом деле будут предметы в каждом (кубическом) сантиметре, чтобы заботиться о точности 1 см на позициях.
Стивен Стадницки
1
@ StevenStadnicki Справедливо, но даже в масштабе километра это все еще 164 029 188 гигабайт на 1 бит на кубический километр. Это похоже на атомную точность в спидометре вашего автомобиля. Это гораздо точнее, чем нужно.
MichaelHouse
1
Ну, переход на шкалу AU или светового года слишком неточен. Так как мы говорим о солнечной системе. Световые годы или парсеки были бы лучше для чего-то большего, такого как большая туманность.
MichaelHouse
2

Вы можете использовать BigIntegerлюбой язык программирования. Это целое число неограниченного размера; он хорошо масштабируется - обычно использует log(n)хранилище для целого размера n.

У Java и C # есть это; Я уверен, что другие языки делают. Если нет, вы можете декомпилировать и переопределить его без особых затруднений.

ashes999
источник