26 const double BOX = 500;
27 const double V0 = 100;
29 const double M2R = 2.0;
37 double x{0},
y{0},
z{0};
38 double vx{0}, vy{0}, vz{0};
52 "MRPT example: 3D gravity simulator- JLBC 2008", 1000, 700);
56 win.setCameraElevationDeg(50.0f);
57 win.setCameraZoom(1000);
66 obj->setColor(0.3, 0.3, 0.3);
67 theScene->insert(
obj);
76 for (
size_t i = 0; i <
N_MASSES; i++)
82 double a = atan2(masses[i].
y, masses[i].
x);
84 masses[i].vx = -
V0 * sin(
a) +
86 masses[i].vy =
V0 * cos(
a) +
99 masses[i].radius =
M2R * pow(masses[i].mass, 1.0 / 3.0);
100 obj->setRadius(masses[i].radius);
102 obj->setLocation(masses[i].
x, masses[i].
y, masses[i].
z);
103 theScene->insert(
obj);
107 win.unlockAccess3DScene();
112 double t0 = tictac.
Tac();
117 double t1 = tictac.
Tac();
123 win.get3DSceneAndLock();
126 double At_steps = At / n_steps;
127 n_steps =
min(n_steps,
size_t(3));
128 for (
size_t j = 0; j < n_steps; j++)
simulateGravity(masses, At_steps);
130 for (
size_t i = 0; i < masses.size(); i++)
133 obj->setLocation(masses[i].
x, masses[i].
y, masses[i].
z);
136 win.unlockAccess3DScene();
140 std::this_thread::sleep_for(1ms);
146 TForce() { f[0] = f[1] = f[2] = 0; }
152 const size_t N = objs.size();
154 vector<TForce> forces(N);
157 vector<pair<size_t, double>> lstMass_i_joins_j(
158 N, pair<size_t, double>(string::npos, 10000.0));
160 for (
size_t i = 0; i < (N - 1); i++)
162 const double Ri = objs[i].radius;
165 for (
size_t j = i + 1; j < N; j++)
167 double Ax = objs[j].x - objs[i].x;
168 double Ay = objs[j].y - objs[i].y;
169 double Az = objs[j].z - objs[i].z;
173 if (D == 0)
continue;
175 const double Rj = objs[j].radius;
180 if (D < lstMass_i_joins_j[j].second)
182 lstMass_i_joins_j[j].first = i;
183 lstMass_i_joins_j[j].second = D;
189 G * objs[i].mass * objs[j].mass /
square(max(D, 1.0));
190 double D_1 = 1.0 / D;
195 const double fx = Ax * K;
196 const double fy = Ay * K;
197 const double fz = Az * K;
199 forces[i].f[0] += fx;
200 forces[i].f[1] += fy;
201 forces[i].f[2] += fz;
203 forces[j].f[0] -= fx;
204 forces[j].f[1] -= fy;
205 forces[j].f[2] -= fz;
211 for (
size_t i = 0; i < N; i++)
213 const double M_1 = 1.0 / objs[i].mass;
215 forces[i].f[0] *= M_1;
216 forces[i].f[1] *= M_1;
217 forces[i].f[2] *= M_1;
219 objs[i].vx += forces[i].f[0] * At;
220 objs[i].vy += forces[i].f[1] * At;
221 objs[i].vz += forces[i].f[2] * At;
223 objs[i].x += objs[i].vx * At;
224 objs[i].y += objs[i].vy * At;
225 objs[i].z += objs[i].vz * At;
230 for (
int i = N - 1; i >= 0; i--)
232 const size_t newObj = lstMass_i_joins_j[i].first;
233 if (newObj == string::npos)
continue;
235 const double Mi = objs[i].mass;
236 const double Mj = objs[newObj].mass;
237 const double newMass = Mi + Mj;
238 const double newMass_1 = 1.0 / newMass;
241 COLLIS_LOSS * newMass_1 * (Mj * objs[newObj].vx + Mi * objs[i].vx);
243 COLLIS_LOSS * newMass_1 * (Mj * objs[newObj].vy + Mi * objs[i].vy);
245 COLLIS_LOSS * newMass_1 * (Mj * objs[newObj].vz + Mi * objs[i].vz);
247 objs[newObj].x = newMass_1 * (Mj * objs[newObj].x + Mi * objs[i].x);
248 objs[newObj].y = newMass_1 * (Mj * objs[newObj].y + Mi * objs[i].y);
249 objs[newObj].z = newMass_1 * (Mj * objs[newObj].z + Mi * objs[i].z);
251 objs[newObj].mass = newMass;
252 objs[newObj].radius =
M2R * pow(newMass, 1.0 / 3.0);
253 objs[newObj].obj3d->setRadius(objs[newObj].radius);
255 objs[i].obj3d->setVisibility(
false);
256 objs.erase(objs.begin() + i);
270 catch (
const std::exception& e)
277 printf(
"Untyped exception!!");
A namespace of pseudo-random numbers generators of diferent distributions.
double Tac() noexcept
Stops the stopwatch.
double drawUniform(const double Min, const double Max)
Generate a uniformly distributed pseudo-random number using the MT19937 algorithm, scaled to the selected range.
const double LARGEST_STEP
void randomize(const uint32_t seed)
Initialize the PRNG from the given random seed.
A high-performance stopwatch, with typical resolution of nanoseconds.
GLsizei GLsizei GLuint * obj
T square(const T x)
Inline function for the square of a number.
mrpt::gui::CDisplayWindow3D::Ptr win
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
The namespace for 3D scene representation and rendering.
bool kbhit() noexcept
An OS-independent version of kbhit, which returns true if a key has been pushed.
static Ptr Create(Args &&... args)
std::string exception_to_str(const std::exception &e)
Builds a nice textual representation of a nested exception, which if generated using MRPT macros (THR...
void simulateGravity(vector< TMass > &objs, double At)
Classes for creating GUI windows for 2D and 3D visualization.
void Tic() noexcept
Starts the stopwatch.
CRandomGenerator & getRandomGenerator()
A static instance of a CRandomGenerator class, for use in single-thread applications.
GLubyte GLubyte GLubyte a
static Ptr Create(Args &&... args)
A graphical user interface (GUI) for efficiently rendering 3D scenes in real-time.