0

New day new Problem...

I did it the way Eric said and I created a method for the Acceleration!

It looks like this:

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;


    }

The way i see it, my method which is called AccelerationOfTheMoon receives a Vector 2 with the position. Now i want to work with this vector so i created another Method which should return my Magnitude as a scalar(double). For this I created a Method to calculate the Magnitude of a Vector and squares it. When i call my MagnitudeOfForce-Method inside my ForceAsVector-Method I'm trying to multiply a negative unit vector with a scalar and return it as a Vector2.

Maybe I'm doing horrificly bad here, but I'm trying hard to understand everything Eric did and still need some of your help!

Thanks.

  • 2
    I don't understand your algorithm at all; the relative positions and velocities of the moon are vectors in 3-space; you have the earth and the moon in a straight line. Can you explain your algorithm in more detail? – Eric Lippert Apr 17 '19 at 13:17
  • 1
    gravity, acceleration... all of them should be a vector, but what you write are scalars, even the location is a scalar!! How could you get a ellipse in a line? – shingo Apr 17 '19 at 13:22
  • 1
    Also, looking at your code, it appears that you've modeled gravity as a repelling force, not an attracting force! The earth is pushing the moon away in your system; of course it is not going to slow down. – Eric Lippert Apr 17 '19 at 13:24
  • What do you mean exactly by increasing the indent? When I'm editing the code it appears as indented! Furthermore i understand your confusion with the values being as scalars. I wanted to multiply them with trigonometric functions in order to get an ellipse, but I really have no idea how! Finally could you explain more detailed what you mean by the gravity acting as a repelling force? How would you change the code! Thanks in advance and sorry for the inconvenience, I'm a real beginner at programming! – Hannes Hauser Apr 17 '19 at 13:31
  • 2
    This may be a too-hard problem for a beginner. Orbital mechanics is not the easiest beginner subject! But you are well on your way to modeling spring forces; maybe try that first. – Eric Lippert Apr 17 '19 at 13:46
  • You have the force as a positive number when the moon is in front of the earth, but it needs to be *towards the earth*. When the position is positive, the sign needs to be negative, and vice versa for when the position is negative. – Eric Lippert Apr 17 '19 at 13:50
  • I don't understand what you mean by "multiply by trig functions". – Eric Lippert Apr 17 '19 at 13:50
  • see [Is it possible to make realistic n-body solar system simulation in matter of size and mass?](https://stackoverflow.com/a/28020934/2521214) and all the sub-links in there ... – Spektre Apr 18 '19 at 05:22
  • If someone else could help, that would be greatly appreciated. I did it the way Eric said, but am struggling with the AcclerationOfTheMoon Method. I'd like to compute the magnitude of the Graviational Force, multiplicate it with the Unit-Vector of the Position to get my Gravitational Force as a vector for my initial state. Only thing I'm struggling with now is the Syntax inside this Method, i can't seem to find an appropriate Method to calculate my Magnitude and my Unit Vector. Help is greatly appreciated and also explain as much as you can, i want to learn! – Hannes Hauser Apr 19 '19 at 11:26
  • I need to get my initial Position (that I declare @ the for-loop) inside my method "AccelerationOfTheMoon" in order to calculate the Magnitude of the Position Vector. Thats probably my main struggle and whats the best option to declare a Method inside another Method, like in this case? – Hannes Hauser Apr 19 '19 at 11:35
  • Edited my first post! – Hannes Hauser Apr 20 '19 at 10:49

1 Answers1

12

You've made two obvious mistakes and a poor choice of algorithm.

First, you've modeled the position of the moon as a single number rather than a vector in 3-space, so what you're modeling here is simple harmonic motion, like a spring constrained to a single dimension, and not an orbit. Start by modeling positions and velocities as 3-space vectors, not doubles.

Second, you've made the sign of the gravitational force positive, so that it is a repelling force between two bodies, rather than attractive. The sign of the force has to be in the direction of the earth.

Third, your implementation of Euler's algorithm seems to be correct, but Euler is a poor choice for numerically solving orbital problems because it is not conservative; you can easily get into situations where the moon gains or loses a little bit of momentum, and that adds up, and wrecks your nice elliptical orbit.

Since the Moon's orbit is Hamiltonian, use a symplectic algorithm instead; it's designed to simulate conservative systems.

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

This approach, and your Eulerian approach, are fundamentally about finding the state vectors:

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

However, for your simple 2-body system there are easier methods. If what you want to do is make a simulation like Kerbal Space Program, where only the body you are orbiting affects your orbit, and planets with multiple moons are "on rails", you don't need to simulate the system on every time unit to work out the sequence of state vectors; you can compute them directly given the Keplerian elements:

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

We know the six elements for the moon to a high degree of precision; from those you can compute the position in 3-space of the moon at any time, again, assuming that nothing perturbs its orbit. (In reality, the moon's orbit is changed by the sun, by the fact that the earth is not a sphere, by the tides, and so on.)


UPDATE:

First off, since this is for coursework you are required to cite all your sources, and that includes getting help from the internet. Your instructors must know what work is yours and what work you had someone else do for you.

You asked how to do this work in two dimensions; that seems wrong, but whatever, do what the course work says.

The rule that I wish more beginners were taught is: make a type, a method or a variable which solves your problem. In this case, we wish to represent the behavior of a complex value, so it should be a type, and that type should be a value type. Value types are struct in C#. So let's do that.

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

Notice that vectors are immutable, just like numbers. You never mutate a vector. When you need a new vector, you make a new one.

What operations do we need to perform on vectors? Vector addition, scalar multiplication, and scalar division is just fancy multiplication. Let's implement those:

    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);

We can do multiplication in the other order too, so let's implement that:

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

Making a vector negative is the same as multiplying it by -1:

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

And to help us debug:

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

}

