Different rounding functions were also my first thought, but they only shift the problem. Let's assume our sprite's height is

**approximately** 40, so we want to get 20. It's easy to construct cases that fail:

// std::ceil()

ceil(bounds.height / 2.f) == ceil(40.0001 / 2) == 21

// std::floor()

floor(bounds.height / 2.f) == floor(39.9999 / 2) == 19

// std::trunc()

trunc(bounds.height / 2.f) == trunc(39.9999 / 2) == 19

I think the most robust solution is really to be far from the rounding "boundaries", for example by adding +0.5.

Or use integer division in the first place.

// Bad: std::round(bounds.height / 2.f)

// Good: round((bounds.height + 0.5f) / 2.f)

// We want to map both 39 and 40 to 20. This works:

round((40.0001 + 0.5) / 2) == round(20.25005) == 20

round((39.9999 + 0.5) / 2) == round(20.24995) == 20

round((38.9999 + 0.5) / 2) == round(19.75005) == 20

round((38.9999 + 0.5) / 2) == round(19.74995) == 20

If values can be negative (not relevant for sizes), we should replace

`std::round(x)` with a custom rounding function

`std::floor(x + 0.5)`, which rounds towards positive infinity independent of the sign. Otherwise, jittering will still occur for values around zero.

Hiura, taking history into account may generally be a good method to smooth such patterns, but here it looks more like symptom treatment than solving the underlying problem