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
| Ball::Ball(int id, int radius, int x, int y, float velocity_x, float velocity_y) //constructeur
{
m_id = id;
m_radius = radius;
m_x = x;
m_y = y;
m_velocity_x = velocity_x;
m_velocity_y = velocity_y;
m_accel_x = 0.0;
m_accel_y = 0.0;
}
void Ball::move_(int l_left, int l_top, int l_right, int l_bot){
if(m_x> l_right){
m_x = l_right;
m_velocity_x *= -1;
}
if(m_x< l_left){
m_x = l_left;
m_velocity_x *= -1;
}
if(m_y + m_velocity_y > l_bot){
m_y = l_bot;
m_velocity_y *= -1;
}
if(m_y + m_velocity_y < l_top){
m_y = l_top;
m_velocity_y *= -1;
}
m_x += m_velocity_x;
m_y += m_velocity_y;
}
int rand_a_b(int a, int b, int c){
srand(time(NULL) + c);
return rand()%(b-a) +a;
}
int hitTest(Ball* a, Ball* b){
double balls_distance_x = static_cast<double>(a->m_x - b->m_x);
double balls_distance_y = static_cast<double>(a->m_y - b->m_y);
return balls_distance_x*balls_distance_x + balls_distance_y*balls_distance_y < pow(static_cast<double>(a->m_radius + b->m_radius), 2.0);
}
void updatePositions(Ball* a, Ball* b){//une fois hitTest détecté on place les balles qui se chevauchent, en bordure de tangeante au point de collision
double collision_angle, angle_pos_a, angle_pos_b, a_norm_pos, b_norm_pos, a_ccs_x, a_ccs_y, b_ccs_x, b_ccs_y;
collision_angle = atan2(static_cast<double>(a->m_y - b->m_y), static_cast<double>(a->m_x - b->m_x));
angle_pos_a = atan2(static_cast<double>(a->m_y), static_cast<double>(a->m_x));
angle_pos_b = atan2(static_cast<double>(b->m_y), static_cast<double>(b->m_x));
a_norm_pos = sqrt(static_cast<double>(a->m_x*a->m_x + a->m_y*a->m_y));
b_norm_pos = sqrt(static_cast<double>(b->m_x*b->m_x + b->m_y*b->m_y));
a_ccs_x = a_norm_pos*cos(angle_pos_a - collision_angle);
a_ccs_y = a_norm_pos*sin(angle_pos_a - collision_angle);
b_ccs_x = b_norm_pos*cos(angle_pos_b - collision_angle);
b_ccs_y = b_norm_pos*sin(angle_pos_b - collision_angle);
if(a_ccs_x > b_ccs_x){
a_ccs_x = (a_ccs_x + b_ccs_x)/2.0 + a->m_radius; // on positionne les boules de façon tangeante au point de collision dans le nouveau système de coordonnées
b_ccs_x = a_ccs_x - a->m_radius - b->m_radius;
}else{
a_ccs_x = (a_ccs_x + b_ccs_x)/2.0 - a->m_radius; // on positionne les boules de façon tangeante au point de collision dans le nouveau système de coordonnées
b_ccs_x = a_ccs_x + a->m_radius + b->m_radius;
}
a->m_x = cos(collision_angle)*a_ccs_x - sin(collision_angle)*a_ccs_y; // On rote les vecteurs position dans le bon système de coordonnées en utilisant une matrice de rotation 2D
a->m_y = sin(collision_angle)*a_ccs_x + cos(collision_angle)*a_ccs_y;
b->m_x = cos(collision_angle)*b_ccs_x - sin(collision_angle)*b_ccs_y;
b->m_y = sin(collision_angle)*b_ccs_x + cos(collision_angle)*b_ccs_y;
}
void updateVelocities(Ball* a, Ball* b){ //une fois hitTest détecté on on réinitialise les vecteurs vitesses respectifs des 2 balles
double collision_angle, angle_velocity_a, angle_velocity_b, a_norm_velocity, b_norm_velocity, a_ccs_velocity_x, a_ccs_velocity_y, b_ccs_velocity_x, b_ccs_velocity_y;
double a_new_ccs_velocity_x, b_new_ccs_velocity_x, a_new_ccs_norm_velocity, b_new_ccs_norm_velocity, a_mass, b_mass;
collision_angle = atan2(static_cast<double>(a->m_y - b->m_y), static_cast<double>(a->m_x - b->m_x));
angle_velocity_a = atan2(static_cast<double>(a->m_velocity_y), static_cast<double>(a->m_velocity_x));
angle_velocity_b = atan2(static_cast<double>(b->m_velocity_y), static_cast<double>(b->m_velocity_x));
a_norm_velocity = sqrt(static_cast<double>(a->m_velocity_x*a->m_velocity_x + a->m_velocity_y*a->m_velocity_y));
b_norm_velocity = sqrt(static_cast<double>(b->m_velocity_x*b->m_velocity_x + b->m_velocity_y*b->m_velocity_y));
a_ccs_velocity_x = a_norm_velocity*cos(angle_velocity_a - collision_angle); //ccs = changed coordinate system. la tangeante au point de collision devient perpendiculaire à l'axe des absisses, ce qui simplifie le calcul
a_ccs_velocity_y = a_norm_velocity*sin(angle_velocity_a - collision_angle);
b_ccs_velocity_x = b_norm_velocity*cos(angle_velocity_b - collision_angle);
b_ccs_velocity_y = b_norm_velocity*sin(angle_velocity_b - collision_angle);
a_mass = (static_cast<double>(4/3)*3.141592*powf(static_cast<float>(a->m_radius), 3.0))/50.0;
b_mass = (static_cast<double>(4/3)*3.141592*powf(static_cast<float>(b->m_radius), 3.0))/50.0;
a_new_ccs_velocity_x = (a_ccs_velocity_x*(a_mass - b_mass) + 2*b_mass*b_ccs_velocity_x)/(a_mass + b_mass);// on peut se contenter de faire à présent une collision 1D sur l'axe des x
b_new_ccs_velocity_x = (b_ccs_velocity_x*(a_mass - b_mass) + 2*b_mass*a_ccs_velocity_x)/(a_mass + b_mass);
a->m_velocity_x = cos(collision_angle)*a_new_ccs_velocity_x - sin(collision_angle)*a_ccs_velocity_y; // On rote les vecteurs vitesse dans le bon système de coordonnées en utilisant une matrice de rotation 2D
a->m_velocity_y = sin(collision_angle)*a_new_ccs_velocity_x + cos(collision_angle)*a_ccs_velocity_y;
b->m_velocity_x = cos(collision_angle)*b_new_ccs_velocity_x - sin(collision_angle)*b_ccs_velocity_y;
b->m_velocity_y = sin(collision_angle)*b_new_ccs_velocity_x + cos(collision_angle)*b_ccs_velocity_y;
//Ball::s_collision = true;
}
Ball::~Ball() //destructeur
{
//delete this;
} |
Partager