And we're done with vectors.

We are trying to simulate the evolution of orbital state parameters, so again make a type. What are the state parameters? Position and velocity:

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

Now we get to the core algorithm. What do we have? a state and an acceleration. What do we want? A new state. Make a method:

    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);
    }
}

Super. What's left? We need to work out the acceleration. Make a method:

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.
}

And now you have all the parts you need. Starting from an initial state you can repeatedly call AccelerationOfTheMoon to get the new acceleration, and then call Euler to get the new state, and repeat.

As a beginner, study these techniques carefully. Notice what I did: I made types to represent concepts, and methods to represent operations on those concepts. Once you do that, the program becomes extremely clear to read.

Think about how you would extend this program using these techniques; we made a hard-coded AccelerationOfTheMoon method, but what if we wanted to compute accelerations of several bodies? Again, make a type to represent Body; a body is characterized by State and mass. What if we wanted to solve the n-body problem? Our acceleration computation would have to take the other bodies as a parameter. And so on.

Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
  • Ok this one really helped! I tried to do this with 2D vectors but i really have no idea how to work with vectors in C#! If you could show me i would highly appreciate it. Furthermore I HAVE to work with Eulers approximation I could simply increase the accuracy by using RungeKutta Method, which i have no experience with! The only two formulas i am allowed to use are Newtons Graviational Law as well as Newton's 2nd Law of Motion! So i think the links you suggested are a little bit too complex for my simulation here, but are greatly appreciated! – Hannes Hauser Apr 17 '19 at 13:58
  • 1
    @HannesHauser: Is this for an assignment? You should have said so. It's fine to get help with your assignments, but I've wasted time trying to help solve a problem you don't have. Also, I don't see why you'd solve the problem with 2-D vectors; the moon exists in a 3-dimensional space. – Eric Lippert Apr 17 '19 at 14:08
  • Oh i see but as i created this question I already told the StackOverflow editor that I needed this for my work at UNI! But anyways I'm sorry to waste your time, that was definitely not what i wanted! Our lecturer said that we had to do it in 2D since moon and earth are almost perfectly aligned which gives us the possibility to to all calculations and visualizations in 2D. – Hannes Hauser Apr 17 '19 at 14:15
  • The moon is not almost perfectly aligned with the ecliptic! If it were then we'd have a lunar eclipse every month! – Eric Lippert Apr 17 '19 at 14:16
  • I'm really sorry to bother you with that but our task was to program it in 2D and I don't really know any better, im an absolute beginner at programming and my field of study differs completely from orbital mechanics! – Hannes Hauser Apr 17 '19 at 14:25
  • @HannesHauser: I've added some updates to show how to model 2d vectors in C#. – Eric Lippert Apr 17 '19 at 14:27
  • Ok awesome thanks for your work! I'll do my best but since we were never taught how to work with vectors I'm really having a hard time with this! Is there a possibility to do this with cos and sin instead of vectors? But I will try your tips anyway! – Hannes Hauser Apr 17 '19 at 14:35
  • @HannesHauser: Yes, you can work it out with trig if you represent orbits via their Keplerian elements; you've already rejected that suggestion. – Eric Lippert Apr 17 '19 at 14:37
  • @HannesHauser: Vectors are just a pair of numbers instead of a single number, because it is convenient to put the coordinates into one thing. Don't be intimidated by the fancy name; it's just a way to conceptualize a value that requires two numbers. – Eric Lippert Apr 17 '19 at 14:40
  • I really thank you for your help even though we didn't learn to work with neither classes nor vectors so I'm having a real hard time here to figure this out... I have so many questions on how to work this out, e.g. why didn't you use a for-loop or whats with the "get;" - operator inside the brackets. I don't want to waste your time but any further help would be great! – Hannes Hauser Apr 17 '19 at 14:57
  • @HannesHauser: You're trying to run before you crawl. Learn the basics of the language: types, methods, properties, and so on, before you try to write a complicated program! – Eric Lippert Apr 17 '19 at 16:10
  • @HannesHauser: The `{get;}` means "this property can only be read, not written, after it is initially set". You never want to change the value of a coordinate in a vector; if you've changed the coordinate, it's a *different vector*. `{get; set;}` means it can be both read and written. – Eric Lippert Apr 17 '19 at 16:12
  • @HannesHauser: The form of a `for` loop is `for( initial state; ending condition; compute new state) do action`. What's the initial `State`? what is the ending condition? How do you compute new state given the old state? Once you've answered these questions, you will know what `for` loop to write. – Eric Lippert Apr 17 '19 at 16:14
  • Problem is I'm coming from a different field of education, so I have a big disadvantage comparing to my fellow students plus I have very little time to complete the project, but thats another topic. About the for loop: E.g. my initial condition is probably a vector pointing to the location of the moon during "periapsis" and the ending condition is reached once it touches the same point,right? If you could use some of the values that i showed at the beginning it would really clear things up for me! – Hannes Hauser Apr 17 '19 at 16:50
  • @HannesHauser: Again, walk before you run. *Can you implement a method that takes a position of the moon and computes an acceleration due to gravity?* Start with: what direction is the force in, as a function of position? – Eric Lippert Apr 17 '19 at 17:00
  • Im calculating acceleration by dividing the gravitational force with the mass of the moon, I already did that with my code but I just dont know who to implement my values into your code in order to start working with vectors... – Hannes Hauser Apr 17 '19 at 17:03
  • @HannesHauser: Well, break it down. You have a `State`. A state contains a `Position`. The force is proportional to `G * Me * Mm / (distance * distance)`. You know scalars `G`, `Me` and `Mm`. What is `distance` as a function of `Position`? This quantity is called the *magnitude*; how do you compute it? – Eric Lippert Apr 17 '19 at 17:07
  • The distance is calculated by r=sqrt((G* me *mm)/F) – Hannes Hauser Apr 17 '19 at 17:16
  • No, it isn't. You have a position. A position is a vector. A vector is a pair of X, Y coordinates that are an offset from the center of the earth. How do you compute the distance to the center of the earth given an X, Y pair? – Eric Lippert Apr 17 '19 at 17:17
  • I really can't follow you, I'm sorry. – Hannes Hauser Apr 17 '19 at 17:24
  • Draw a diagram that has the earth and the moon on it. The earth is at (0, 0). The moon is at (X, Y). What's the distance between the earth and the moon on your diagram? – Eric Lippert Apr 17 '19 at 17:25
  • I think this problem is much too hard for where you're at in your mathematical/physics education; this isn't really a good forum to try to teach basic geometry. Maybe get a tutor, or ask your professor or teaching assistant for help. Orbital mechanics is not a suitable beginner topic if you don't yet know what vectors are. – Eric Lippert Apr 17 '19 at 17:26
  • I really do know what vectors are, but i just dont understand your questions. Im calculating the distance by substracting (x,y)-(0,0) which returns (x,y) and to get the length i take the square root of vector (x/y)^2 which equals √(x^2+y^2) – Hannes Hauser Apr 17 '19 at 17:39
  • That's correct, so now you can add a method to `Vector2` called `Magnitude` that returns the magnitude of a vector. Now you can determine the magnitude of the gravitational force by squaring the magnitude of the position vector, but you still need to determine its direction. So, new problem: given the position of the moon, can you compute a vector *in the direction of the force* whose magnitude is 1.0 ? Remember that the direction of the force has to be *towards the earth*. – Eric Lippert Apr 17 '19 at 17:42
  • Once you have done that then you have two things; the magnitude of the force, as a scalar, and the direction of the force, as a unit vector. Multiplying them together gives you the force as a vector, which you can then divide by the mass of the moon to get the acceleration as a vector. – Eric Lippert Apr 17 '19 at 17:46
  • When you do that, you should notice something. You computed the magnitude of the acceleration as `(G * Mm * Me / (d * d)) / Mm)` -- why did you multiply by `Mm` and then divide it out? **The acceleration due to gravity caused by the earth on the moon is independent of the mass of the moon**. We could put an object of *any* mass in the orbit of the moon and the orbit would not change; if we replaced the moon with a baseball, it would still go around once a month. – Eric Lippert Apr 17 '19 at 17:48
  • I'm kinda getting the hang of it! I'll look at this more intensely tomorrow and will report! I hope you'll still answer by then! You are a great help eric – Hannes Hauser Apr 17 '19 at 18:01
  • @HannesHauser: You're welcome, but I encourage you to find help at your school with the math. The lesson in programming, again, is *make types and methods to represent concepts and operations*. Your program will be much more clear and understandable and correct if you do. I will be home visiting family for Easter and not on computers until Tuesday, so I won't be around to comment further. Good luck! – Eric Lippert Apr 17 '19 at 18:03
  • To get the unit vector i need to divide my gravitation vector (x,y) with |(x.y)| which is optained by taking the square root of (x^2+y^2). So than i have to multiply this one with the magnitude (which is a scalar). Do i need to switch my final vector to a negative value? – Hannes Hauser Apr 17 '19 at 20:50
  • Still my bigger problem is impementing and calculating with vectors in C#! Really putting in values would help greatly if you wouldn't mind. Furthermore I'll try your tip on increasing the usage of more object-oriented programming. – Hannes Hauser Apr 17 '19 at 20:54
  • You need to make the unit vector in the direction of the earth, which is the negative of the direction of the position vector. To work out the values, again, **draw an XY diagram showing the Earth and the Moon**, and mark on the diagram the starting position, and the starting velocity. Remember, the velocity must be *tangent* to the orbit. – Eric Lippert Apr 17 '19 at 21:03
  • Start with the position: what's the starting position of the Moon, in XY coordinates, centered on the Earth? You're picking the coordinate system, so you decide. – Eric Lippert Apr 17 '19 at 21:06
  • Alright, i basically planned the earth to be at the origin of the cartesian coordinate system having the coordinates (0,0). Moon is starting at the periapsis having the coordinates (363300000,0). Ok so you said velocity must be tangent to the orbit, that being said my starting vector for velocitity is (0,1076). So i got my two state vectors, with that i can calculate my acceleration vector which is pointing towards the earth and should have the starting coordinates of (-0.003,0). I hope this is right so i dont bother you anymore! – Hannes Hauser Apr 17 '19 at 21:36
  • @HannesHauser: Now the next thing to do is: put the whole thing in a loop. You start with your initial conditions at t=0, then you take a step of size delta_t: calculate the acceleration, then calculate the new state vectors. Now you have a state vector at time delta_t. Go through the loop again, and take a step of size delta_t, calculate the acceleration, calculate the new state vector, and repeat as many times as you like. – Eric Lippert Apr 17 '19 at 21:51
  • @HannesHauser: Once you have got this solid, a challenge for you. The moon does not orbit around the center of the earth. Rather, the earth and the moon both orbit around a point on the interior of the earth away from the center called the *barycenter*. Can you work out how to modify your system to solve the two-body problem? Unfix the earth from the origin, and have its position and velocity influenced by the gravity of the moon. – Eric Lippert Apr 17 '19 at 21:53
  • So all the code you wrote above is put in another class given another name as my main program and they are called in my main class via the constructor? And my new vectors are then put in an array right? After all this doesn't seem to hard, i was just basically loosing hope battling with this one for almost a week! – Hannes Hauser Apr 17 '19 at 21:58
  • You can put the vectors in an array if you want, or not. All you need to calculate the next one is the previous one, so you don't necessarily need all of them. You can put the types in another file if you like, or keep them in your main file; good practice would be to put them in their own files, but this will be a pretty short program so maybe you want it all in one place. Remember to indicate derivative work when appropriate; academic honesty is an important habit to get into. – Eric Lippert Apr 17 '19 at 22:07
  • If im unfixing the earth i have two moving objects, so earth also gets a velocity, acceleration and location vector. Since earth is about 80 times the mass of the moon, the location of the barycenter needs to be around 1/80 of the distance between earth and moon. Considering this, earth must also follow the path of an ellipse just like the moon. Maybe the barycenter is on the line that connects both spherical centers which contain all the mass - in theory. – Hannes Hauser Apr 17 '19 at 22:11
  • You mean i should just let the computer plot each calculated value real time in a bitmap so actually none of them really get stored? I will link stackoverflow as one of my main sources of information and will recommend further! – Hannes Hauser Apr 17 '19 at 22:14
  • @HannesHauser: Re: the location of the barycenter, that is almost exactly right. The fraction is actually `mm/(me+mm)`, so if the ratios are 80 to 1, the fraction is 1/81 of the earth-moon distance. – Eric Lippert Apr 17 '19 at 22:48