Численное приближение планетарной орбиты

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

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

Выглядит это так:

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 внутри метода ForceAsVector, я пытаюсь умножить отрицательный единичный вектор на скаляр и вернуть его как Vector2.

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

Спасибо.


person Hannes Hauser    schedule 17.04.2019    source источник
comment
Я совершенно не понимаю ваш алгоритм; относительные положения и скорости Луны - векторы в 3-м пространстве; у вас есть земля и луна на прямой линии. Не могли бы вы объяснить свой алгоритм более подробно?   -  person Eric Lippert    schedule 17.04.2019
comment
гравитация, ускорение ... все они должны быть вектором, но то, что вы пишете - скаляры, даже местоположение - скаляр !! Как можно было нарисовать эллипс в линию?   -  person shingo    schedule 17.04.2019
comment
Кроме того, глядя на ваш код, кажется, что вы смоделировали гравитацию как силу отталкивания, а не как силу притяжения! Земля отталкивает луну в вашей системе; тормозить конечно не собираюсь.   -  person Eric Lippert    schedule 17.04.2019
comment
Что именно вы имеете в виду под увеличением отступа? Когда я редактирую код, он выглядит с отступом! Кроме того, я понимаю вашу путаницу со значениями как скалярами. Я хотел умножить их на тригонометрические функции, чтобы получить эллипс, но понятия не имею, как это сделать! Наконец, не могли бы вы более подробно объяснить, что вы имеете в виду под силой тяжести, действующей как отталкивающая сила? Как бы вы поменяли код! Заранее благодарим и приносим извинения за неудобства, я настоящий новичок в программировании!   -  person Hannes Hauser    schedule 17.04.2019
comment
Это может оказаться слишком сложной задачей для новичка. Орбитальная механика - не самый простой предмет для новичков! Но вы уже на правильном пути к моделированию пружинных сил; может попробовать это в первую очередь.   -  person Eric Lippert    schedule 17.04.2019
comment
У вас есть сила как положительное число, когда Луна находится перед Землей, но она должна быть направлена ​​к Земле. Когда положение положительное, знак должен быть отрицательным, и наоборот, когда положение отрицательное.   -  person Eric Lippert    schedule 17.04.2019
comment
Я не понимаю, что вы имеете в виду под умножением на триггерные функции.   -  person Eric Lippert    schedule 17.04.2019
comment
см. Можно ли сделать реалистичное моделирование солнечной системы с n телами с учетом размера и массы? и все дополнительные ссылки там ...   -  person Spektre    schedule 18.04.2019
comment
Если бы кто-то еще мог помочь, мы были бы очень признательны. Я сделал это так, как сказал Эрик, но я борюсь с методом AcclerationOfTheMoon. Я хотел бы вычислить величину гравитационной силы, умножить ее на единичный вектор положения, чтобы получить мою гравитационную силу в качестве вектора для моего начального состояния. Единственное, с чем я сейчас борюсь, - это синтаксис внутри этого метода, я не могу найти подходящий метод для вычисления моей величины и моего единичного вектора. Помощь очень ценится, а также объясняет все, что вы можете, я хочу узнать!   -  person Hannes Hauser    schedule 19.04.2019
comment
Мне нужно получить мою начальную позицию (которую я объявляю @ в цикле for) внутри моего метода AccelerationOfTheMoon, чтобы вычислить величину вектора положения. Это, вероятно, моя основная проблема, и какой лучший вариант объявить метод внутри другого метода, как в этом случае?   -  person Hannes Hauser    schedule 19.04.2019
comment
Отредактировал свой первый пост!   -  person Hannes Hauser    schedule 20.04.2019


Ответы (1)


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

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

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

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

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

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

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

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

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

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

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


ОБНОВИТЬ:

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

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

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

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, чтобы получить новое ускорение, а затем вызывать Эйлера, чтобы получить новое состояние, и повторять.

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

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

