Сложение графиков изменения значений
У меня есть устройства в которых есть некие "слоты", в которых есть графики изменения значения этих "слотов" 
дальше, у меня есть, назовем подсцены, это комбинация разных устройств с разными "слотами" и разными графиками в них
и, наконец, у меня есть сцена, само собой это комбинация подсцен 
мне нужно сложить сцену воедино, принципы сложения графиков сцены:
- если устройство встречается только один раз среди всех подсцен сцены, то графикb его слотов просто продлеваются на всю продолжительность сцены с крайних точек (зеленые линии)

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

- самый сложный вариант, когда одно устройство может встретиться в нескольких подсценах на разных линиях
в таком случае места пересечения подсцен (синий прямоугольник) должны сложиться по определенному типу (умножение, вычитание, максимальное значение), вот например максимальное значение
и заполнить пустоты (приоритет зависит от линии) еще пример, допустим просто вычитание, то есть из нижней вычитаем значения верхней

В общем то вопрос как это вообще сделать, я думал идти циклом по убыванию линий, складывать и продлевать графики линий, но в таком случае на итоговый график будет влиять продление, а оно должно добавляться только в итоге, если идти циклом по подсценам, то какие действия нужны, чтобы сложить точки в местах пересечения и потом продлить последнюю до следующей подсцены на этой линии? в общем пока что, как не пытался, сложить просто в тупую графики получается, а вот с определенными принципами, пока затрудняюсь, пишу это все на 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 шт):
Вместо "цикл по подсценам" я бы циклом верхнего уровня объявил цикл по оси времени. Как-то так:
- Цикл по моментам времени
- В каждый момент определяем список сцен
- Цикл по сценам
- Для каждой сцены определяем список устройств в данный момент
- Цикл по устройствам
- Определяем тип расчёта для данного устройства: "суммирование", "продолжение" и т.д.
- Выполняем расчёт требуемого типа.