mpri-graphics-project/Ball.cpp

115 lines
2.9 KiB
C++
Raw Normal View History

2018-02-07 15:08:16 +01:00
#include "Ball.hpp"
2018-02-12 01:11:23 +01:00
#include <iostream>
2018-02-07 15:08:16 +01:00
#include <cmath>
bool bouncing = true;
double stop_bouncing;
2018-02-13 17:05:49 +01:00
Ball::Ball(const Point& _center, const Ground* _ground, double _min_height,
double _v_x, double _v_z, double _p, double _q) :
2018-02-07 15:18:53 +01:00
Center(_center),
surface(_center, _min_height, _p, _q),
2018-02-13 17:05:49 +01:00
ground(_ground),
radius(_p),
2018-02-12 18:18:28 +01:00
init_h(_center.y),
min_height(_min_height),
2018-02-12 10:21:49 +01:00
bounce_number(0.0),
2018-02-07 15:18:53 +01:00
crt_time(0),
2018-02-12 18:18:28 +01:00
A(_center.y),
2018-02-07 15:18:53 +01:00
B(0),
2018-02-12 18:18:28 +01:00
U(sqrt(2 * G_CTE * _center.y)),
T(sqrt(2.0 * _center.y / G_CTE)),
2018-02-12 13:54:39 +01:00
v_x(_v_x),
2018-02-12 18:32:58 +01:00
v_z(_v_z)
2018-02-07 15:18:53 +01:00
{
}
2018-02-07 15:08:16 +01:00
2018-02-11 22:42:15 +01:00
void Ball::_compute_pos(double dt) {
2018-02-13 18:06:01 +01:00
double height = (*ground)(Center.x, Center.z);
if (bouncing) {
Center.y = fmax(
2018-02-13 18:06:01 +01:00
min_height + height,
2018-02-13 18:26:18 +01:00
A + B * crt_time - (G_CTE / 2) * crt_time * crt_time + min_height
);
} else {
double n_time = crt_time - stop_bouncing;
double min_rad = radius - min_height;
2018-02-13 22:20:58 +01:00
v_x *= 0.8;
v_z *= 0.8;
2018-02-13 18:06:01 +01:00
Center.y = height + min_height + ((min_rad * (1.0 - exp(-n_time)) + min_rad )/2.) +
(min_rad - ((min_rad* (1- exp(-n_time)) + min_rad)/2.)) * sin(5. *
n_time);
}
2018-02-11 22:42:15 +01:00
Center.x += dt * v_x;
2018-02-12 18:32:58 +01:00
Center.z += dt * v_z;
2018-02-07 15:08:16 +01:00
surface.update_center_pos(Center);
2018-02-13 17:05:49 +01:00
surface.check_ground_collision(ground);
2018-02-07 15:08:16 +01:00
}
void Ball::_compute_T_n() {
double update = (2. * U / G_CTE);
2018-02-12 10:21:49 +01:00
T += update;
2018-02-07 15:08:16 +01:00
}
void Ball::_compute_B_n() {
B = G_CTE * T + U;
}
void Ball::_compute_A_n() {
A = - G_CTE * T * T / 2 - (U * T);
}
void Ball::_compute_U_n() {
U *= 0.8;
2018-02-07 15:08:16 +01:00
}
void Ball::_compute_v_x(Point normal) {
2018-02-12 18:32:58 +01:00
double factor = normal.x / (4*(normal.x + normal.z));
v_x *= (0.5 + factor);
2018-02-11 22:42:15 +01:00
}
2018-02-12 18:32:58 +01:00
void Ball::_compute_v_z(Point normal) {
2018-02-13 01:02:58 +01:00
double factor = normal.z / (4*(normal.x + normal.z));
2018-02-12 18:32:58 +01:00
v_z *= (0.5 + factor);
2018-02-11 22:42:15 +01:00
}
2018-02-13 20:53:23 +01:00
void Ball::_compute_parameters() {
2018-02-13 18:06:01 +01:00
Point normal = (*ground).get_normal(Center.x, Center.z);
2018-02-12 10:21:49 +01:00
bounce_number += 1;
2018-02-07 15:08:16 +01:00
_compute_U_n();
_compute_A_n();
_compute_B_n();
2018-02-12 10:21:49 +01:00
_compute_T_n();
_compute_v_x(normal);
2018-02-12 18:32:58 +01:00
_compute_v_z(normal);
2018-02-13 22:45:29 +01:00
min_height = fmin(radius, min_height + 0.2 * (radius - min_height));
std::cout << "U:" << U << "\n";
2018-02-13 20:53:23 +01:00
}
void Ball::update_pos(double dt) {
//double height = (*ground)(Center.x, Center.z);
crt_time += dt;
if ((bouncing) && (crt_time >= T)) {
double old_t = T;
double max_t;
_compute_parameters();
>>>>>>> Utility function
max_t = (T - old_t)/2.0 + old_t;
if (((A + B * max_t - (G_CTE / 2) * max_t * max_t + min_height) < radius)) {
stop_bouncing = crt_time;
bouncing = false;
}
2018-02-07 15:08:16 +01:00
}
2018-02-11 22:42:15 +01:00
_compute_pos(dt);
2018-02-07 15:08:16 +01:00
}
2018-02-12 01:11:23 +01:00
std::ostream& operator<< (std::ostream &out, Ball const& data) {
Point center = data.getCenter();
2018-02-12 10:21:49 +01:00
out << "t:" << data.access_crt_time() << ":";
out << "T:" << data.accessT() << ":";
2018-02-12 01:11:23 +01:00
out << center.x << ':';
2018-02-12 10:21:49 +01:00
out << center.z << ':';
2018-02-12 18:18:28 +01:00
out << center.y << ':';
2018-02-12 01:11:23 +01:00
return out;
}