Russian Qt Forum

Программирование => Алгоритмы => Тема начата: Igors от Январь 03, 2021, 14:57



Название: Выбрать кадры
Отправлено: Igors от Январь 03, 2021, 14:57
Добрый день

Есть простая структурка
Код
C++ (Qt)
struct CFrameRange {
 int mStart = 0;     // первый кадр
 int mSttop = 12;  // последний кадр
 int mCount = 4;    // число вариантов выбора
};
Требуется написать для нее метод принимающий float от 0 до 1 и возвращающий номер кадра. Напр для дефаултных значений должны возвращаться один из номеров  0, 4, 8, 12, чем больше входной флоат - тем и номер больше
Код
C++ (Qt)
int CFrameRange::Val2Frame( float val ) const
{
 ???
}

Спасибо


Название: Re: Выбрать кадры
Отправлено: ecspertiza от Январь 12, 2021, 14:26
А нужно красиво или тупо?

псевдо:

Код:
int CFrameRange::Val2Frame( float val ) const
{
    int index = atoi(std::to_string(val).replace("0.", ""));
    return index;
}

или что то не верно понял?


Название: Re: Выбрать кадры
Отправлено: ecspertiza от Январь 12, 2021, 14:28
Или float - это процент до 100 грубо говоря. И чем он выше тем ближе к концу нужно выбрать кадр?


Название: Re: Выбрать кадры
Отправлено: __Heaven__ от Январь 14, 2021, 08:27
Код
C++ (Qt)
int len = stop - start;
int result = (len * val) / count;
result *= count;
 


Название: Re: Выбрать кадры
Отправлено: Igors от Январь 14, 2021, 12:14
Или float - это процент до 100 грубо говоря. И чем он выше тем ближе к концу нужно выбрать кадр?
Да, как % только от 0 до 1

Код
C++ (Qt)
int len = stop - start;
int result = (len * val) / count;
result *= count;
 
Опять "прете напролом" :) Так кадр 12 поучится только если val = 1,0f (почти никогда)


Название: Re: Выбрать кадры
Отправлено: __Heaven__ от Январь 14, 2021, 22:08
ну как напролом, что спрошено, то и предложено


Название: Re: Выбрать кадры
Отправлено: Igors от Январь 15, 2021, 11:43
ну как напролом, что спрошено, то и предложено
Не совсем. Если val распределено равномерно (или равновероятно), то и выбранных кадров (0, 4, 8, 12) должно быть примерно поровну.

Довольно мерзкая деталюшка "на округление"   :)



Название: Re: Выбрать кадры
Отправлено: ecspertiza от Январь 17, 2021, 20:54
Код:
int CFrameRange::Val2Frame( float val ) const
{
    int len = stop - start;
    int lenInterval = len / count;
    float intervalPercent = (float)1 / lenInterval;
    int intervalIndex = floor(val / intervalPercent);
   
    float minFramePercent = intervalIndex * intervalPercent;
    float maxFramePercent = (intervalIndex + 1) * intervalPercent;
   
    float minFrameDiff = abs(minFramePercent - val);
    float maxFrameDiff = abs(maxFramePercent - val);
    int step = len / lenInterval;
    float framePer;
    if (minFrameDiff  < maxFrameDiff) {
        framePer = minFramePercent;
    }else {
        framePer = maxFramePercent;
    }

    return step * (framePer / intervalPercent);
}

Думаю можно как то сделать оптимальнее. Но у меня получилось вот так.


Название: Re: Выбрать кадры
Отправлено: Igors от Январь 18, 2021, 12:13
...у меня получилось вот так.
Извините, "ни асилил" Ваш вариант. Вот что получилось у меня
Код
C++ (Qt)
int CFrameRange::Val2Frame( float val ) const
{
int index = int(val * mCount);
float step = float(mStop - mStart) / (mCount - 1);
int frame = int(index * step + 0.5f) + mStart;
return qBound(mStart, frame, mStop);
}
 


