Численная аппроксимация планетарной орбиты

2

Новый день, новая проблема...

Я сделал это так, как сказал Эрик, и создал метод ускорения!

Это выглядит так:

static Vector2 AccelerationOfTheMoon(Vector2 position)
    {
        double Mm = 7.349 * Math.Pow(10, 22);

        double MagnitudeOfForce()
        {
            double MagF = position.LengthSquared();
            return MagF;
        }

        Vector2 ForceAsVector()
        {
            return position.NegativeUnitVector() * MagnitudeOfForce();
        }

        Vector2 acceleration = ForceAsVector() / Mm;


    }

На мой взгляд, мой метод, который называется AccelerationOfTheMoon, получает вектор 2 с позицией. Теперь я хочу работать с этим вектором, поэтому я создал другой метод, который должен возвращать мою величину в виде скаляра (двойного). Для этого я создал метод для вычисления величины вектора и возведения его в квадрат. Когда я вызываю свой MagnitudeOfForce-Method внутри моего ForceAsVector-Method, я пытаюсь умножить отрицательный единичный вектор на скаляр и вернуть его как Vector2.

Может быть, мне ужасно плохо, но я изо всех сил пытаюсь понять все, что сделал Эрик, и все еще нуждаюсь в вашей помощи!

Благодарю.

  • 2
    Я совсем не понимаю ваш алгоритм; относительные положения и скорости Луны являются векторами в 3-пространстве; у вас есть земля и луна по прямой линии. Можете ли вы объяснить свой алгоритм более подробно?
  • 1
    гравитация, ускорение ... все они должны быть вектором, но то, что вы пишете, это скаляры, даже местоположение это скаляр !! Как вы могли получить эллипс в линии?
Показать ещё 9 комментариев
Теги:
vector
numerical-methods
newtons-method
orbital-mechanics

2 ответа

11
Лучший ответ

Вы допустили две очевидные ошибки и неудачный выбор алгоритма.

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

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

В-третьих, ваша реализация алгоритма Эйлера кажется правильной, но Эйлер - плохой выбор для численного решения орбитальных задач, потому что он не является консервативным; Вы можете легко попасть в ситуации, когда Луна набирает или теряет немного импульса, и это складывает и разрушает вашу красивую эллиптическую орбиту.

Поскольку орбита Луны гамильтонова, используйте симплектический алгоритм; это разработано, чтобы моделировать консервативные системы.

https://en.wikipedia.org/wiki/Symplectic_integrator

Этот подход, а также ваш эйлеровский подход, в основном направлены на поиск векторов состояний:

https://en.wikipedia.org/wiki/Orbital_state_vectors

Однако для вашей простой системы из двух тел существуют более простые методы. Если вы хотите сделать симуляцию, подобную космической программе Kerbal, в которой только ваша орбита влияет на вашу орбиту, а планеты с несколькими лунами "на рельсах", вам не нужно моделировать систему на каждую единицу времени разработать последовательность векторов состояний; Вы можете вычислить их непосредственно, учитывая кеплеровские элементы:

https://en.wikipedia.org/wiki/Orbital_elements

Мы знаем шесть элементов Луны с высокой степенью точности; из них вы можете вычислить положение в 3-пространстве Луны в любое время, опять же, предполагая, что ничто не мешает его орбите. (В действительности, лунная орбита изменяется солнцем, фактом, что земля не сфера, потоками, и так далее.)


ОБНОВИТЬ:

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

Вы спросили, как сделать эту работу в двух измерениях; это кажется неправильным, но что угодно, делайте то, что говорит курсовая работа.

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

struct Vector2
{
    double X { get; }
    double Y { get; }
    public Vector2(double x, double y)
    {
        this.X = x;
        this.Y = y;
    }

Обратите внимание, что векторы неизменны, как и числа. Вы никогда не мутируете вектор. Когда вам нужен новый вектор, вы создаете новый.

Какие операции нам нужно выполнить с векторами? Сложение векторов, скалярное умножение и скалярное деление - просто причудливое умножение. Позвольте реализовать те:

