posCurrentFrame -= (posCurrentFrame / sizeWithBack) * sizeWithBack; if(posCurrentFrame<0) posCurrentFrame += sizeWithBack; // это для отрицательных шагов(т.е. удалить), т.к. -0.5 округляют не в меньшую сторону, а к нулю(можно floor использовать)
C++ (Qt)#include <iostream>#include <random>#include <cmath>#include <stdexcept> inline int NextFrame_m_ax(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"); if (x0 == x1) return x0; const 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);} int NextFrame_deMax(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;} int main(){ int f0 = 5; int f1 = 10; int frame = 9; std::cout << "m_ax \t deMax" << std::endl; for(int i=-20; i<20; ++i) { std::cout << NextFrame_m_ax(frame, i, f0, f1) << "\t" << NextFrame_deMax(frame, i, f0, f1) << std::endl; } return 0;}
Bashm_ax deMax9 -10 01 12 23 34 45 56 -47 -38 -29 -10 01 12 23 34 45 56 67 78 89 910 109 98 87 76 65 56 67 78 89 910 109 98 87 76 65 56 67 78 8
C++ (Qt) int f0 = 10; int f1 = 5;
Bashm_ax deMax9 1918 1817 1716 1615 1514 1413 1312 1211 1110 109 1918 1817 1716 1615 1514 1413 1312 1211 1110 109 98 87 76 65 56 67 78 89 910 109 98 87 76 65 56 67 78 89 910 10
inline 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) return 0; //TODO error posCurrentFrame += step; // new Frame; int sizeWithBack = size*2 - 2; posCurrentFrame -= (posCurrentFrame / sizeWithBack) * sizeWithBack; if(posCurrentFrame<0) posCurrentFrame += sizeWithBack; // без этой строчки у меня текущий кадр при отрицательном шаге сваливается в отрицательное значение, не из диапазона [0, sizeWithBack) и получается ерунда return posCurrentFrame < size? x0 + posCurrentFrame * dPosFirst: x0 + (sizeWithBack - posCurrentFrame) * dPosFirst;}
Bashm_ax, total time: 296deMax, total time: 305 m_ax, total time: 296deMax, total time: 304 m_ax, total time: 297deMax, total time: 303
C++ (Qt)posCurrentFrame -= (posCurrentFrame / sizeWithBack) * sizeWithBack;if(posCurrentFrame<0) posCurrentFrame += sizeWithBack;
C++ (Qt)return toFrame((x + step % T) % T);
inline int NextFrame(int currentFrame, uint step, int x0, int x1, bool &isReverse) { int dPosFirst = x1>x0? 1: -1; int size = abs(x1-x0)+1; int posCurrentFrame = (currentFrame - x0) * dPosFirst; if(posCurrentFrame >= size) return 0; //TODO error if(isReverseFind == true) posCurrentFrame = sizeWithBack - posCurrentFrame; posCurrentFrame += step; // new Frame; int sizeWithBack = size*2 - 2; posCurrentFrame -= (posCurrentFrame / sizeWithBack) * sizeWithBack;// if(posCurrentFrame<0) posCurrentFrame += sizeWithBack; // без этой строчки у меня текущий кадр при отрицательном шаге сваливается в отрицательное значение, не из диапазона [0, sizeWithBack) и получается ерунда isReverse = posCurrentFrame >= size; return posCurrentFrame < size? x0 + posCurrentFrame * dPosFirst: x0 + (sizeWithBack - posCurrentFrame) * dPosFirst;}
C++ (Qt)period = qAbs(R[1] - R[0]) * 2 + 1;step = (step % period) + period;
C++ (Qt)it += 100;
class NextFrame{ int x0, x1; int posCurrentFrame, dPosFirst, size, sizeWithBack; bool isReverse;public: NextFrame(int currentFrame, int x0, int x1, bool isReverse): x0(x0), x1(x1), isReverse(isReverse) { dPosFirst = x1>x0? 1: -1; size = abs(x1-x0)+1; sizeWithBack = size*2 - 2; posCurrentFrame = (currentFrame - x0) * dPosFirst; if(posCurrentFrame >= size) return; //TODO error if(isReverse == true) posCurrentFrame = sizeWithBack - posCurrentFrame; } int operator+=(uint step) { posCurrentFrame += step; // new Frame; posCurrentFrame -= (posCurrentFrame / sizeWithBack) * sizeWithBack; // if(posCurrentFrame<0) posCurrentFrame += sizeWithBack; // без этой строчки у меня текущий кадр при отрицательном шаге сваливается в отрицательное значение, не из диапазона [0, sizeWithBack) и получается ерунда isReverse = posCurrentFrame >= size; return posCurrentFrame < size? x0 + posCurrentFrame * dPosFirst: x0 + (sizeWithBack - posCurrentFrame) * dPosFirst; }};...//вроде работает :) NextFrame nf(9, 5, 10); for(int i=0; i<20; ++i) qDebug() << (nf+=1);