# Assignment 6: Planet Simulation

Due: Thursday, April 2nd by 11:59 PM

## Update

Note: the Planet.cpp source file has a minor error. At the beginning of the loop in the main function, there are two statements:

```render_scene(scene);
cons_update();
```

Change them to

```cons_clear_screen();
render_scene(scene);
cons_update();
```

Without this fix, the planets will leave "trails" in the window.

## Planet Simulation

In this assignment, you will write a program that simulates the motion of a planet orbiting around a star.

The basic approach will be very similar to the animation you created in Lab 16.

## Getting Started

Start a Cygwin Bash Shell and run the following commands:

```cd h:
cd CS101
unzip CS101_Assign6.zip
cd CS101_Assign6
```

H:\CS101\CS101_Assign6\Planet.cpp

Run the command

```make
```

when you are ready to compile the program. To run the program, run the command

```./Planet.exe
```

Your task is to simulate a solar system with a star orbited by at least one planet. The star's position is fixed, and the planet orbits around the star. The motion of the planet at each step of the animation is based on two values, dx and dy (delta X and delta Y). At each step of the animation, dx is added to the planet's x coordinate and dy is added to the planet's y coordinate. In the absence of any force acting on the planet (i.e., if dx and dy stay constant), this causes the planet to move in a straight line with a constant velocity. (Bodies in motion tend to stay in motion.)

However, there is a force acting on the planet: the star's gravity. At each step of the simulation, the current velocity and direction of the planet (dx and dy) should be changed based on the gravitational attraction of the planet towards the star. The magnitude of the gravitational attraction, fgrav, is given by the following formula:

fgrav = M / dist2

where M is a constant representing the mass of the star and the planet, and dist is the geometric distance between the center of the star and the center of the planet. The geometric distance between two points (x1,y1) and (x2,y2) is given by the formula

dist = sqrt( (x2 - x1)2 + (y2 - y1)2 )

(In the formula above, sqrt means the square root.)

In order to determine how the force of gravitational attraction affects the planet's motion (dx and dy), you will need to determine the horizontal (fx) and vertical (fy) components of the gravitational force:

The horizontal and vertical components of the gravitational force, fx and fy, are proportional to distx and disty, the x and y components of the distance between the star and the planet:

distx = planetx - starx

disty = planety - stary

fx = fgrav (|distx| / dist)

fy = fgrav (|disty| / dist)

Note that ||distx|| means the absolute value of distx, and ||disty|| means the absolute value of disty.

So, to determine the change in the direction and velocity of the planet at each step of the simulation, fx is either added to or subtracted from dx, and fy is either added to or subtracted from dy. You will know whether to add or subtract by considering that gravity is an attractive force; you should change dx and dy in a way that either decreases the planet's velocity away from the star, or increases the planet's velocity towards the star.

Note: we are assuming that the acceleration (change in motion) of the planet is directly proportional to the force acting on it. In other words, we are not taking the mass of the planet into account. (A more massive planet would accelerate more slowly, and a less massive one would accelerate more quickly.) So, you can assume that the mass of the planet is equal to 1.

Once you have computed the change in dx and dy based on the gravitational force, you can then change the x and y coordinates of the planet. When you run the program, you should see the planet orbit around the star.

You can run our solution to the assignment to get a sense of what yours should do:

CS101_Assign6.exe

Our implementation has three planets. The initial simulation parameters are as follows:

starx = cons_get_screen_width() / 2
stary = cons_get_screen_height() / 2
M = 4
planet1x = starx
planet1y = stary + 10
planet1dx = .5
planet1dy = 0
planet2x = starx - 20
planet2y = stary
planet2dx = .2
planet2dy = -.4
planet3x = starx
planet3y = stary - 15
planet3dx = .3
planet3dy = -.15

You may want to increase the size of the console window and decrease the size of the text font in order to keep the planets visible. (Click on the icon at the upper left-hand corner of the console window, choose Properties from the menu, and then configure Layout and Font.)

## Hints

All of your simulation variables (fields in struct Scene) should be double variables. Don't do calculations using integer arithmetic. Do the calculations using floating-point (double) arithmetic, and then, in the render_scene function, convert the x and y coordinates of the planet and star to int column and row values using type casts, e.g.:

```int star_x, star_y;

star_x = (int) scene.star_x;
star_y = (int) scene.star_y;
```

As your simulation runs, the x and y coordinates of the planet may sometimes be off screen. You should handle this in your render_scene function: if either x or y is less than 0, or if x >= cons_get_screen_width(), or if y >= cons_get_screen_height(), don't display the planet.

Define a struct Planet data type to represent all of the information about a planet. Simulating multiple planets is very easy if your struct Scene data type has a field which is an array or vector of struct Planet elements.

You may want to increase the size of the console window in which the program runs. (See above.)

The following two function prototypes are defined in the <math.h> header file:

```double sqrt(double value);
double fabs(double value);
```

The sqrt function returns the square root of a double value, and the fabs function returns the absolute value of a double value.

You can change the value of the ANIMATION_DELAY constant in order to speed up or slow down the simulation.

Up to 80 percent: Implement a basic simulation with a star and a single planet, as described above.

Up to 90 percent: Implement the basic simulation using a struct Planet data type, which represents a single planet. Include appropriate functions to perform operations on instances of struct Planet, such as moving the planet, calculating the gravitational force on the planet, etc.

Up to 100 percent: Simulate multiple planets.

As always: Make sure that you indent your code properly, choose meaningful variable and function names, and add appropriate comments. Points may be deducted for poor coding style.

## Submitting

To submit your work, make sure your Planet.cpp file is saved, and type the command

```make submit
```