javascriptmathcamerainterpolationvideo-tracking

How to smoothly track a center of mass?


I'm developing a program which tracks many small objects. They are very closely grouped for the most part.

My desire is to smoothly track the center of mass. The following code runs 60 times per second in all cases and calculates the center of mass:

let cX = 0;
let cY = 0;

for (let c of entities) {
  cX += c.x;
  cY += c.y;
}

prevCenterX = centerX;
prevCenterY = centerY;

centerX = cX / entities.length;
centerY = cY / entities.length;

That is, I simply add up all the positions of each entity and then divide by the entity count in order to get the x and y coordinate of the center of the mass of objects.

Then in the rendering code, I simply do this:

camera.x = lerp(prevCenterX, centerX, alpha);
camera.y = lerp(prevCenterY, centerY, alpha);

Where alpha is the percentage (from 0.0 to 1.0) of the tick that we are through (because the simulation only updates 60 times per second, but the user's monitor may have any sort of refresh rate). The rendering code in my case runs 165 times per second.

Anyways, this works perfectly in 99% of cases. The issue is that when an entity is either gained or lost, then the centerX and centerY very quickly change, which causes the camera to do a jarring jump the next frame, which is very visually unpleasant.

Is there a way to counteract this? My desire is for the camera to always move smoothly. I have been trying to figure out a solution to this for weeks now, but every one of my attempted solutions fails. Is this more tricky than I think, or am I missing something obvious?


Solution

  • You can try simple smoothing of center position, for example, with IIR filter:

    centerX = centerX * (1-t) + t * cX / entities.length;
    centerY = centerY * (1-t) + t * cY / entities.length;
    

    where t is coefficient like 0.1 or 0.5 (depending on needed smoothing degree).

    If result looks better, but is still unpleasant, consider using of Kalman filter. (More complex, but is widely used in object tracking. While math background looks very tangled, you can find consize implementations).