1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187
|
#include <iostream>
#include <iomanip>
#include <cmath>
#include <time.h>
#include <stdlib.h>
#include <thread>
using std::thread;
#include <vector>
using std::vector;
using namespace std;
void wait(int seconds)
{
clock_t endwait;
endwait = clock() + seconds * CLOCKS_PER_SEC;
while (clock() < endwait) {}
}
void Autovelox (double v1, a1, v2, a2, v1max, v2max)
{
if(v1 < L) {
v1 = v1 + a1 * t;
}
if(v1 >= L) {
v1 = L;
}
if(v2 < L) {
v2 = v2 + a2 * t;
}
if(v2 >= L) {
v2 = L;
}
if(abs(v1) > abs(v1max)) {
v1max = v1;
}
if(abs(v2) > abs(v2max)) {
v2max = v2;
}
}
int main()
{
const double G = 6.67408e-11; // costante gravitazionale.
const double L = 299792458; // velocità della luce.
int n = std::thread::hardware_concurrency();
double m1, m2, d, i, p, F, a1, a2, s1, s2, t, cont,days, distparz,time, v1, v2,r1,r2,v1k,v2k,conth,contg,distmin,ao1,v1max,v2max,ao2,sdiff1,sdiff2;
double datiR[6] = { 6.371e+6 , 1.737e+6 , 6.96e+8 , 3.39e+6 , 6.9911e+7 , 13e+9 };
double datiM[6] = { 5.972e+24 , 7.34767309e+22 , 1.989e+30 , 3.844e+8 , 1.898e+27 , 8.573e+36 };
// terra luna sole marte giove sagittarius A*
double datiD[7] = { 3.84403e+8 , 1.496e+11 , 9.2451e+10 , 2.279e+11 , 7.785e+11 , 6.287e+11 , 2.46e+20 };
// dtl dts dtm dsm dgs dgt dss
double separation;
int sel;
float caricamento;
vector<ThreadItem> threadlist;
threadlist.resize(n);
printf("\nQuesto programma analizza due corpi che collassano su se stessi senza attriti.\nTutti i dati inseriti vanno interpretati nelle unita' dell'MKS.\nInserisci la massa del corpo n'1. Se si inserisce 0 si potra' scegliere tra dati predefiniti:\n");
scanf("%lf", &m1);
if(m1 == 0) {
do{
printf("O: Terra\n1: Luna\n2: Sole\n3: Marte\n4: Giove\n5: Sagittarius A* (Buco nero al centro della Via Lattea)\n");
scanf("%i",&sel);
}
while(sel > 5||sel < 0);
m1 = datiM[sel];
r1 = datiR[sel];
goto input2;
}
printf("Inserisci il raggio del corpo n'1. Inserire 0 per considerare un corpo puntiforme:\n");
scanf("%lf", &r1);
input2:
printf("Inserisci la velocita' iniziale del corpo 1 (si intende una velocita' in direzione del corpo 2. Accetta valori negativi):\n");
scanf("%lf",&v1);
v1max = v1;
printf("\nInserisci la massa del corpo n'2. Se si inserisce 0 si potra' scegliere tra dati predefiniti:\n");
scanf("%lf", &m2);
if(m2 == 0) {
do{
printf("O: Terra\n1: Luna\n2: Sole\n3: Marte\n4: Giove\n5: Sagittarius A* (Buco nero al centro della Via Lattea)\n");
scanf("%i",&sel);
}
while(sel > 5||sel < 0);
m2 = datiM[sel];
r2 = datiR[sel];
goto input3;
}
printf("Inserisci il raggio del corpo n'2. Inserire 0 per considerare un corpo puntiforme:\n");
scanf("%lf", &r2);
input3:
printf("Inserisci la velocita' iniziale del corpo 2 (si intende una velocita' in direzione del corpo 1. Accetta valori negativi):\n");
scanf("%lf",&v2);
v2max = v2;
distmin = r1 + r2;
printf("\nInserisci distanza tra i due corpi. Per inserire la distanza tra le due superfici inserire 1, poi il valore. Se si vuole inserire la distanza tra i due centri di massa inserire 2, poi il valore. Se si inserisce 0 si potra' scegliere tra dati predefiniti. Se si vuole sapere di di piu' sulle distanze inserire un numero negativo. ATTENZIONE! Se viene inserito 1 ricordarsi di digitare un valore maggiore alla distanza minima di %f m\n",distmin);
do {
scanf("%i", &sel);
if(sel<0) {
printf("Le distanze tra pianeti e sole è la distanza media fra i due. Le distanze fra pianeti sono distanze minime.");
}
}
while(sel<0||sel>2);
if(sel == 0) {
do{
printf("O: Terra-Luna\n1: Terra-Sole\n2: Terra-Marte\n3: Sole-Marte\n4: Sole-Giove\n5: Terra-Giove\n6: Sagittarius A*-Sistema Solare\n");
scanf("%i",&sel);
}
while(sel > 7||sel < 0);
d = datiD[sel];
goto input4;
}
scanf("%lf",&d);
if(sel == 2) {
d = d - r1 - r2;
}
if(d < 0) {
printf("ATTENZIONE! La distanza tra le superfici dei due corpi e' minore a zero! Questo significa che i due corpi sono l'uno dentro l'altro. Il programma si chiudera'...");
for(;;) {
}
}
input4:
printf("Decidi l'intervallo di tempo tra un calcolo e quello successivo in secondi (piu' il numero e' vicino a 0 piu' i calcoli saranno precisi ma occorreranno piu' risorse per svolgerlo):\n");
do {
scanf("%lf", &t);
}
while(t<=0);
long long int count = 0;
double distance = 0;
std::cout.precision(6);
std::cout << std::fixed;
for (;;)
{
separation = d - distance;
double F = G * m1 * m2 / (separation*separation);
double a1 = F / m1;
double a2 = F / m2;
threadlist[i].worker = thread(Autovelox(v1, a1, v2, a2, v1max, v2max),&threadlist[i].result);
double s1 = v1 * t;
double s2 = v2 * t;
count++;
distance = distance + s1 + s2;
caricamento = 100 - (100 * (d-distance)) / d;
if (count%1000000LL == 0)
{
days = count * t / 86400;
std::cout << "tempo: " << std::setw(12) << count
<< " distanza: " << std::setw(18) << separation
<< " giorni: " << std::setw(14) << days
<< " \ns1: " << std::setw(14) << s1
<< " s2: " << std::setw(14) << s2
<< " v1: " << std::setw(14) << v1
<< " v2: " << std::setw(14) << v2
<< " \nCaricamento... " << caricamento << "% della distanza iniziale completato..."
<< '\n';
}
ao1 = a1;
ao2 = a2;
if (distance >= d) {
time = count * t;
sdiff1 = (-0.5) * separation * s1 / s2;
sdiff2 = -(separation + sdiff1);
time = time - (2 * sdiff1 / ao1 + 2 * sdiff1 / ao1);
separation = separation + sdiff1 + sdiff2;
break;
}
}
for(int i = 0;i < n;i++) {
threadlist[i].worker.join();
}
v1k = v1max * 3.6;
v2k = v2max * 3.6;
conth = days*24;
time = conth * 60;
cout << "\nCALCOLI COMPLETATI\n";
wait(2);
cout << "\nSe questo valore e' 0 i calcoli sono corretti: " << separation << "\n";
printf("Dati: m1 = %lf m2 = %lf\nd = %lf (tra le superfici)\nI corpi collasseranno su se stessi in %lf s (%f h o %f giorni)", m1,m2,d,time,conth,days);
printf("\nLa velocita' massima raggiunta dal corpo 1 e' %lf m/s o %lf km/h\nLa velocita' massima raggiunta dal corpo 2 e' %lf m/s o %lf km/h\n", v1max,v1k,v2max,v2k);
system("pause");
}
|