Найти тему

Орбитальна механика. Реализация на языке C#

Не так давно я загорелся идеей сделать свой космический симулятор. И первая задача, которую надо было решить это орбитальная механика. Т.е. траектории полёта небесных тел и космических кораблей.
После не продолжительного ознакомления с законами Кеплера я понял, что это задача не из простых. И как настоящий программист я начал искать готовое решение.

Я нашел вот такое бесплатное решение:
https://github.com/Karth42/SimpleKeplerOrbits

Плагин SimpleKeplerOrbits уже адаптирован под движок Unity в котором я работаю, но я оставил для себя только компоненты реализованные на чистом C# без готовой обвязки для движка.

Плагин выполняет очень простую функцию. Он формирует орбитальные параметры исходя из заданных значений - например массы планеты, позиции спутника и его текущей скорости. Конструктор орбиты выглядит так:

KeplerOrbitData ( Vector3d position, Vector3d velocity, double attractorMass, double gConst)

Есть метод UpdateOrbitDataByTime который позволяет обновить позицию объекта по заданному времени. И метод GetOrbitPoints который выдаёт точки траектории орбиты с заданной точностью.
Собственно всё. Этого уже достаточно.
Плагин очень маленький особенно если выкинуть все обвязки к движку, код полностью открытый.

Если вы хотите создать что-то подобное, то я бы посоветовал обратить внимание на это решение. Оно бесплатно, и сэкономит вам кучу времени.

Для своих нужд я написал вот такой екстеншен. Он позволяет конвертировать координаты из формата Unity в формат плагина и обратно с заданным масштабом:

public static class Vector3dExtensions
{
public static Vector3d ToVector3d(this Vector3 v) =>
new Vector3d (v.x , v.y , v.z );

public static Vector3d ToVector3d(this Vector3 v, double scale) =>
(new Vector3d (v.x , v.y , v.z )) * scale;

public static Vector3 ToVector3(this Vector3d v) =>
new Vector3 ((float ) v.x , (float ) v.y , (float ) v.z );

public static Vector3 ToVector3(this Vector3d v, double scale) =>
new Vector3 ((float ) (v.x / scale), (float ) (v.y / scale), (float ) (v.z / scale));

public static string ToVelocity(this Vector3d v) =>
$ "{ (int ) v.magnitude }m/s" ;
}


Прототип игры которую я делал вы можете скачать под Android здесь:
APK-Android

Если у вас есть вопросы, я с радостью отвечу.