- for (a=1; a <= state->count; a++)
- if (a != state->mouse_ball)
- for (b=1; b <= state->count; b++)
- if (a != b)
- {
- d = ((state->px[a] - state->px[b]) *
- (state->px[a] - state->px[b]) +
- (state->py[a] - state->py[b]) *
- (state->py[a] - state->py[b]));
- if (d < dee2)
- {
- state->collision_count++;
- d = sqrt(d);
- vxa = state->vx[a];
- vya = state->vy[a];
- vxb = state->vx[b];
- vyb = state->vy[b];
- nx = state->px[b] - state->px[a];
- ny = state->py[b] - state->py[a];
- if (d < -0.0001 || d > 0.0001)
- {
- cdx = nx/d;
- cdy = ny/d;
- dd = state->r[a] + state->r[b] - d;
- state->px[a] -= dd*cdx; /* just move them apart */
- state->py[a] -= dd*cdy; /* no physical rationale, sorry */
- state->px[b] += dd*cdx;
- state->py[b] += dd*cdy;
- m = sqrt (state->vx[a] * state->vx[a] +
- state->vy[a] * state->vy[a]);
- if (m < -0.0001 || m > 0.0001) /* A's velocity > 0 ? */
- {
- cosam = ((cdx * state->vx[a] + cdy * state->vy[a]) *
- state->e);
- vxa -= cdx * cosam;
- vya -= cdy * cosam; /* conserve momentum */
- vxb += cdx * cosam;
- vyb += cdy * cosam;
- }
- m = sqrt (state->vx[b] *
- state->vx[b] +
- state->vy[b] *
- state->vy[b]);
- if (m < -0.0001 || m > 0.0001)
- {
- cosam = ((cdx * state->vx[b] + cdy * state->vy[b]) *
- state->e);
- vxa += cdx * cosam;
- vya += cdy * cosam;
- vxb -= cdx * cosam;
- vyb -= cdy * cosam;
- }
- }
- state->vx[a] = vxa;
- state->vy[a] = vya;
- state->vx[b] = vxb;
- state->vy[b] = vyb;
- }
- }
+ for (a=1; a <= state->count - 1; a++)
+ for (b=a + 1; b <= state->count; b++)
+ {
+ d = ((state->px[a] - state->px[b]) *
+ (state->px[a] - state->px[b]) +
+ (state->py[a] - state->py[b]) *
+ (state->py[a] - state->py[b]));
+ dee2 = (state->r[a] + state->r[b]) *
+ (state->r[a] + state->r[b]);
+ if (d < dee2)
+ {
+ state->collision_count++;
+ d = sqrt(d);
+ dd = state->r[a] + state->r[b] - d;
+
+ cdx = (state->px[b] - state->px[a]) / d;
+ cdy = (state->py[b] - state->py[a]) / d;
+
+ /* Move each ball apart from the other by half the
+ * 'collision' distance.
+ */
+ state->px[a] -= 0.5 * dd * cdx;
+ state->py[a] -= 0.5 * dd * cdy;
+ state->px[b] += 0.5 * dd * cdx;
+ state->py[b] += 0.5 * dd * cdy;
+
+ ma = state->m[a];
+ mb = state->m[b];
+
+ vxa = state->vx[a];
+ vya = state->vy[a];
+ vxb = state->vx[b];
+ vyb = state->vy[b];
+
+ vca = vxa * cdx + vya * cdy; /* the component of each velocity */
+ vcb = vxb * cdx + vyb * cdy; /* along the axis of the collision */
+
+ /* elastic collison */
+ dva = (vca * (ma - mb) + vcb * 2 * mb) / (ma + mb) - vca;
+ dvb = (vcb * (mb - ma) + vca * 2 * ma) / (ma + mb) - vcb;
+
+ dva *= state->e; /* some energy lost to inelasticity */
+ dvb *= state->e;
+
+#if 0
+ dva += (frand (50) - 25) / ma; /* q: why are elves so chaotic? */
+ dvb += (frand (50) - 25) / mb; /* a: brownian motion. */
+#endif
+
+ vxa += dva * cdx;
+ vya += dva * cdy;
+ vxb += dvb * cdx;
+ vyb += dvb * cdy;
+
+ state->vx[a] = vxa;
+ state->vy[a] = vya;
+ state->vx[b] = vxb;
+ state->vy[b] = vyb;
+ }
+ }