    public static Vector2 operator +(Vector2 a, Vector2 b) => 
      new Vector2(a.X + b.X, a.Y + b.Y);
    public static Vector2 operator -(Vector2 a, Vector2 b) => 
      new Vector2(a.X - b.X, a.Y - b.Y);
    public static Vector2 operator *(Vector2 a, double b) => 
      new Vector2(a.X * b, a.Y * b);
    public static Vector2 operator /(Vector2 a, double b) => 
      a * (1.0 / b);

Мы можем сделать умножение и в другом порядке, поэтому давайте реализуем это:

    public static Vector2 operator *(double b, Vector2 a) => 
      a * b;

Сделать вектор отрицательным - это то же самое, что умножить его на -1:

    public static Vector2 operator -(Vector2 a) => a * -1.0;

И чтобы помочь нам отладить:

    public override string ToString() => $"({this.X},{this.Y})";

}

И мы закончили с векторами.

Мы пытаемся смоделировать эволюцию параметров орбитального состояния, поэтому снова сделаем тип. Каковы параметры состояния? Положение и скорость:

struct State
{
    Vector2 Position { get; }
    Vector2 Velocity { get; }
    public State(Vector2 position, Vector2 velocity)
    {
        this.Position = position;
        this.Velocity = velocity;
    }

Теперь перейдем к основному алгоритму. Что у нас есть? состояние и ускорение. Что мы хотим? Новое государство. Сделай метод:

    public State Euler(Vector2 acceleration, double step)
    {
        Vector2 newVelocity = this.Velocity + acceleration * step;
        Vector2 newPosition = this.Position + this.Velocity * step;
        return new State(newPosition, newVelocity);
    }
}

Супер. Что осталось? Нам нужно отработать ускорение. Сделай метод:

static Vector2 AccelerationOfTheMoon(Vector2 position) 
{
  // You do this. Acceleration is force divided by mass,
  // force is a vector, mass is a scalar. What is the force
  // given the position? DO NOT MAKE A SIGN MISTAKE AGAIN.
}

И теперь у вас есть все необходимые детали. Начиная с исходного состояния, вы можете повторно вызывать AccelerationOfTheMoon, чтобы получить новое ускорение, а затем вызывать Euler, чтобы получить новое состояние, и повторить.

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

Подумайте, как бы вы расширили эту программу, используя эти методы; мы создали жестко запрограммированный метод AccelerationOfTheMoon, но что, если мы хотим вычислить ускорения нескольких тел? Опять же, создайте тип для представления Body; тело характеризуется State и массой. Что, если мы хотим решить проблему n-тела? Наше вычисление ускорения должно было бы принять другие тела в качестве параметра. И так далее.

  • 0
    Хорошо, этот действительно помог! Я пытался сделать это с 2D-векторами, но я действительно не знаю, как работать с векторами в C #! Если бы вы могли показать мне, я был бы очень признателен. Кроме того, я ДОЛЖЕН работать с приближением Эйлера. Я мог бы просто повысить точность, используя метод RungeKutta, с которым у меня нет опыта! Единственные две формулы, которые мне разрешено использовать, - это Закон Ньютона, а также 2-й Закон Ньютона! Поэтому я думаю, что ссылки, которые вы предложили, слишком сложны для моей симуляции, но они очень ценятся!
  • 1
    @HannesHauser: это для назначения? Ты должен был так сказать. Хорошо получить помощь с вашими заданиями, но я потратил впустую время, пытаясь помочь решить проблему, которой у вас нет. Кроме того, я не понимаю, почему вы решили проблему с 2-мерными векторами; Луна существует в трехмерном пространстве.
Показать ещё 39 комментариев
0

Если бы кто-то мог помочь, это было бы очень признательно.

Я сделал это так, как сказал Эрик, но борюсь с методом AcclerationOfTheMoon.

Я хотел бы вычислить величину Силы Гравитации, умножить ее на Единицу-Вектор Положения, чтобы получить Силу Гравитации в качестве вектора для моего начального состояния.

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню