- #1
ElectronicStudent123
- 5
- 0
- Homework Statement
- I have been tasked with creating a computer simulation that (algebraically) models the behavior of an asteroid as it approaches the Earth. I have a drawing area of 300 Mm by 200 Mm, which I scale down to be 1200 by 800 on screen and 12 by 8 on paper. The asteroid begins its journey in Q3 at point (-150Mm x, -100Mm y) and moves towards the Earth which its situated at the origin.
There are two variables associated with the asteroid: initial angle and initial speed. The angle can be between 10 degrees to 80 degrees and the speed can be between 1 km/s to 20 km/s. For programming purposes, I use scanf() to input the initial values, but the final product will use potentiometers to set the values.
The Earth is designated as point P(x,y) and the asteroid is designated as point C(x,y). The mass of the Earth is #define Mp 5.972e24 and the mass of the asteroid is #define Mc 26.99e9.
The purpose of this exercise is to better understand computing concepts like multitasking, graphics, multithreading, semaphores, IPCs, etc.
- Relevant Equations
- Vcx = Vc * cosA
Vcy = Vc * sinA
F = (G * Mp * Mc)/(R^2)
R^2 = (Px - Cx)^2 + (Py - Cy)^2
B = arctan((Py - Cy)/(Px - Cx)
ax = (F/Mc) * cosB
ay = (F/Mc) * sinB
Vcx = V0 + (ax * t)
Vcy = V0 + (ay * t)
Cx = Cx-old + (Vcx * t)
Cy = Cy-old + (Vcy * t)
The program begins by prompting the user to input the initial angle and speed. Once these values have been input, the program calculates the initial velocity components for the asteroid in two dimensions.
Once the initial velocity components have been calculated, a pipe for passing information between threads is created, along with two threads. The calculations are handled in the parent thread and the graphics are handled in the child thread. If any potential helpers would like me to post the entire code I can, but for now I am just going to post the calculations thread and its relevant code.
The calculations thread enters a while() loop that is terminated by the removal of an empty file in the directory in which the code is located. This empty file is removed if a) the asteroid leaves the drawing area b) the asteroid collides with the planet c) the asteroid enters a stable orbit. I have not been able to achieve a stable orbit yet, which is why I am here.
The calculations loop begins by determining what quadrant the asteroid is in by using a series of conditional statements.
Regardless of which quadrant the asteroid is in, the square of the distance between the asteroid and the Earth are calculated, as well as the force between them. I have a function called BCalc() which takes the current position of Cx and Cy as its arguments. This function calculates the angle between the asteroid and the Earth, and if the angle is negative, forces it to be positive (I am not sure if this is necessary).
Depending on which quadrant the asteroid is in, I declare a new angle, either A1, A2, A3 or A4 for use in the remaining calculations.
My program then proceeds to calculate the acceleration for the x-axis and the y-axis based on the cos and sin of either A1, A2, A3, A4. With these accelerations, I then update the x and y velocity components based on two conditional statements.
These conditionals are the same regardless of whatever quadrant the asteroid is in. Perhaps the problem with my code is here?
My drawing area is 300 Mm by 200 Mm, which I scale down to 1200 by 800. From a calculations perspective, I treat this as if there are four quadrants. Unfortunately, the graphics library that we have to use, initializes a drawing area that only behaves as if there is one quadrant (Q1) so I have to "shift" the Earth and the position of the asteroid relative to the Earth to Q1 for the purpose of displaying the graphics. This may be a source of error, but I believe that I have this part correct. The Earth is initially at the origin, and it is shifted to the middle of the drawing area (600, 400). Since the position of the asteroid will always be relative to the Earth, I take the x and y coordinates of the asteroid and add 600 to the x coordinate and 400 to the y coordinate to get the equivalent Q1 coordinate for use in the graphics thread.
Attached is an output of the program where we can see the path of the asteroid being altered by the Earths gravity (25 degrees initial angle with 8000 m/s initial speed). The second attachment is of my four quadrants for the calculations thread and the one quadrant for the graphics thread.
If you have any other questions, please let me know. I am making this thread in hopes that someone with more knowledge about this stuff can review my math and help find any errors that exist. Thanks for reading.
C:
printf("Input an initial angle from 10 to 80 degrees\n");
scanf("%f", &theta);
rewind(stdin);
printf("Input an speed from 1000 m/s to 20,000 m/s\n");
scanf("%f", &V0);
rewind(stdin);
printf("You have entered: %.1f degrees and %.1f km/s\n", theta, V0);
printf("Computing initial x and y components...\n");
theta *= torad;
Vcx = V0 * (cos(theta));
Vcy = V0 * (sin(theta));
printf("Vcx = %.1f m/s and Vcy = %.1f m/s\n\n", Vcx, Vcy);
Once the initial velocity components have been calculated, a pipe for passing information between threads is created, along with two threads. The calculations are handled in the parent thread and the graphics are handled in the child thread. If any potential helpers would like me to post the entire code I can, but for now I am just going to post the calculations thread and its relevant code.
C:
#define G 6.67408e-11 //universal graviational constant
#define Mp 5.972e24 //mass of the earth
#define Mc 26.99e9 //mass of apophis
#define ts 1200
#define pi 3.14159
#define torad pi/180
#define todeg 180/pi
#define scalar 250000
const double Px = 0;
const double Py = 0;
double Cx = -150e6;
double Cy = -100e6;
float ax = 0;
float ay = 0;
float a = 0;
float v = 0;
float Fx, Fy;
float Q1xy[2];
float Data[4]; //for use with DisplayData
while (endflag != NULL)
{
endflag = fopen("666", "r");
double Rsq, F;
float B = 0;
float cosA = 0;
float sinA = 0;
float A1 = 0;
float A2 = 0;
float A3 = 0;
float A4 = 0;
if(Cx > 0 && Cy > 0) //Q1
{
printf("***YOU ARE IN Q1***\n");
printf("Cx-now = %g Mm and Cy-now = %g Mm\n", Cx, Cy);
Rsq = ((Px - Cx) * (Px - Cx)) + ((Py - Cy) * (Py - Cy));
printf("Rsq = %g m^2\n", Rsq);
F = (G * Mp * Mc) / Rsq;
printf("Force = %g N\n", F);
B = BCalc(Cx, Cy); //BCalc is a function which calculates the angle and forces it positive if it is negative
printf("B = %.2f rad\n", B);
A1 = B;
printf("A1 = %.1f rad\n", A1);
cosA = cos(A1) * todeg;
printf("cosA = %.1f deg\n", cosA);
sinA = sin(A1) * todeg;
printf("sinA = %.1f deg\n", sinA);
ax = (F / Mc) * cos(A1);
ay = (F / Mc) * sin(A1);
if(Cx < Px && Cy < Py)
{
Vcx += (ax * ts);
Vcy += (ay * ts);
}
else
{
Vcx = Vcx - (ax * ts);
Vcy = Vcy - (ay * ts);
}
}
else if(Cx < 0 && Cy > 0) //Q2
{
printf("***YOU ARE IN Q2***\n");
printf("Cx-now = %g Mm and Cy-now = %g Mm\n", Cx, Cy);
Rsq = ((Px - Cx) * (Px - Cx)) + ((Py - Cy) * (Py - Cy));
printf("Rsq = %g m^2\n", Rsq);
F = (G * Mp * Mc) / Rsq;
printf("Force = %g N\n", F);
//B = atan((Py - Cy) / (Px - Cx));
B = BCalc(Cx, Cy);
printf("B = %.2f rad\n", B);
A2 = B + (pi / 2);
printf("A2 = %.1f rad\n", A2);
cosA = cos(A2) * todeg;
printf("cosA = %.1f deg\n", cosA);
sinA = sin(A2) * todeg;
printf("sinA = %.1f deg\n", sinA);
ax = (F / Mc) * cos(A2);
ay = (F / Mc) * sin(A2);
if(Cx < Px && Cy < Py)
{
Vcx += (ax * ts);
Vcy += (ay * ts);
}
else
{
Vcx = Vcx - (ax * ts);
Vcy = Vcy - (ay * ts);
}
}
else if(Cx < 0 && Cy < 0) //Q3 (asteroid starts here)
{
printf("***YOU ARE IN Q3***\n");
printf("Cx-now = %g Mm and Cy-now = %g Mm\n", Cx, Cy);
Rsq = ((Px - Cx) * (Px - Cx)) + ((Py - Cy) * (Py - Cy));
printf("Rsq = %g m^2\n", Rsq);
F = (G * Mp * Mc) / Rsq;
printf("Force = %g N\n", F);
//B = atan((Py - Cy) / (Px - Cx));
B = BCalc(Cx, Cy);
printf("B = %.2f rad\n", B);
A3 = B + pi;
printf("A3 = %.1f rad\n", A3);
cosA = cos(A3) * todeg;
printf("cosA = %.1f deg\n", cosA);
sinA = sin(A3) * todeg;
printf("sinA = %.1f deg\n", sinA);
ax = (F / Mc) * cos(A3);
ay = (F / Mc) * sin(A3);
if(Cx < Px && Cy < Py)
{
Vcx += (ax * ts);
Vcy += (ay * ts);
}
else
{
Vcx = Vcx - (ax * ts);
Vcy = Vcy - (ay * ts);
}
}
else if(Cx > 0 && Cy < 0) //Q4
{
printf("***YOU ARE IN Q4***\n");
printf("Cx-now = %g Mm and Cy-now = %g Mm\n", Cx, Cy);
Rsq = ((Px - Cx) * (Px - Cx)) + ((Py - Cy) * (Py - Cy));
printf("Rsq = %g m^2\n", Rsq);
F = (G * Mp * Mc) / Rsq;
printf("Force = %g N\n", F);
//B = atan((Py - Cy) / (Px - Cx));
B = BCalc(Cx, Cy);
printf("B = %.2f rad\n", B);
A4 = B + ((3 * pi) / 2);
printf("A4 = %.1f rad\n", A4);
cosA = cos(A4) * todeg;
printf("cosA = %.1f deg\n", cosA);
sinA = sin(A4) * todeg;
printf("sinA = %.1f deg\n", sinA);
ax = (F / Mc) * cos(A4);
ay = (F / Mc) * sin(A4);
if(Cx < Px && Cy < Py)
{
Vcx += (ax * ts);
Vcy += (ay * ts);
}
else
{
Vcx = Vcx - (ax * ts);
Vcy = Vcy - (ay * ts);
}
}
a = sqrt((ax * ax) + (ay * ay));
v = sqrt((Vcx * Vcx) + (Vcy * Vcy));
Cx += (Vcx * ts);
Cy += (Vcy * ts);
printf("acceleration = %.3f m/s^2\n", a);
printf("velocity = %.3f m/s\n", v);
printf("ax = %.3f m/s^2 and ay = %.3f m/s^2\n", ax, ay);
printf("Vcx = %.3f m/s and Vcy = %.3f m/s\n", Vcx, Vcy);
printf("Cx-new = %g Mm and Cy-new = %g Mm\n", Cx, Cy);
Fx = DownSizer(Cx);
Fy = DownSizer(Cy);
printf("Downsizing Cx and Cy yields: %.1f and %.1f\n", Fx, Fy);
Data[0] = Fx;
Data[1] = Fy;
Data[2] = Vcx;
Data[3] = Vcy;
char message[20];
memset(message, '\0', sizeof(message));
sprintf(message, "%.1f %.1f", Fx, Fy);
printf("Message = %s\n\n", message);
write(id[1], message, strlen(message)); //write message to pipe
sleep(1);
startgfx = fopen("1", "w"); //create flag to tell gfx to start the display
sleep(1);
}
float BCalc(double Cx, double Cy)
{
float tempB = 0;
tempB = atan((Py - Cy) / (Px - Cx));
if(tempB < 0)
{
tempB *= -1;
return tempB;
}
else return tempB;
}
The calculations thread enters a while() loop that is terminated by the removal of an empty file in the directory in which the code is located. This empty file is removed if a) the asteroid leaves the drawing area b) the asteroid collides with the planet c) the asteroid enters a stable orbit. I have not been able to achieve a stable orbit yet, which is why I am here.
The calculations loop begins by determining what quadrant the asteroid is in by using a series of conditional statements.
C:
if(Cx > 0 && Cy > 0) //Q1
else if(Cx < 0 && Cy > 0) //Q2
else if(Cx < 0 && Cy < 0) //Q3 (asteroid starts here)
else if(Cx > 0 && Cy < 0) //Q4
Regardless of which quadrant the asteroid is in, the square of the distance between the asteroid and the Earth are calculated, as well as the force between them. I have a function called BCalc() which takes the current position of Cx and Cy as its arguments. This function calculates the angle between the asteroid and the Earth, and if the angle is negative, forces it to be positive (I am not sure if this is necessary).
C:
float BCalc(double Cx, double Cy)
{
float tempB = 0;
tempB = atan((Py - Cy) / (Px - Cx));
if(tempB < 0)
{
tempB *= -1;
return tempB;
}
Depending on which quadrant the asteroid is in, I declare a new angle, either A1, A2, A3 or A4 for use in the remaining calculations.
C:
A1 = B;
A2 = B + (pi / 2);
A3 = B + pi;
A4 = B + ((3 * pi) / 2);
My program then proceeds to calculate the acceleration for the x-axis and the y-axis based on the cos and sin of either A1, A2, A3, A4. With these accelerations, I then update the x and y velocity components based on two conditional statements.
C:
if(Cx < Px && Cy < Py)
{
Vcx += (ax * ts);
Vcy += (ay * ts);
}
else
{
Vcx = Vcx - (ax * ts);
Vcy = Vcy - (ay * ts);
}
These conditionals are the same regardless of whatever quadrant the asteroid is in. Perhaps the problem with my code is here?
My drawing area is 300 Mm by 200 Mm, which I scale down to 1200 by 800. From a calculations perspective, I treat this as if there are four quadrants. Unfortunately, the graphics library that we have to use, initializes a drawing area that only behaves as if there is one quadrant (Q1) so I have to "shift" the Earth and the position of the asteroid relative to the Earth to Q1 for the purpose of displaying the graphics. This may be a source of error, but I believe that I have this part correct. The Earth is initially at the origin, and it is shifted to the middle of the drawing area (600, 400). Since the position of the asteroid will always be relative to the Earth, I take the x and y coordinates of the asteroid and add 600 to the x coordinate and 400 to the y coordinate to get the equivalent Q1 coordinate for use in the graphics thread.
Attached is an output of the program where we can see the path of the asteroid being altered by the Earths gravity (25 degrees initial angle with 8000 m/s initial speed). The second attachment is of my four quadrants for the calculations thread and the one quadrant for the graphics thread.
If you have any other questions, please let me know. I am making this thread in hopes that someone with more knowledge about this stuff can review my math and help find any errors that exist. Thanks for reading.
Attachments
Last edited by a moderator: