Название: Вычислить кадр мувика Отправлено: Igors от Май 22, 2017, 07:08 Добрый день
Задан диапазон кадров R[2], напр [5..10] (играть с 5-го по 10-й включительно) или [10..5] (играть в обратном порядке с 10-го по 5-й). После того как достигнут последний или первый кадр диапазона мувик должен проигрываться в обратном порядке, напр 5, 6, 7, 8, 9, 10, 9, 8, 7, 6, 5, 6... Требуется ф-ция которая возвращает любой следующий кадр от текущего Код Для последовательности кадров выше NextFrame(9, 1) = 10 NextFrame(9, 2) = 9 Спасибо Название: Re: Вычислить кадр мувика Отправлено: deMax от Май 22, 2017, 10:06 Набил на скорую руку, вроде работает
Код: int NextFrame(int currentFrame, int step, int x0, int x1) { Название: Re: Вычислить кадр мувика Отправлено: deMax от Май 22, 2017, 10:22 если у вас может быть отрицательной позиция кадра, добавить после строки
posCurrentFrame -= (posCurrentFrame / sizeWithBack) * sizeWithBack; строку: if(posCurrentFrame<0) posCurrentFrame += sizeWithBack; p.s. имхо, я бы разбил на 2 функции: int nextFrame = pos2frame( frame2pos( currentFrame ) + step ) а если видео нужно гонять в цикле, то итератор подошел бы class zzzz{int data, direction ... int operator ++() { data += direction; if(direction == x0 || direction == x1) direction = -direction; return data; } } // direction = +1 / -1, для x0==x1 direction=0; Название: Re: Вычислить кадр мувика Отправлено: m_ax от Май 22, 2017, 13:28 Цитировать Набил на скорую руку, вроде работает Можно попроще Код
Цитировать а если видео нужно гонять в цикле, то итератор подошел бы Итераторы здесь, это больная тема :)Название: Re: Вычислить кадр мувика Отправлено: deMax от Май 22, 2017, 13:49 Можно попроще не спорю, но "int x = currentFrame - min;" некорректно, так как в условии " или [10..5] (играть в обратном порядке с 10-го по 5-й)"нет проверки на диапазон, да и вообще она неверный результат на тесте выводит. int n = trunc(double(step)/T); лучше floor - для отрицательных значений(из условия неясно могут ли кадры быть отрицательными) у trunc результат неверный будет Вообще переводить в double, лишние операции, мой вариант проще :) Название: Re: Вычислить кадр мувика Отправлено: m_ax от Май 22, 2017, 13:54 Цитировать но "int x = currentFrame - min;" некорректно, так как в условии " или [10..5] (играть в обратном порядке с 10-го по 5-й)" Проверки на принадлежность к диапазону и на обратный порядок - пускай igors делает) Я чисто концепт обозначил)Цитировать она неверный результат на тесте выводит. На каком именно тесте?Название: Re: Вычислить кадр мувика Отправлено: Igors от Май 22, 2017, 14:07 В предложенные решения пока глубоко не вникал (просто это трудно несмотря на внешнюю простоту задачки), но хочу обратить Ваше внимание на такую деталь
5, 6, 7, 8, 9, 10, 9, 8, 7, 6, 5, 6... А "от какого" 9? Не вижу как это учтено в Ваших исходниках. Вводить доп переменные не запрещено, можно и просто переставить диапазон R. Но все равно спасибо за участие :)... NextFrame(9, 1) = 10 NextFrame(9, 2) = 9 Итераторы здесь, это больная тема :) Здесь как раз нужен прямой доступ. Если мувик не укладывается в заданный FPS и включена стандартная опция "drop frames", то кадры должны пропускаться. Пример: на данный момент должно быть показано уже 10 кадров, а успели всего 6 - грузим 4-й кадр от текущего. Собсно за этим и нужна такая ф-ция.Да, и в "геометрии" там задачка давно плачет по Вашему академическому образованию :) Название: Re: Вычислить кадр мувика Отправлено: deMax от Май 22, 2017, 14:08 На каком именно тесте? for(int i=-20; i<20; ++i) qDebug() << NextFrame(9,i,5,10); // for(int i=-20; i<20; ++i) qDebug() << NextFrame(9,i,10,5); // можно с нуля начинать, но так как автор не указал допустимы ли отрицательная позиция кадра, я начал с -20. Мой пример выводит корректно, хотя я бы сам его переписал. х0,х1 диапазон 5 и 10, или 10 и 5 например(плохие имена переменных) А "от какого" 9? Не вижу как это учтено в Ваших исходниках. Вводить доп переменные не запрещено, можно и просто переставить диапазон R. Но все равно спасибо за участие :) [5 6 7 8 9 10] 9 8 7 6 5 6 7 ... - из основного диапазона (в скобках []) 9-ку брал, можно аргумент ввести если из следующего перевернутого братьif(isReverseFind==true) posCurrentFrame = sizeWithBack - posCurrentFrame; Название: Re: Вычислить кадр мувика Отправлено: Igors от Май 23, 2017, 12:42 Мой вариант
Код
Название: Re: Вычислить кадр мувика Отправлено: m_ax от Май 23, 2017, 20:34 Цитировать Да, и в "геометрии" там задачка давно плачет по Вашему академическому образованию Ну так Вы бы её академически сформулировали бы, что ли)А так у меня сейчас голова забита совершенно другими задачками) Да и сессия на носу) Название: Re: Вычислить кадр мувика Отправлено: deMax от Май 24, 2017, 10:25 Мой вариант А если R[10,5], то фрейм 8 окажеться на -2 месте, и следующий кадр укажет на 9, а не на 7.int relF = qAbs(curFrame - R[0]) + step; // frame to relative Моя программа выводит: for(int i=-20; i<20; ++i) qDebug() << NextFrame(9,i,5,10); 9 10 9 8 7 6 5 6 7 8 9 10 9 8 7 6 5 6 7 8 9 10 9 8 7 6 5 6 7 8 9 10 9 8 7 6 5 6 7 8 for(int i=-20; i<20; ++i) qDebug() << NextFrame(9,i,10,5); 9 8 7 6 5 6 7 8 9 10 9 8 7 6 5 6 7 8 9 10 9 8 7 6 5 6 7 8 9 10 9 8 7 6 5 6 7 8 9 10 А вот данная программа выводит: -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 9 8 7 6 5 5 6 7 8 9 10 9 8 7 6 5 5 6 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 6 7 8 9 10 10 9 8 7 6 5 6 7 8 9 Ладно, пусть i<0 это наверное не нужно(кадры, возможно, не могут быть отрицательными), но вот 5 5 подряд вроде не должно быть? или я не понял что должна функция делать? Название: Re: Вычислить кадр мувика Отправлено: Igors от Май 24, 2017, 13:13 Ладно, пусть i<0 это наверное не нужно(кадры, возможно, не могут быть отрицательными), но вот 5 5 подряд вроде не должно быть? или я не понял что должна функция делать? Параметр step (у Вас "i") это не кадр, а смещение кадра относительно текущего. Пример currentFrame = 5; // текущий кадр мувика = 5 step = 2; // на какое число кадров сдвинуться? (на 2 собаки вперед) Т.е. какой кадр мувика (лежащий в диапазоне R) станет текущим? При этом еcли смещение = периоду то следующий кадр будет тем же (напр 5). Отрицательное смещение не рассматривается - время-то идет только вперед :) Название: Re: Вычислить кадр мувика Отправлено: deMax от Май 24, 2017, 14:50 Это понятно, просто при "i < -curFramePos" позиция в последовательности станет отрицательной.
>> Отрицательное смещение не рассматривается - время-то идет только вперед Вам виднее, тогда uint step ;) мне не известно и не интересно зачем вам гонять фрагмент видео. Я только написал рабочее решение для int step, остальные программы работают неправильно :P Возможно нет смысла проверять currentFrame на принадлежность диапазону(уже проверенно). Название: Re: Вычислить кадр мувика Отправлено: m_ax от Май 25, 2017, 13:15 Цитировать остальные программы работают неправильно Всё работает как надо) Слегка подправил для для обратного порядка и на проверку на диапазон. Код По моему это гораздо проще и нагляднее) Название: Re: Вычислить кадр мувика Отправлено: deMax от Май 25, 2017, 14:07 m_ax
теперь работает, но есть мелкие придирки 1. uint step - для отрицательных чисел у вас алгоритм вычисляет неправильно(автору не нужно) 2. при x0 == x1 у вас T == 0 -> %T сгенерирует ошибку и программа упадет без обработчика 3. Названия переменных T -> cycleSize, toFrame -> pos2numFrame, x -> pos 4. имхо, через деление выражение ((x + step % T) % T) быстрее будет 5. std::min и max тоже можно убрать повысив производительность, if((sign>0 && currentFrame<x0 ?&& currentFrame>x1) || (sign<0 && currentFrame<x1 ?&& currentFrame>x0)) throw std::logic_error("out of range"); Название: Re: Вычислить кадр мувика Отправлено: m_ax от Май 25, 2017, 14:43 Цитировать 1. uint step - для отрицательных чисел у вас алгоритм вычисляет неправильно(автору не нужно) Да вроде и с отрицательными работает нормально)Цитировать 2. при x0 == x1 у вас T == 0 -> %T сгенерирует ошибку и программа упадет без обработчика Да, согласен)Цитировать 4. имхо, через деление выражение ((x + step % T) % T) быстрее будет Не знаю.. думаю сейчас, это больше от компилятора зависит..Цитировать 5. std::min и max тоже можно убрать повысив производительность, if((sign>0 && currentFrame<x0 ?&& currentFrame>x1) || (sign<0 && currentFrame<x1 ?&& currentFrame>x0)) throw std::logic_error("out of range"); Здесь, думаю, тож спорно в плане производительности.. Я за читабельность в данном случае) Название: Re: Вычислить кадр мувика Отправлено: deMax от Май 25, 2017, 15:10 Да вроде и с отрицательными работает нормально) 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 10 9 8 7 6 5 6 7 8 9 10 9 8 7 6 5 6 7 8 9 18 17 16 15 14 13 12 11 10 9 18 17 16 15 14 13 12 11 10 9 8 7 6 5 6 7 8 9 10 9 8 7 6 5 6 7 8 9 10 нет ерунда, да еще за диапазон вышла. Но автор сказал не надо, значит uint Цитировать Не знаю.. думаю сейчас, это больше от компилятора зависит.. Моя функция 20млн.раз выполняется за 301мс(с поддержкой отрицательного шага 324), а ваша 640.Возможно лямбда здесь лишняя, кстати зачем она тут? имхо это сильно быстрее ваших двух остатков от деления(жирная операция) Код: posCurrentFrame -= (posCurrentFrame / sizeWithBack) * sizeWithBack; Цитировать Здесь, думаю, тож спорно в плане производительности.. Я за читабельность в данном случае) перемудрил: if((currentFrame<x0 && currentFrame<x1) || (currentFrame>x1 && currentFrame>x0)) throw std::logic_error("out of range"); но ваше std::min читается получше, хоть и медленнее. хотя, имихо, это условие вообще должно вне функции проверяться, чтобы не терять производительность), т.к. эта функция скорее всего принимает curFrame как свое возвращаемое значение. Название: Re: Вычислить кадр мувика Отправлено: m_ax от Май 25, 2017, 15:35 Цитировать нет ерунда, да еще за диапазон вышла. Я вот на таком тесте Код получил следующее: Код т.е. у вас она уходит в отрицательные значения.. Если изменить порядок диапазона: Код то обе реализации выдают ерунду ( Код
Название: Re: Вычислить кадр мувика Отправлено: deMax от Май 25, 2017, 15:58 Я написал что добавил строчку, но не выложил код
Код: inline int NextFrame(int currentFrame, int step, int x0, int x1) { Название: Re: Вычислить кадр мувика Отправлено: m_ax от Май 25, 2017, 16:00 Цитировать Моя функция 20млн.раз выполняется за 301мс(с поддержкой отрицательного шага 324), а ваша 640. У меня другие результаты - противоположные.. Может вы её в холостую запускали? Мой тест приаттачен. компилятор: gcc 4.9.2 Название: Re: Вычислить кадр мувика Отправлено: m_ax от Май 25, 2017, 19:12 Цитировать У меня другие результаты - противоположные.. Сделал вашу функцию инлайн и результаты примерно выровнялись:Код (результаты после 3-х запусков), что говорит о том, что компилятор не видит особой разницы между Код и этим Код
Название: Re: Вычислить кадр мувика Отправлено: Igors от Май 31, 2017, 10:46 Простите мою навязчивость но все же
но хочу обратить Ваше внимание на такую деталь По-прежнему не вижу где это, please "ткните носиком". 5, 6, 7, 8, 9, 10, 9, 8, 7, 6, 5, 6... А "от какого" 9? Не вижу как это учтено в Ваших исходниках.... NextFrame(9, 1) = 10 NextFrame(9, 2) = 9 Название: Re: Вычислить кадр мувика Отправлено: deMax от Июнь 01, 2017, 09:39 m_ax,
Цитировать Сделал вашу функцию инлайн и результаты примерно выровнялись: если удалить "if(posCurrentFrame<0) posCurrentFrame += sizeWithBack;" (у вас то отрицательные позиции не работают), то еще одинаковей будет.Igors Цитировать А "от какого" 9? Не вижу как это учтено в Ваших исходниках. вроде отвечал уже:[5 6 7 8 9 10] 9 8 7 6 5 6 7 ... - из основного диапазона (в скобках []) 9-ку брал, можно аргумент ввести если из следующего перевернутого брать if(isReverseFind==true) posCurrentFrame = sizeWithBack - posCurrentFrame; если нужно хранить позицию девятки (isReverse = false от x0 к x1; true от x1 к x0) Код: inline int NextFrame(int currentFrame, uint step, int x0, int x1, bool &isReverse) { но здесь итератор просится, чем эта функция с кучей параметров Название: Re: Вычислить кадр мувика Отправлено: Igors от Июнь 01, 2017, 10:36 вроде отвечал уже: А что, можно как-то "не хранить"? Не вижу как, если известен только текущий фрейм (напр 9) то однозначного рез-та не получить. Поэтому не надо "делать одолжение", давайте обсуждать только полные решения...можно аргумент ввести если из следующего перевернутого брать ...если нужно хранить позицию девятки Код: inline int NextFrame(int currentFrame, uint step, int x0, int x1, bool &isReverse) { но здесь итератор просится, чем эта функция с кучей параметров И если поступило указание "на 100 собак вперед" - то мы 100 раз зовем ++it, расписываясь в том что "просто посчитать" не умеем. Ну как-то неудобно :)Да, а мой вариант чем плох? Если нужно и отрицательное смещение (мне нет), то может проще всего свести его к положительному Код В общем, если есть желание - попинайте меня вместо m_ax :) Спасибо Название: Re: Вычислить кадр мувика Отправлено: m_ax от Июнь 01, 2017, 12:43 Цитировать И если поступило указание "на 100 собак вперед" - то мы 100 раз зовем ++it, расписываясь в том что "просто посчитать" не умеем. Ну как-то неудобно И в чём проблема?Код Это random access итератор. Название: Re: Вычислить кадр мувика Отправлено: Igors от Июнь 01, 2017, 14:19 Код Это random access итератор. Название: Re: Вычислить кадр мувика Отправлено: deMax от Июнь 01, 2017, 14:44 Итератор будет внутри хранить текущую позицию(а не номер фрейма), у него будет расчитан размер...
Вроде все тоже самое что и функция, только первая часть будет вызвана один раз в конструкторе и наружу не лезет всякая ерунда типа reverse, и при вызове функции не инлайн один аргумент - смещение (в стек будет лишний мусор копироваться). Хотя при времени выполнения функции 300/20е6 секунды, может и не стоит этим заниматься. p.s. можете назвать его по другому, т.к. у вас в отличие от полноценного итератора будет только конструктор и метод сдвига. как то так: Код: class NextFrame Название: Re: Вычислить кадр мувика Отправлено: Igors от Июнь 04, 2017, 10:15 Итератор будет внутри хранить текущую позицию(а не номер фрейма), у него будет расчитан размер... Понял - с идеей инкапсуляции. По-моему особого смысла в ней здесь нет, больше "обвязок" придется писать (а потом читать). Хотя конечно - дело вкуса...и при вызове функции не инлайн один аргумент - смещение (в стек будет лишний мусор копироваться). Хотя при времени выполнения функции 300/20е6 секунды, может и не стоит этим заниматься. Я тоже за производительность, но уверен - это не то место где надо оптимизировать :)... ...если есть желание можно проверить производительность, хотя за счет вызова функции наверное уменьшиться. |