Название: Re: Выбрать кадры
Отправлено: Old от Январь 18, 2021, 12:33
Извините, "ни асилил" Ваш вариант. Вот что получилось у меня
Код
C++ (Qt)
int CFrameRange::Val2Frame( float val ) const
{
int index = int(val * mCount);
float step = float(mStop - mStart) / (mCount - 1);
int frame = int(index * step + 0.5f) + mStart;
return qBound(mStart, frame, mStop);
}
 

Вы и ваш не очень осилили. :)
Разве не может быть mCount = 1?


Название: Re: Выбрать кадры
Отправлено: ecspertiza от Январь 18, 2021, 13:10
...у меня получилось вот так.
Извините, "ни асилил" Ваш вариант. Вот что получилось у меня
Код
C++ (Qt)
int CFrameRange::Val2Frame( float val ) const
{
int index = int(val * mCount);
float step = float(mStop - mStart) / (mCount - 1);
int frame = int(index * step + 0.5f) + mStart;
return qBound(mStart, frame, mStop);
}
 

+- тоже что и у Вас, только сложнее.


Название: Re: Выбрать кадры
Отправлено: Racheengel от Январь 20, 2021, 13:30
if (val <= 0) return mStart;
if (val >= 1) return mStop;
int delta = (mStop-mStart) % mCount;
return val * delta + mStart;


Название: Re: Выбрать кадры
Отправлено: Igors от Январь 20, 2021, 16:55
if (val <= 0) return mStart;
if (val >= 1) return mStop;
int delta = (mStop-mStart) % mCount;
return val * delta + mStart;
Не понял юмора. Ну вот данные первого поста, остаток от деления = 0. Так что, всегда вернем mStart ?


Название: Re: Выбрать кадры
Отправлено: Racheengel от Январь 21, 2021, 12:06
Упс, малёх обшибся... "простите старика, маразьм":

if (val <= 0) return mStart;
if (val >= 1) return mStop;
float delta = (mStop-mStart) / mCount;
int index = (val * delta) * mCount + mStart;

а так?


Название: Re: Выбрать кадры
Отправлено: Igors от Январь 21, 2021, 13:06
а так?
Так уже было, кадр 12 не возвращается никогда (почти)


Название: Re: Выбрать кадры
Отправлено: __Heaven__ от Январь 22, 2021, 08:37
Код
C++ (Qt)
     int len = stop - start + count;
     int result = (len * val) / count;
     return min(result * count, stop);
 


Название: Re: Выбрать кадры
Отправлено: ecspertiza от Январь 22, 2021, 12:53
Код
C++ (Qt)
     int len = stop - start + count;
     int result = (len * val) / count;
     return min(result * count, stop);
 

по идее можно сократить / count и * count, будет равнозначно. Но у меня математика не бьется, получаем результат отличный от того что нужно.


Название: Re: Выбрать кадры
Отправлено: Racheengel от Январь 22, 2021, 19:35
а так?
Так уже было, кадр 12 не возвращается никогда (почти)

всегда вернётся, если val = 1:
if (val >= 1) return mStop;

А вот то, насколько часто бывает val = 1, это уже проблема вызывающей стороны.


Название: Re: Выбрать кадры
Отправлено: Igors от Январь 23, 2021, 11:48
всегда вернётся, если val = 1:
if (val >= 1) return mStop;

А вот то, насколько часто бывает val = 1, это уже проблема вызывающей стороны.
Нет. Пусть mStart = 0, mStop = 3, mNum = 4. Для равновероятного val от 0 ло 1 должны равновероятно выпадать кадры от 0 до 3 включительно, все равно что rand()  % mNum. То что выбирааются лишь некоторые (а не все) кадры в заданном диапазоне - не должно менять задачу, последний кадр должен быть столь же вероятен как любой другой.

Но в любом случае приятно видеть опыт постановки и практической работы с юзером :)


Название: Re: Выбрать кадры
Отправлено: Igors от Январь 23, 2021, 11:55
Код
C++ (Qt)
     int len = stop - start + count;
     int result = (len * val) / count;
     return min(result * count, stop);
 
Первая строка складывает разницу кадров со счетчиком - это не может быть правдой. На всякий случай проверим с val = 0, возвращается 0 , должно mStart