const float largeurMin = 40;
const float largeurMax = 150;
+const float largeurChateau = 8.5;
+const float hauteurChateau = 7;
+
const float positionChateau1 = -85.0;
const float positionChateau2 = 85.0;
return min + (max - min)* (rand() / (RAND_MAX + 1.0));
}
+float deg2rad(float deg)
+{
+ const float PI = 4.0 * atan(1.0);
+ return deg * PI / 180.0;
+}
+
// conversion coordonnées réelles -> coordonnées fenêtre
int rtowX(const DrawingWindow& w, float rx)
{
return -(rYMax - rYMin + 1.0) * wy / w.height - rYMax;
}
+float hauteurMontagne(float largeur, float hauteur, float x)
+{
+ float rx = 2.0 * x / largeur;
+ return hauteur * (1.0 - rx * rx);
+}
+
void dessineTerrain(DrawingWindow& w, float largeur, float hauteur)
{
- float l = largeur / 2.0;
- float h = hauteur;
int y0 = rtowY(w, 0) + 1;
- int xmin = rtowX(w, -l) - 1;
- int xmax = rtowX(w, l) + 1;
+ int xmin = rtowX(w, -largeur / 2.0) - 1;
+ int xmax = rtowX(w, largeur / 2.0) + 1;
w.setColor("forestgreen");
for (int x = xmin; x <= xmax; x++) {
- float rx = wtorX(w, x) / l;
- float ry = h * (1.0 - rx * rx);
+ float rx = wtorX(w, x);
+ float ry = hauteurMontagne(largeur, hauteur, rx);
int y = rtowY(w, ry);
if (y <= y0)
w.drawLine(x, y0, x, y);
}
}
+void dessineVent(DrawingWindow &w, float vitesse)
+{
+ int lg = rtowX(w, vitesse) - rtowX(w, 0);
+ int dir = lg > 0 ? 1 : -1;
+ int y = 20;
+ w.setColor("black");
+ if (lg == 0) {
+ w.drawCircle(w.width / 2, y, 4);
+ } else {
+ int x1 = (w.width - lg) / 2;
+ int x2 = (w.width + lg) / 2;
+ w.drawLine(x1 - dir, y - 1, x2 - dir, y - 1);
+ w.drawLine(x1, y, x2, y);
+ w.drawLine(x1 - dir, y + 1, x2 - dir, y + 1);
+ for (int i = 0; i < 3; i++) {
+ w.drawLine(x2 - i * dir, y, x2 - (6 + i) * dir, y - 4);
+ w.drawLine(x2 - i * dir, y, x2 - (6 + i) * dir, y + 4);
+ }
+ }
+}
+
void dessineExplosion(DrawingWindow& w, float rx, float ry)
{
- const int maxray = rtowX(w, 5) - rtowX(w, 0);
+ const int maxray = rtowX(w, 3) - rtowX(w, 0);
// 1/2 rouge -> rouge -> jaune
const int x = rtowX(w, rx);
const int y = rtowY(w, ry);
w.setColor("white");
for (i = 0; i < maxray; i++) {
w.drawCircle(x, y, i);
- w.msleep(20);
+ w.msleep(10);
}
w.fillCircle(x, y, maxray - 1);
}
void jeu(DrawingWindow& w)
{
- dessineTerrain(w, frand(largeurMin, largeurMax),
- frand(hauteurMin, hauteurMax));
+ const float largeurMont = frand(largeurMin, largeurMax);
+ const float hauteurMont = frand(hauteurMin, hauteurMax);
+
+ dessineTerrain(w, largeurMont, hauteurMont);
dessineChateau(w, positionChateau1);
dessineChateau(w, positionChateau2);
- while (1)
- dessineExplosion(w, frand(rXMin, rXMax), frand(rYMin, rYMax));
-
+ const float g = 9.81;
+ const float k = 0.005;
+ const float dt = 0.1;
+ const float wnd = frand(-30, 30);
+ const float x0 = positionChateau1 + 8;
+ const float y0 = 8;
+
+ dessineVent(w, wnd);
+
+ while (1) {
+ const float v0 = frand(10, 100);
+ const float alpha = deg2rad(frand(10, 90));
+
+ float x = x0;
+ float y = y0;
+ float vx = v0 * cos(alpha);
+ float vy = v0 * sin(alpha);
+ w.setColor("black");
+ bool collision = false;
+ do {
+ int wx = rtowX(w, x);
+ int wy = rtowY(w, y);
+ w.fillCircle(wx, wy, 2);
+
+ float vxr = vx - wnd;
+ float kvr = -k * sqrt(vxr * vxr + vy * vy);
+ float ax = kvr * vxr;
+ float ay = kvr * vy - g;
+ x += vx * dt;
+ y += vy * dt;
+ vx += ax * dt;
+ vy += ay * dt;
+
+ w.msleep(10);
+ w.setColor("white");
+ w.fillCircle(wx, wy, 2);
+ w.setColor("black");
+ w.drawPoint(wx, wy);
+
+ if ((y <= 0) ||
+ (y < hauteurChateau
+ && ((positionChateau1 - largeurChateau <= x
+ && positionChateau1 + largeurChateau >= x) ||
+ (positionChateau2 - largeurChateau <= x
+ && positionChateau2 + largeurChateau >= x)))) {
+ collision = true;
+ } else {
+ float h = hauteurMontagne(largeurMont, hauteurMont, x);
+ if (h > 0 && y < h)
+ collision = true;
+ }
+ } while (!collision);
+ dessineExplosion(w, x, y);
+ }
}
int main(int argc, char *argv[])
Données
-------
+g constante de gravitation
+k coefficient de frottement
+dt intervalle de temps de la simulation
+wnd vitesse du vent
x0, y0 position initiale
v0 vitesse initiale
alpha angle de tir
-g constante de gravitation
-k coefficient de frottement
-w vitesse du vent
Variables
---------
+fx(t) composante x de la force de frottement à l'instant t
+fy(t) composante y de la force de frottement à l'instant t
+
+ax(t) composante x de l'accélération à l'instant t
+ay(t) composante y de l'accélération à l'instant t
+
x(t) composante x de la position à l'instant t
y(t) composante y de la position à l'instant t
vy(t) composante y de la vitesse à l'instant t
vrx(t) composante x de la vitesse relative à l'instant t
- = vx(t) - w
+ = vx(t) - wnd
vry(t) composante y de la vitesse relative à l'instant t
= vy(t)
|vr(t)| vitesse relative à l'instant t
= SQRT(vrx(t)^2 + vry(t)^2)
-ax(t) composante x de l'accélération à l'instant t
-ay(t) composante y de l'accélération à l'instant t
-
-fx(t) composante x de la force de frottement
-fy(t) composante y de la force de frottement
-
Initialisation
--------------
+ax(0) = 0
+ay(0) = 0
+
x(0) = x0
y(0) = y0
vx(0) = v0 cos(alpha)
vy(0) = v0 sin(alpha)
-ax(0) = 0
-ay(0) = 0
-
Mise à jour
-----------
-x(t+1) = x(t) + vx(t)
-y(t+1) = y(t) + vy(t)
-
-vx(t+1) = vx(t) + ax(t)
-vy(t+1) = vy(t) + ay(t)
-
+|f(t)| = -k |vr(t)| vr(t)
fx(t) = -k |vr(t)| vrx(t)
- = -k |vr(t)| (vx(t) - w)
- = -k SQRT((vx(t) - w)^2 + vy(t)^2) vx(t)
+ = -k |vr(t)| (vx(t) - wnd)
+ = -k SQRT((vx(t) - wnd)^2 + vy(t)^2) (vx(t) - wnd)
fy(t) = -k vr(t) vry(y)
= -k vr(t) vy(t)
- = -k SQRT((vx(t) - w)^2 + vy(t)^2) vy(t)
+ = -k SQRT((vx(t) - wnd)^2 + vy(t)^2) vy(t)
+
+ax(t) = fx(t)
+ = -k SQRT((vx(t) - wnd)^2 + vy(t)^2) (vx(t) - wnd)
+ay(t) = fy(t) - g
+ = -k SQRT((vx(t) - wnd)^2 + vy(t)^2) vy(t) - g
-ax(t+1) = fx(t)
- = -k SQRT((vx(t) - w)^2 + vy(t)^2) vx(t)
-ay(t+1) = -g + fy(t)
- = -g - k SQRT((vx(t) - w)^2 + vy(t)^2) vy(t)
+x(t+1) = x(t) + vx(t) dt
+y(t+1) = y(t) + vy(t) dt
+
+vx(t+1) = vx(t) + ax(t) dt
+vy(t+1) = vy(t) + ay(t) dt
Algorithme
----------
Données
- ax0 ax(t)
- ay0 ay(t)
- vx0 vx(t)
- vy0 vy(t)
x0 x(t)
y0 y(t)
+ vx0 vx(t)
+ vy0 vy(t)
Résultats
- ax1 ax(t+1)
- ay1 ay(t+1)
- vx1 vx(t+1)
- vy1 vy(t+1)
x1 x(t+1)
y1 y(t+1)
+ vx1 vx(t+1)
+ vy1 vy(t+1)
Intermédiaires
+ vxr vx(t) - wnd
kvr - k × vr(t)
+ ax ax(t)
+ ay ay(t)
Algorithme
- x1 <- x0 + v0
- y1 <- y0 + v0
- vx1 <- vx0 + ax0
- vy1 <- vy0 + ay0
- kvr <- k × SQRT((vx0 - w)^2 + vy0^2)
- ax1 <- kvr × vx0
- ay1 <- kvr × vy0 - g
+ vxr <- vx0 - wnd
+ kvr <- -k × SQRT(vxr × vxr + vy0 × vy0)
+ ax <- kvr × vxr
+ ay <- kvr × vy0 - g
+
+ x1 <- x0 + vx0 × dt
+ y1 <- y0 + vy0 × dt
+ vx1 <- vx0 + ax0 × dt
+ vy1 <- vy0 + ay0 × dt