person Eric Lippert    schedule 17.04.2019
comment
Хорошо, это действительно помогло! Я пытался сделать это с 2D-векторами, но понятия не имею, как работать с векторами на C #! Если бы вы могли показать мне, я был бы очень признателен. Кроме того, я ДОЛЖЕН работать с приближением Эйлера. Я мог бы просто повысить точность, используя метод Рунге-Кутта, с которым у меня нет опыта! Единственные две формулы, которые мне разрешено использовать, - это закон тяготения Ньютона и 2-й закон движения Ньютона! Поэтому я думаю, что ссылки, которые вы предложили, слишком сложны для моего моделирования здесь, но мы очень признательны! - person Hannes Hauser; 17.04.2019
comment
@HannesHauser: Это для задания? Вы должны были так сказать. Получить помощь с заданиями - это нормально, но я зря потратил время, пытаясь помочь решить проблему, которой у вас нет. Кроме того, я не понимаю, зачем вам решать проблему с помощью двумерных векторов; Луна существует в трехмерном пространстве. - person Eric Lippert; 17.04.2019
comment
О, понятно, но когда я создавал этот вопрос, я уже сказал редактору StackOverflow, что мне это нужно для моей работы в UNI! Но в любом случае извините, что потратил ваше время, это определенно не то, что я хотел! Наш лектор сказал, что нам пришлось делать это в 2D, поскольку Луна и Земля почти идеально выровнены, что дает нам возможность выполнять все вычисления и визуализации в 2D. - person Hannes Hauser; 17.04.2019
comment
Луна не совсем совпадает с эклиптикой! Если бы это было так, то у нас было бы лунное затмение каждый месяц! - person Eric Lippert; 17.04.2019
comment
Мне очень жаль беспокоить вас этим, но нашей задачей было запрограммировать это в 2D, и я действительно не знаю ничего лучше, я абсолютный новичок в программировании, и моя область обучения полностью отличается от орбитальной механики! - person Hannes Hauser; 17.04.2019
comment
@HannesHauser: Я добавил несколько обновлений, чтобы показать, как моделировать 2d-векторы на C #. - person Eric Lippert; 17.04.2019
comment
Хорошо, здорово, спасибо за вашу работу! Я сделаю все, что в моих силах, но, поскольку нас никогда не учили работать с векторами, мне очень трудно с этим! Есть ли возможность сделать это с помощью cos и sin вместо векторов? Но я все равно попробую ваши советы! - person Hannes Hauser; 17.04.2019
comment
@HannesHauser: Да, вы можете решить это с помощью триггера, если вы представляете орбиты через их кеплеровские элементы; вы уже отклонили это предложение. - person Eric Lippert; 17.04.2019
comment
@HannesHauser: Векторы - это просто пара чисел вместо одного числа, потому что удобно складывать координаты в одно целое. Не пугайтесь причудливого имени; это просто способ концептуализировать значение, требующее двух чисел. - person Eric Lippert; 17.04.2019
comment
Я действительно благодарю вас за вашу помощь, хотя мы не научились работать ни с классами, ни с векторами, поэтому мне очень трудно понять это ... У меня так много вопросов о том, как это решить, например почему вы не использовали цикл for или что-то в этом роде с get; - оператор в скобках. Я не хочу тратить ваше время зря, но любая дополнительная помощь будет отличной! - person Hannes Hauser; 17.04.2019
comment
@HannesHauser: Вы пытаетесь бежать, прежде чем ползете. Изучите основы языка: типы, методы, свойства и т. Д., Прежде чем пытаться написать сложную программу! - person Eric Lippert; 17.04.2019
comment
@HannesHauser: {get;} означает, что это свойство можно читать, а не записывать, только после того, как оно изначально установлено. Вы никогда не захотите изменять значение координаты в векторе; если вы изменили координату, это другой вектор. {get; set;} означает, что его можно читать и писать. - person Eric Lippert; 17.04.2019
comment
@HannesHauser: Цикл for имеет форму for( initial state; ending condition; compute new state) do action. Какой начальный State? каково конечное условие? Как вы вычисляете новое состояние, учитывая старое состояние? Как только вы ответите на эти вопросы, вы будете знать, какой for цикл писать. - person Eric Lippert; 17.04.2019
comment
Проблема в том, что я из другой области образования, поэтому у меня большой недостаток по сравнению с моими однокурсниками, плюс у меня очень мало времени, чтобы завершить проект, но это уже другая тема. О цикле for: например. мое начальное состояние, вероятно, является вектором, указывающим на местоположение луны во время перицентра, а конечное условие достигается, когда она касается той же точки, верно? Если бы вы могли использовать некоторые из значений, которые я показал в начале, это действительно прояснило бы мне ситуацию! - person Hannes Hauser; 17.04.2019
comment
@HannesHauser: И снова гуляйте, прежде чем бежать. Можете ли вы реализовать метод, который определяет положение луны и вычисляет ускорение свободного падения? Начните с того, в каком направлении действует сила в зависимости от положения? - person Eric Lippert; 17.04.2019
comment
Я вычисляю ускорение, разделив гравитационную силу на массу Луны, я уже сделал это с помощью своего кода, но я просто не знаю, кому реализовать мои значения в вашем коде, чтобы начать работать с векторами ... - person Hannes Hauser; 17.04.2019
comment
@HannesHauser: Ну, разбери это. У вас есть State. Состояние содержит Position. Сила пропорциональна G * Me * Mm / (distance * distance). Вы знаете скаляры G, Me и Mm. Что такое distance как функция от Position? Эта величина называется величиной; как это вычислить? - person Eric Lippert; 17.04.2019
comment
Расстояние рассчитывается как r = sqrt ((G * me * мм) / F) - person Hannes Hauser; 17.04.2019
comment
Нет, это не так. У вас есть позиция. Позиция - это вектор. Вектор - это пара координат X, Y, которые являются смещением от центра Земли. Как вычислить расстояние до центра Земли по парам X, Y? - person Eric Lippert; 17.04.2019
comment
Я действительно не могу следить за тобой, извини. - person Hannes Hauser; 17.04.2019
comment
Нарисуйте схему, на которой изображены Земля и Луна. Земля находится в точке (0, 0). Луна находится в (X, Y). Какое расстояние между Землей и Луной на вашей диаграмме? - person Eric Lippert; 17.04.2019
comment
Я думаю, что эта проблема слишком сложна для вашего математического / физического образования; это не совсем хороший форум, чтобы пытаться преподавать базовую геометрию. Может быть, найдите репетитора или попросите помощи у своего профессора или помощника учителя. Орбитальная механика не подходит для начинающих, если вы еще не знаете, что такое векторы. - person Eric Lippert; 17.04.2019
comment
Я действительно знаю, что такое векторы, но я просто не понимаю ваших вопросов. Я вычисляю расстояние путем вычитания (x, y) - (0,0), которое возвращает (x, y), и для получения длины i возьмите квадратный корень из вектора (x / y) ^ 2, который равен √ (x ^ 2 + у ^ 2) - person Hannes Hauser; 17.04.2019
comment
Это правильно, поэтому теперь вы можете добавить в Vector2 метод с именем Magnitude, который возвращает величину вектора. Теперь вы можете определить величину гравитационной силы, возведя в квадрат величину вектора положения, но вам все равно нужно определить ее направление. Итак, новая проблема: учитывая положение Луны, можете ли вы вычислить вектор в направлении силы, величина которого равна 1.0? Помните, что направление силы должно быть к земле. - person Eric Lippert; 17.04.2019
comment
Как только вы это сделаете, у вас появятся две вещи; величина силы в виде скаляра и направление силы в виде единичного вектора. Их умножение дает силу в виде вектора, который затем можно разделить на массу Луны, чтобы получить ускорение в виде вектора. - person Eric Lippert; 17.04.2019
comment
Когда вы это сделаете, вы должны что-то заметить. Вы вычислили величину ускорения как (G * Mm * Me / (d * d)) / Mm) - почему вы умножили на Mm, а затем разделили? Ускорение свободного падения, вызванное землей на Луне, не зависит от массы Луны. Мы могли бы поместить объект любой массы на орбиту Луны, и орбита не изменилась бы; если бы мы заменили луну бейсбольным мячом, она все равно будет вращаться один раз в месяц. - person Eric Lippert; 17.04.2019
comment
Я вроде как разбираюсь в этом! Я завтра рассмотрю это более внимательно и доложу! Надеюсь, к тому времени вы еще ответите! Ты большой помощник эрик - person Hannes Hauser; 17.04.2019
comment
@HannesHauser: Пожалуйста, но я призываю вас найти в школе помощь по математике. Урок программирования, опять же, состоит в том, чтобы создать типы и методы для представления концепций и операций. Если вы это сделаете, ваша программа будет намного яснее, понятнее и правильнее. Я буду дома в гостях у семьи на Пасху и не буду сидеть за компьютерами до вторника, так что у меня не будет времени, чтобы комментировать дальше. Удачи! - person Eric Lippert; 17.04.2019
comment
Чтобы получить единичный вектор, мне нужно разделить вектор гравитации (x, y) на | (x.y) | который выбирается путем извлечения квадратного корня из (x ^ 2 + y ^ 2). Итак, я должен умножить это на величину (которая является скаляром). Мне нужно переключить мой окончательный вектор на отрицательное значение? - person Hannes Hauser; 17.04.2019
comment
Тем не менее, моя большая проблема - это реализация и вычисление векторов на C #! Если вы не возражаете, действительно внесение ценностей очень поможет. Кроме того, я попробую ваш совет по увеличению использования объектно-ориентированного программирования. - person Hannes Hauser; 17.04.2019
comment
Вам нужно сделать единичный вектор в направлении земли, которое является отрицательным по отношению к направлению вектора положения. Чтобы вычислить значения, снова нарисуйте диаграмму XY, показывающую Землю и Луну, и отметьте на диаграмме начальное положение и начальную скорость. Помните, что скорость должна быть касательной к орбите. - person Eric Lippert; 18.04.2019
comment
Начните с позиции: каково начальное положение Луны в координатах XY с центром на Земле? Вы выбираете систему координат, поэтому вам решать. - person Eric Lippert; 18.04.2019
comment
Хорошо, я в основном планировал, что Земля находится в начале декартовой системы координат с координатами (0,0). Луна начинается с перицентра с координатами (363300000,0). Итак, вы сказали, что скорость должна быть касательной к орбите, при этом мой начальный вектор скорости равен (0,1076). Итак, у меня есть два вектора состояния, с помощью которых я могу вычислить свой вектор ускорения, который указывает на землю и должен иметь начальные координаты (-0.003,0). Я надеюсь, что это правильно, поэтому я больше не беспокою вас! - person Hannes Hauser; 18.04.2019
comment
@HannesHauser: Теперь следующее, что нужно сделать, это собрать все это в цикл. Вы начинаете с начальных условий при t = 0, затем делаете шаг размером delta_t: вычисляете ускорение, затем вычисляете новые векторы состояния. Теперь у вас есть вектор состояния в момент времени delta_t. Пройдите цикл снова и сделайте шаг размером delta_t, вычислите ускорение, вычислите новый вектор состояния и повторите столько раз, сколько захотите. - person Eric Lippert; 18.04.2019
comment
@HannesHauser: Как только у вас появится это твердое тело, это станет для вас вызовом. Луна не вращается вокруг центра Земли. Скорее, Земля и Луна вращаются вокруг точки внутри Земли, удаленной от центра, называемого барицентром. Можете ли вы придумать, как модифицировать вашу систему, чтобы решить проблему двух тел? Открепите Землю от начала координат, и пусть ее положение и скорость зависят от гравитации Луны. - person Eric Lippert; 18.04.2019
comment
Итак, весь код, который вы написали выше, помещается в другой класс с другим именем в качестве моей основной программы, и они вызываются в моем основном классе через конструктор? И мои новые векторы затем помещаются в массив, верно? В конце концов, это кажется несложным, я просто терял надежду, сражаясь с этим почти неделю! - person Hannes Hauser; 18.04.2019
comment
Вы можете поместить векторы в массив, если хотите, или нет. Все, что вам нужно для расчета следующего, - это предыдущий, поэтому вам не обязательно нужны все из них. Вы можете поместить типы в другой файл, если хотите, или сохранить их в своем основном файле; Хорошей практикой было бы поместить их в свои собственные файлы, но это будет довольно короткая программа, поэтому, возможно, вы захотите все это в одном месте. Не забудьте указать производные работы, когда это необходимо; академическая честность - важная привычка. - person Eric Lippert; 18.04.2019
comment
Если я отключаю Землю, у меня есть два движущихся объекта, поэтому Земля также получает вектор скорости, ускорения и местоположения. Поскольку масса Земли примерно в 80 раз больше массы Луны, положение барицентра должно быть примерно 1/80 расстояния между Землей и Луной. Учитывая это, Земля также должна следовать по траектории эллипса, как и Луна. Возможно, барицентр находится на линии, которая соединяет оба сферических центра, которые содержат всю массу - теоретически. - person Hannes Hauser; 18.04.2019
comment
Вы имеете в виду, что я должен просто позволить компьютеру отображать каждое вычисленное значение в реальном времени в растровом изображении, чтобы на самом деле ни одно из них не сохранялось? Я свяжу stackoverflow как один из моих основных источников информации и буду рекомендовать дальше! - person Hannes Hauser; 18.04.2019
comment
@HannesHauser: Re: расположение барицентра, это почти точно. На самом деле дробь равна mm/(me+mm), поэтому, если отношение равно 80 к 1, дробь составляет 1/81 расстояния Земля-Луна. - person Eric Lippert; 18.04.2019