C++ (Qt)int NextFrame( int currentFrame, int step, .. );
int NextFrame(int currentFrame, int step, int x0, int x1) { int dPosFirst = x1>x0? 1: -1; // направление в первой последовательности int size = abs(x1-x0)+1; int posCurrentFrame = (currentFrame - x0) * dPosFirst; if(posCurrentFrame >= size || posCurrentFrame<0) return 0; //TODO error: число не принадлежит последовательности posCurrentFrame += step; // new Frame; if(x0 == x1)return x0; // если один кадр int sizeWithBack = size*2 - 2; // размер последовательности включая обратную(не правильно считает для одного кадра x0==x1, но этот случай отсекли) posCurrentFrame -= (posCurrentFrame / sizeWithBack) * sizeWithBack; // теперь новый кадр будет лежать в диапазоне [0, sizeWithBack), так как данная последовательность повторяется return posCurrentFrame < size? x0 + posCurrentFrame * dPosFirst: x0 + (sizeWithBack - posCurrentFrame) * dPosFirst;}
C++ (Qt)inline int NextFrame(int currentFrame, int step, int min, int max){ const int T = 2*(max - min); auto toFrame = [&](int x)->int { return (x <= T/2) ? (min + x) : (T - x + min); }; int x = currentFrame - min; int n = trunc(double(step)/T); return toFrame(x + step - T*n);}
C++ (Qt)int NextFrame( int curFrame, int step, int R[2] ){ int relF = qAbs(curFrame - R[0]) + step; // frame to relative int range = qAbs(R[1] - R[0]) + 1; // frame count if (relF >= range) { // if frame is out of range relF %= range * 2 - 1; // skip period if (relF >= range) { // flip direction relF -= range - 1; qSwap(R[0], R[1]); } } return R[0] + ((R[0] < R[1]) ? relF : -relF); // frame to absolute}
C++ (Qt)inline int NextFrame(int currentFrame, int step, int x0, int x1) throw (std::logic_error){ if ((currentFrame < std::min(x0, x1)) || (currentFrame > std::max(x0, x1))) throw std::logic_error("out of range"); int sign = (x1 > x0) ? 1 : -1; const int T = 2*sign*(x1 - x0); auto toFrame = [&](int x)->int { return (x <= T/2) ? (x0 + sign*x) : (sign*(T - x) + x0); }; int x = sign*(currentFrame - x0); return toFrame((x + step % T) % T);}