2020-02-16 04:57:03 +00:00
|
|
|
|
/*Uses $LK,"fixed-point",A="FI:::/Demo/Lectures/FixedPoint.CC"$ arithmetic
|
2020-02-15 20:01:48 +00:00
|
|
|
|
because it used to be faster than floating
|
2020-02-16 04:57:03 +00:00
|
|
|
|
point. See $LK,"::/Demo/Lectures/FixedPoint.CC"$.
|
2020-02-15 20:01:48 +00:00
|
|
|
|
|
|
|
|
|
The decimal place is between
|
|
|
|
|
bits 31 and 32.
|
|
|
|
|
*/
|
|
|
|
|
|
2020-12-23 23:27:18 +00:00
|
|
|
|
#define BALLS_NUM 64
|
|
|
|
|
#define BALL_RADIUS 5
|
2020-02-15 20:01:48 +00:00
|
|
|
|
|
2020-12-23 23:27:18 +00:00
|
|
|
|
I64 ball_x[BALLS_NUM], ball_y[BALLS_NUM], ball_velocity_x[BALLS_NUM], ball_velocity_y[BALLS_NUM];
|
2020-02-15 20:01:48 +00:00
|
|
|
|
|
2020-12-23 23:27:18 +00:00
|
|
|
|
U0 DrawIt(CTask *, CDC *dc)
|
2020-02-15 20:01:48 +00:00
|
|
|
|
{
|
2020-02-20 23:40:10 +00:00
|
|
|
|
I64 i;
|
2020-12-23 23:27:18 +00:00
|
|
|
|
|
|
|
|
|
dc->color = RED;
|
|
|
|
|
for (i = 0; i < BALLS_NUM; i++)
|
|
|
|
|
GrCircle(dc, ball_x[i].i32[1], ball_y[i].i32[1], BALL_RADIUS);
|
2020-02-15 20:01:48 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/****
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$SP,"",BI=1$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Initial and final velocity vects
|
|
|
|
|
with normal and tangential components.
|
|
|
|
|
All masses are ident, so they
|
|
|
|
|
have been dropped from the equations.
|
|
|
|
|
|
|
|
|
|
Conservation of Momentum:
|
|
|
|
|
|
|
|
|
|
V1$SY,3$it$SY,0$+V2$SY,3$it$SY,0$=V1$SY,3$ft$SY,0$+V2$SY,3$ft$SY,0$
|
|
|
|
|
|
|
|
|
|
V1$SY,3$in$SY,0$+V2$SY,3$in$SY,0$=V1$SY,3$fn$SY,0$+V2$SY,3$fn$SY,0$
|
|
|
|
|
|
|
|
|
|
Conservation of Energy:
|
|
|
|
|
|
|
|
|
|
|V1$SY,3$i$SY,0$|$SY,-3$2$SY,0$+|V2$SY,3$i$SY,0$|$SY,-3$2$SY,0$=|V1$SY,3$f$SY,0$|$SY,-3$2$SY,0$+|V2$SY,3$f$SY,0$|$SY,-3$2$SY,0$
|
|
|
|
|
****/
|
|
|
|
|
|
|
|
|
|
U0 AnimateTask(I64)
|
|
|
|
|
{
|
2020-12-23 23:27:18 +00:00
|
|
|
|
CTask *task = Fs->parent_task;
|
|
|
|
|
I64 i, j, h, v, distdist,
|
|
|
|
|
dia = (2 * BALL_RADIUS) << 32,
|
|
|
|
|
diadia = SqrI64(2 *BALL_RADIUS) << 32,
|
|
|
|
|
delta_x, delta_y, v_t1, v_n1, v_t2, v_n2;
|
|
|
|
|
F64 dist;
|
|
|
|
|
|
|
|
|
|
while (TRUE)
|
|
|
|
|
{
|
|
|
|
|
h = task->pix_width;
|
|
|
|
|
v = task->pix_height;
|
|
|
|
|
for (i = 0; i < BALLS_NUM; i++)
|
|
|
|
|
{
|
|
|
|
|
ball_x[i] += ball_velocity_x[i];
|
|
|
|
|
ball_y[i] += ball_velocity_y[i];
|
|
|
|
|
if (ball_x[i] < BALL_RADIUS << 32)
|
|
|
|
|
{
|
|
|
|
|
ball_velocity_x[i] *= -1;
|
|
|
|
|
ball_x[i] = BALL_RADIUS << 32;
|
2020-02-20 23:40:10 +00:00
|
|
|
|
}
|
2020-12-23 23:27:18 +00:00
|
|
|
|
if (ball_x[i] >= (h - BALL_RADIUS) << 32)
|
|
|
|
|
{
|
|
|
|
|
ball_velocity_x[i] *= -1;
|
|
|
|
|
ball_x[i] = (h - BALL_RADIUS) << 32;
|
2020-02-20 23:40:10 +00:00
|
|
|
|
}
|
2020-12-23 23:27:18 +00:00
|
|
|
|
if (ball_y[i] < BALL_RADIUS << 32)
|
|
|
|
|
{
|
|
|
|
|
ball_velocity_y[i] *= -1;
|
|
|
|
|
ball_y[i] = BALL_RADIUS << 32;
|
2020-02-20 23:40:10 +00:00
|
|
|
|
}
|
2020-12-23 23:27:18 +00:00
|
|
|
|
if (ball_y[i] >= (v - BALL_RADIUS) << 32)
|
|
|
|
|
{
|
|
|
|
|
ball_velocity_y[i] *= -1;
|
|
|
|
|
ball_y[i] = (v - BALL_RADIUS) << 32;
|
2020-02-20 23:40:10 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2020-12-23 23:27:18 +00:00
|
|
|
|
for (i = 0; i < BALLS_NUM; i++)
|
|
|
|
|
{
|
|
|
|
|
for (j = i + 1; j < BALLS_NUM; j++)
|
|
|
|
|
{
|
|
|
|
|
delta_x = ball_x[i] - ball_x[j];
|
|
|
|
|
delta_y = ball_y[i] - ball_y[j];
|
2020-02-20 23:40:10 +00:00
|
|
|
|
|
|
|
|
|
//We shift 16 because multiplying
|
|
|
|
|
//two 32 shifted would yield 64 shifted
|
|
|
|
|
//and we want a 32 shifted res.
|
2020-12-23 23:27:18 +00:00
|
|
|
|
distdist = SqrI64(delta_x >> 16) + SqrI64(delta_y >> 16);
|
2020-02-20 23:40:10 +00:00
|
|
|
|
|
|
|
|
|
//We work with square instead of sqrt
|
|
|
|
|
//to avoid unnecessarily calculating
|
|
|
|
|
//square heads (They are slow.)
|
2020-12-23 23:27:18 +00:00
|
|
|
|
if (distdist && distdist <= diadia)
|
|
|
|
|
{
|
|
|
|
|
dist = Sqrt(distdist); //shifted 16 bits
|
|
|
|
|
delta_x /= dist; //shifted 16
|
|
|
|
|
delta_y /= dist;
|
|
|
|
|
|
|
|
|
|
v_t1 = (ball_velocity_x[i] >> 16 * delta_y - ball_velocity_y[i] >> 16 * delta_x) >> 16;
|
|
|
|
|
v_n1 = (ball_velocity_x[i] >> 16 * delta_x + ball_velocity_y[i] >> 16 * delta_y) >> 16;
|
|
|
|
|
v_t2 = (ball_velocity_x[j] >> 16 * delta_y - ball_velocity_y[j] >> 16 * delta_x) >> 16;
|
|
|
|
|
v_n2 = (ball_velocity_x[j] >> 16 * delta_x + ball_velocity_y[j] >> 16 * delta_y) >> 16;
|
|
|
|
|
|
|
|
|
|
if (ball_velocity_x[i] >> 16 * ball_velocity_x[j] >> 16 +
|
|
|
|
|
ball_velocity_y[i] >> 16 * ball_velocity_y[j] >> 16 <= 0)
|
|
|
|
|
{
|
|
|
|
|
ball_velocity_x[i] = v_t1 * delta_y - v_n1 * delta_x;
|
|
|
|
|
ball_velocity_y[i] = -v_t1 * delta_x - v_n1 * delta_y;
|
|
|
|
|
ball_velocity_x[j] = v_t2 * delta_y - v_n2 * delta_x;
|
|
|
|
|
ball_velocity_y[j] = -v_t2 * delta_x - v_n2 * delta_y;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ball_velocity_x[i] = v_t1 * delta_y + v_n2 * delta_x;
|
|
|
|
|
ball_velocity_y[i] = -v_t1 * delta_x + v_n2 * delta_y;
|
|
|
|
|
ball_velocity_x[j] = v_t2 * delta_y + v_n1 * delta_x;
|
|
|
|
|
ball_velocity_y[j] = -v_t2 * delta_x + v_n1 * delta_y;
|
2020-02-20 23:40:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//Correct for overlap
|
2020-12-23 23:27:18 +00:00
|
|
|
|
dist = 0x10000 + (dia / 0x10000 - dist) / 2;
|
|
|
|
|
ball_x[i] += dist * delta_x;
|
|
|
|
|
ball_y[i] += dist * delta_y;
|
|
|
|
|
ball_x[j] -= dist * delta_x;
|
|
|
|
|
ball_y[j] -= dist * delta_y;
|
2020-02-20 23:40:10 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
Sleep(1);
|
2020-02-15 20:01:48 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
U0 Init()
|
|
|
|
|
{
|
2020-02-20 23:40:10 +00:00
|
|
|
|
I64 i;
|
2020-12-23 23:27:18 +00:00
|
|
|
|
|
|
|
|
|
for (i = 0; i < BALLS_NUM; i++)
|
|
|
|
|
{
|
|
|
|
|
ball_x[i] = (RandU16 % (Fs->pix_width - BALL_RADIUS * 2) + BALL_RADIUS) << 32;
|
|
|
|
|
ball_y[i] = (RandU16 % (Fs->pix_height - BALL_RADIUS * 2) + BALL_RADIUS) << 32;
|
|
|
|
|
ball_velocity_x[i] = RandI32 / 4;
|
|
|
|
|
ball_velocity_y[i] = RandI32 / 4;
|
2020-02-20 23:40:10 +00:00
|
|
|
|
}
|
2020-02-15 20:01:48 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
U0 Collision()
|
|
|
|
|
{
|
2020-02-20 23:40:10 +00:00
|
|
|
|
SettingsPush; //See $LK,"SettingsPush",A="MN:SettingsPush"$
|
|
|
|
|
Init;
|
2020-12-23 23:27:18 +00:00
|
|
|
|
Fs->animate_task = Spawn(&AnimateTask, NULL, "Animate",, Fs);
|
2020-02-20 23:40:10 +00:00
|
|
|
|
DocCursor;
|
|
|
|
|
DocClear;
|
2020-12-23 23:27:18 +00:00
|
|
|
|
Fs->draw_it = &DrawIt;
|
2020-03-19 20:59:53 +00:00
|
|
|
|
CharGet;
|
2020-02-20 23:40:10 +00:00
|
|
|
|
SettingsPop;
|
2020-02-15 20:01:48 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Collision;
|
|
|
|
|
|