Я думаю, что это один из способов сделать это.
Шаг 1 - выяснить все места, где можно разместить новый желтый прямоугольник.Без ограничения общности мы можем сохранить это как список всех возможных положений XY верхнего левого угла прямоугольника.Естественно, для такой огромной стартовой области этот список будет содержать миллионы записей, поэтому для экономии места давайте сохраним этот список в виде набора прямоугольных областей.
Например, если на нашем экране есть пиксели от X= От 0 до X = 2999 включительно, и от Y = 0 до Y = 999 включительно, и наш новый прямоугольник имеет ширину 300 пикселей и высоту 150 пикселей, верхний левый угол нашего нового прямоугольника может появляться в любой позиции от (X, Y) = (0, 0) - (2699, 849) включительно.Давайте сохраним это как квадруплет [0, 0, 2699, 849].
Теперь, когда мы помещаем каждый существующий (красный) прямоугольник на экран, некоторые из этих возможностей исключаются, так как они приводят кновый (желтый) прямоугольник, перекрывающий их.Например, если есть красный прямоугольник [1100, 200, 1199, 299], то наш желтый прямоугольник не может иметь свой левый верхний угол в любом положении от (X, Y) = (801, 51) до (1199, 299)включительно.
Итак, замените [0, 0, 2699, 849] четырьмя прямоугольными зонами, которые покрывают одну и ту же область, но оставляют зазор.Есть много способов сделать это, но вот один: [0, 0, 1199, 50], [1200, 0, 299, 2699], [0, 51, 800, 849], [801, 300, 2699, 849].
Продолжайте добавлять на экран больше красных прямоугольников.Каждый раз, добавляя один, вычитайте больше возможностей из списка (это обычно приводит к тому, что список содержит больше меньших «безопасных зон»).(Это может занять очень много времени для вашего полного экрана с 1000+ прямоугольниками на нем; если вместо этого вы начнете с только упомянутого пространства [XK, 0, X + K, H], то сравнительно немного из 1000+ будет перекрывать это, и вычисления будут выполняться намного быстрее.) Этот код должен быть написан с большой тщательностью и кучей юнит-тестов, потому что ошибок ограждения будет достаточно.
Конечный результат - полный список возможных местна экране, где можно разместить верхний левый угол вашего нового желтого прямоугольника, выраженного в виде списка прямоугольных зон.
Шаг 2: просмотрите этот список и выберите наиболее желательное место.Любая прямоугольная зона, которая фактически пересекает вашу идеальную вертикальную линию, будет иметь приоритет.Но возможно, что не будет ни одного.В этом случае вам остается выбрать наиболее предпочтительный вариант из зон, падающих слева, и зон, падающих справа от идеальной линии.Подсказка: в каждом случае необходимо учитывать только один угол каждой зоны (верхний левый угол зон справа, верхний правый угол зон слева).