Залить часть геометрической фигуры

Нужна помощь коллективного разума на тему: как залить часть произвольной замкнутой геометрической фигуры?

Usecase:

  1. Пользователь рисует фигуру (эллипс/прямоугольник/замкнутый многоугольник)
  2. Пользователь вводит процент, насколько фигура заполнена (0-100)
  3. Мы делаем .Fill() куска фигуры

Зачем это нужно: пользователю скажем, что это вид сбоку на какие-то ёмкости. Ёмкости могут быть не только прямоугольные/круглые, но и сложного сечения, отсюда и проблема.

Получить площадь замкнутого многоугольника я могу, как и вычислить условные 25% от неё. А вот дальше-то что? Примем, что у нас многоугольник выпуклый, с одним "дном". Как на картинке.

Есть мысль идти тупо по точкам внутри контура, снизу вверх и влево-вправо, пока количество залитых пикселей не будет равно 25% от площади, но на большом поле это займёт кучу времени. А Paint() вызывается довольно часто.

Ниже пример, как если-бы пользователь нарисовал фигуру и ввёл 25% заполненности (в реале заливка будет снизу вверх, я в Paint нарисовал некорректно, но смысл не меняется)

Работаю в C# WinForms .net 3.5


Ответы (1 шт):

Автор решения: A K

Общего алгоритма не знаю, но знаю, что для выпуклых фигур вполне достаточно обойти все строки изображения по порядку снизу вверх и заливать в цикле горизонтальные строчки.

Для каждой строчки заливаем цветом "серёдку" между двумя точками фигуры - крайней слева и крайней справа):

введите сюда описание изображения

Поскольку мы договорились, что фигура выпуклая, то точек будет либо две, либо (в вырожденном случае) одна.

В процессе считаем нужный процентаж от высоты фигуры, чтобы остановиться вовремя.

Если фигура начинается не с самого низа картинки (а это вероятно так будет), то сначала нужно досчитать до первой горизонтальной линии

введите сюда описание изображения

(как вариант это может быть точка):

введите сюда описание изображения

И только после этого начинать заливать.

Есть мысль идти тупо по точкам внутри контура ... но на большом поле это займёт кучу времени.

Чертите не точками, а сразу горизонтальными линиями.

→ Ссылка