26 const double BOX = 500;
27 const double V0 = 100;
29 const double M2R = 2.0;
36 TMass() :
x(0),
y(0),
z(0), vx(0), vy(0), vz(0), mass(1), obj3d() {}
52 "MRPT example: 3D gravity simulator- JLBC 2008", 1000, 700);
56 win.setCameraElevationDeg(50.0f);
57 win.setCameraZoom(1000);
65 mrpt::make_aligned_shared<opengl::CGridPlaneXY>(
66 -2000, 2000, -2000, 2000, 0, 100);
67 obj->setColor(0.3, 0.3, 0.3);
68 theScene->insert(
obj);
77 for (
size_t i = 0; i <
N_MASSES; i++)
83 double a = atan2(masses[i].
y, masses[i].
x);
85 masses[i].vx = -
V0 * sin(
a) +
87 masses[i].vy =
V0 * cos(
a) +
94 mrpt::make_aligned_shared<opengl::CSphere>();
101 masses[i].radius =
M2R * pow(masses[i].mass, 1.0 / 3.0);
102 obj->setRadius(masses[i].radius);
104 obj->setLocation(masses[i].
x, masses[i].
y, masses[i].
z);
105 theScene->insert(
obj);
109 win.unlockAccess3DScene();
114 double t0 = tictac.
Tac();
119 double t1 = tictac.
Tac();
125 win.get3DSceneAndLock();
128 double At_steps = At / n_steps;
129 n_steps =
min(n_steps,
size_t(3));
130 for (
size_t j = 0; j < n_steps; j++)
simulateGravity(masses, At_steps);
132 for (
size_t i = 0; i < masses.size(); i++)
135 obj->setLocation(masses[i].
x, masses[i].
y, masses[i].
z);
138 win.unlockAccess3DScene();
142 std::this_thread::sleep_for(1ms);
148 TForce() { f[0] = f[1] = f[2] = 0; }
154 const size_t N = objs.size();
156 vector<TForce> forces(N);
159 vector<pair<size_t, double>> lstMass_i_joins_j(
160 N, pair<size_t, double>(string::npos, 10000.0));
162 for (
size_t i = 0; i < (N - 1); i++)
164 const double Ri = objs[i].radius;
167 for (
size_t j = i + 1; j < N; j++)
169 double Ax = objs[j].x - objs[i].x;
170 double Ay = objs[j].y - objs[i].y;
171 double Az = objs[j].z - objs[i].z;
175 if (D == 0)
continue;
177 const double Rj = objs[j].radius;
182 if (D < lstMass_i_joins_j[j].second)
184 lstMass_i_joins_j[j].first = i;
185 lstMass_i_joins_j[j].second = D;
191 G * objs[i].mass * objs[j].mass /
square(max(D, 1.0));
192 double D_1 = 1.0 / D;
197 const double fx = Ax * K;
198 const double fy = Ay * K;
199 const double fz = Az * K;
201 forces[i].f[0] += fx;
202 forces[i].f[1] += fy;
203 forces[i].f[2] += fz;
205 forces[j].f[0] -= fx;
206 forces[j].f[1] -= fy;
207 forces[j].f[2] -= fz;
213 for (
size_t i = 0; i < N; i++)
215 const double M_1 = 1.0 / objs[i].mass;
217 forces[i].f[0] *= M_1;
218 forces[i].f[1] *= M_1;
219 forces[i].f[2] *= M_1;
221 objs[i].vx += forces[i].f[0] * At;
222 objs[i].vy += forces[i].f[1] * At;
223 objs[i].vz += forces[i].f[2] * At;
225 objs[i].x += objs[i].vx * At;
226 objs[i].y += objs[i].vy * At;
227 objs[i].z += objs[i].vz * At;
232 for (
int i = N - 1; i >= 0; i--)
234 const size_t newObj = lstMass_i_joins_j[i].first;
235 if (newObj == string::npos)
continue;
237 const double Mi = objs[i].mass;
238 const double Mj = objs[newObj].mass;
239 const double newMass = Mi + Mj;
240 const double newMass_1 = 1.0 / newMass;
243 COLLIS_LOSS * newMass_1 * (Mj * objs[newObj].vx + Mi * objs[i].vx);
245 COLLIS_LOSS * newMass_1 * (Mj * objs[newObj].vy + Mi * objs[i].vy);
247 COLLIS_LOSS * newMass_1 * (Mj * objs[newObj].vz + Mi * objs[i].vz);
249 objs[newObj].x = newMass_1 * (Mj * objs[newObj].x + Mi * objs[i].x);
250 objs[newObj].y = newMass_1 * (Mj * objs[newObj].y + Mi * objs[i].y);
251 objs[newObj].z = newMass_1 * (Mj * objs[newObj].z + Mi * objs[i].z);
253 objs[newObj].mass = newMass;
254 objs[newObj].radius =
M2R * pow(newMass, 1.0 / 3.0);
255 objs[newObj].obj3d->setRadius(objs[newObj].radius);
257 objs[i].obj3d->setVisibility(
false);
258 objs.erase(objs.begin() + i);
272 catch (std::exception& e)
274 std::cout <<
"MRPT exception caught: " << e.what() << std::endl;
279 printf(
"Untyped exception!!");