Сложение графиков изменения значений

У меня есть устройства в которых есть некие "слоты", в которых есть графики изменения значения этих "слотов"

дальше, у меня есть, назовем подсцены, это комбинация разных устройств с разными "слотами" и разными графиками в них

и, наконец, у меня есть сцена, само собой это комбинация подсцен

мне нужно сложить сцену воедино, принципы сложения графиков сцены:

  1. если устройство встречается только один раз среди всех подсцен сцены, то графикb его слотов просто продлеваются на всю продолжительность сцены с крайних точек (зеленые линии)
  2. если устройство встречается в двух или более подсценах в одной линии, графики одинаковых слотов суммируются, и продлеваются - начало первой подсцены до начала сцены (оранжевая линия), конец до следующей сцены (зеленая линия), и конец последней до конца сцены (розовая линия)
  3. самый сложный вариант, когда одно устройство может встретиться в нескольких подсценах на разных линиях в таком случае места пересечения подсцен (синий прямоугольник) должны сложиться по определенному типу (умножение, вычитание, максимальное значение), вот например максимальное значение введите сюда описание изображения и заполнить пустоты (приоритет зависит от линии) еще пример, допустим просто вычитание, то есть из нижней вычитаем значения верхнейвведите сюда описание изображения

В общем то вопрос как это вообще сделать, я думал идти циклом по убыванию линий, складывать и продлевать графики линий, но в таком случае на итоговый график будет влиять продление, а оно должно добавляться только в итоге, если идти циклом по подсценам, то какие действия нужны, чтобы сложить точки в местах пересечения и потом продлить последнюю до следующей подсцены на этой линии? в общем пока что, как не пытался, сложить просто в тупую графики получается, а вот с определенными принципами, пока затрудняюсь, пишу это все на qt, график это QVector. Поможет что угодно, даже примерный алгоритм или просто код в формате

"цикл по подсценам" {
   "цикл по устройствам" {
        "цикл по слотам" {
             "если нет графика, добавляем"
             "если есть, ищем пересечение и складываем, если нашли"
        }
   }
}

Проблему с циклам решил собственно так, как и хотел

 scene_graphic.clear();

 QVector<SubScene*> subscenes(subscenes_);

 std::sort(subscenes.begin(), subscenes.end(), [&](SubScene *ss1, SubScene *ss2) { return ss1->GetLineIndex() > ss2->GetLineIndex(); });

 for (int i(line_count_ - 1); i >= 0; i--) {

   Q_FOREACH(SubScene *a_subscene, subscenes) {

     if (a_subscene->GetLineIndex() == i)
       Q_FOREACH(Device *a_device, a_subscene->GetDevices())
         Q_FOREACH(Slot *a_slot, *a_device->GetSlots())
           if (!a_slot->GetGraphic().isEmpty()) {

             QVector<QPoint> slot_graphic(a_slot->GetGraphic());
             QVector<QPoint> low_graphic(scene_graphic.value(a_device, QMap<a_slot, QVector<QPoint>>()).value(a_slot, QVector<QPoint>>({ QPoint(start, -1), QPoint(start + duration, -1) })));
             scene_graphic[a_device].insert(a_slot, CombineGraphics(low_graphic, slot_graphic, a_subscene->GetOverlayType()));
           }
   }
 }

осталось сделать очень умный метод CombineGraphics, в совете или подсказке все еще нуждаюсь

QVector<QPoint> CombineGraphics(QVector<QPoint> low_priority, QVector<QPoint> high_priority, Overlay type)
{
 QVector<QPoint> combined;

 for (int low_index(1); low_index < low_priority.count(); low_index++) {
   QPoint low_point_left(low_priority.at(low_index - 1)), low_point_right(low_priority.at(low_index)); // отрезок нижнего графика

   for (int high_index(0); high_index < high_priority.count(); high_index++) {
     QPoint high_point_left(high_priority.at(high_index)), high_point_right(high_priority.at(high_index)); // отрезок верхнего графика

     if (если отрезки пересекаются или находятся друг над другом(а по идее верхний всегда каким либо образом входит в нижний, потому что нижний от начала и до конца выставлен условными точками -1 по Y вместо которых подставляются 0) {

       считаем все по типу сложения и добавляем точку в combined;
     }
   }
 }

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

Автор решения: Sergey

Вместо "цикл по подсценам" я бы циклом верхнего уровня объявил цикл по оси времени. Как-то так:

  1. Цикл по моментам времени
  2. В каждый момент определяем список сцен
  3. Цикл по сценам
  4. Для каждой сцены определяем список устройств в данный момент
  5. Цикл по устройствам
  6. Определяем тип расчёта для данного устройства: "суммирование", "продолжение" и т.д.
  7. Выполняем расчёт требуемого типа.
→ Ссылка