Разделить прямоугольник на равные части

Я опять туплю (это моё нормальное состояние).
Написал код, который, как мне казалось, должен делить прямоугольник на равные отрезки и закрашивать их.

		protected override void OnPaint(PaintEventArgs e)
		{
            Rectangle rectangle = Deflate(e.ClipRectangle, 1, 1);
            Brush brushBkg = new SolidBrush(BackColor);
            e.Graphics.FillRectangle(brushBkg, rectangle);
            if (Items != null)
            {
                int itemCount = Items.Count();
                if (itemCount > 0)
                {
					int itemWidth = Width / itemCount;
                    int iter = 0;
                    foreach (MultipleProgressBarItem item in Items)
                    {
						Rectangle clipRect = Deflate(e.ClipRectangle, 1, 1);
                        e.Graphics.SetClip(e.ClipRectangle);
                        Rectangle rect;
                        int itemPositionX = itemWidth * iter;
                        int n = item.Value * itemWidth / item.MaxValue;
                        if (n > 0)
                        {
                            rect = new Rectangle(itemPositionX, 0, n, rectangle.Height);
                            Brush brush = new SolidBrush(item.BackgroundColor);
                            e.Graphics.FillRectangle(brush, rect);
                            brush.Dispose();
                        }
                        rect = new Rectangle(itemPositionX, 0, itemWidth, rectangle.Height);
                        e.Graphics.DrawRectangle(Pens.Black, rect);
                        e.Graphics.SetClip(rect);
                        e.Graphics.DrawRectangle(Pens.Black, clipRect);

                        Brush brushText = new SolidBrush(ForeColor);
                        string title = !string.IsNullOrEmpty(item.Title) && !string.IsNullOrWhiteSpace(item.Title) ?
                            item.Title : $"Item №{iter}";
                        SizeF size = e.Graphics.MeasureString(title, Font);
                        float y = Height / 2.0f - size.Height / 2.0f;
                        e.Graphics.DrawString(item.Title, Font, brushText, itemPositionX + 4.0f, y);
                        brushText.Dispose();
						
                        iter++;
                    }
                }
            }
            else
            {
                e.Graphics.DrawRectangle(Pens.Black, rectangle);
            }

            brushBkg.Dispose();
        }

Но происходит что-то странное.


То есть, при шести и более добавленных элементах начинается что-то странное. Я не могу это объяснить. Как будто числа нацело не делятся. Понятно, что совсем нацело они почти никогда не разделятся. Но мне казалось, что погрешность такого деления должна быть в один пиксель, а не в километр.
Возможно, что ошибка не в делении, а в чём-то ещё. Но я её не вижу :man_shrugging:

itemWidth

сделай не целым (а типом с плавающей точкой).

int itemPositionX = itemWidth * iter;

Вот здесь, один itemWidth теряет не более 1 пиксела, но когда iter большой, то теряется несколько пикселов. Например 0.3 это ошибка, увеличим её в 12 раз и вот потеряно 4 пиксела.
Поэтому деление при расчёте itemWidth надо использовать нецелочисленное, чтобы позиция рассчитывалась точнее.

int itemPositionX = Math.Floor(itemWidth * iter);

Это у любых людей основное состояние. Если у кого-то что-то быстро получается, то только потому, что он специально на такие действия натренировался. Например шахматисты, которые блиц играют, они просто запомнинают комбинации и начала партий.

Странно :thinking: Я когда-то давно уже писал что-то подобное, но не помню такой проблемы. Может там элементов мало было.

Кстати, косяк нашёл

e.Graphics.DrawString(item.Title, Font, brushText, itemPositionX + 4.0f, y);

а надо так:

e.Graphics.DrawString(title, Font, brushText, itemPositionX + 4.0f, y);