Я надеюсь, что у кого-то есть идея, как мне лучше решить эту проблему, которую я создал для себя 🙂 В настоящее время я ищу способ запрограммировать эту логику:
Представьте, что у меня есть ползунок управления, который пользователь контролирует и переключается с 0 на 255, и представьте, что у меня есть ползунок синхронизации, от 0 миллисекунд до 20000 миллисекунд.
Теперь, если я установлю ползунок синхронизации на 20 000 и переместим ползунок управления с 0 на 255, я ожидаю, что код выдаст точку перехода между 0 и 255 в течение 20 секунд. У меня есть код, который делает это хорошо, и он будет прикреплен ниже.
Однако, скажем, 10 секунд в этот переходный период, пользователь перемещает ползунок управления с 255 обратно на 0. Через 10 секунд точка перехода, х, должна быть на уровне 127. Я хочу, чтобы значение х было переместите оставшиеся 10 секунд к новой точке ползунка управления, в данном случае к 0. В идеале это должно работать для любого количества движений в течение этого 20-секундного периода.
Когда x достигает контрольной точки, код перехода деактивируется до следующего движения.
Вот код, который обрабатывает первую часть проблемы, которую я пытаюсь решить:
class Fader {
public:
float newFaderValueSetTime;
float newFaderValue;
bool transitionInMotion;
float lastReturnedValueWhenNewFaderValueWasSet;
bool newFaderValueSet;
float lastOutputValue;
Fader(void) {
lastReturnedValueWhenNewFaderValueWasSet = 0;
newFaderValue = 0;
lastOutputValue = 0;
transitionInMotion = false;
}
int getValue(float delayAmount) {
float currentTime = ofGetElapsedTimeMillis() ;
float timePassedSinceNewFaderValue = currentTime - newFaderValueSetTime;
if(timePassedSinceNewFaderValue >= delayAmount) {
transitionInMotion = false;
}
if(transitionInMotion) {
lastOutputValue = ofMap(timePassedSinceNewFaderValue, 0, delayAmount, lastReturnedValueWhenNewFaderValueWasSet, newFaderValue);
} else {
lastOutputValue = newFaderValue;
}
return lastOutputValue;
}void setFaderValue(int val, float delayAmount) {
if(delayAmount > 0 && !transitionInMotion) {
transitionInMotion = true;
newFaderValueSetTime = ofGetElapsedTimeMillis();
lastReturnedValueWhenNewFaderValueWasSet = lastOutputValue;
}
newFaderValue = val;
}
};
Это в c ++ с использованием OpenFrameworks, отсюда и префикс для некоторых функций. Во всяком случае, я надеюсь, что я был достаточно конкретным в этой проблеме.
Я думаю, что основной вопрос кода — это способ отображения диапазонов значений — например, возьмем следующую строку:
lastOutputValue = ofMap (timePassedSinceNewFaderValue, 0, delayAmount, lastReturnedValueWhenNewFaderValueWasSet, newFaderValue);
Эта строка принимает количество времени, прошедшего как временную позицию, устанавливает ее относительно величины задержки, затем переназначает свое значение из lastReturnedValueWhenNewFaderValueWasSet в newFaderValue. Например,
Если во время перехода значение фейдера было равно 0 и перемещалось в 255, то
lastReturnedValueWhenNewFaderValueWasSet = 0 и newFaderValue = 255;
Однако с 10-секундной отметкой lastOutputValue будет 127, и если я затем переместлю newFaderValue с 255 на 0, то lastReturnedValueWhenNewFaderValueWasSet все равно будет 0, а сопоставление будет от 0 до 0, а не от текущей позиции точка перехода, х.
Я надеюсь, что это объясняет логику немного лучше. Ура!
Я решил проблему, которую я поставил. Вот краткое изложение логики и кода для тех, кто ищет решение этой проблемы.
х будет увеличиваться, если пункт назначения больше х
х будет уменьшаться, если пункт назначения меньше х
х определяется как значение, установленное до запуска таймера
если таймер активен, если и только если
таймер больше нуля
Пункт назначения больше или меньше х
Величина увеличения определяется как расстояние между x, пунктом назначения, деленное на время, оставшееся до достижения пункта назначения, умноженное на разницу с момента последнего установления значения x.
например
допустим, х равен 127, а пункт назначения — 200. Оставшееся время составляет 10 000 миллисекунд.
положительная разница = 200-127 = 73 на 10000
делится на оставшееся время, умноженное на изменение времени с момента последнего обновления.
(200-127 / 10000) * 60 (миллисекунды с момента последнего обновления)
= сумма для увеличения …
допустим, x = 200, а пункт назначения — 90. Оставшееся время составляет 10 000 миллисекунд.
положительная разница составляет 200-90 = 110.
(110/10000) * 60 (миллисекунды с момента последнего обновления) = 0,66 .. который должен быть удален из х …
и потому что x уменьшается в этом случае, дополнительный расчет (0,66 * -1) для получения отрицательного значения.
И код:
class Fader {
public:float newFaderValueSetTime;
float destination;
float lastUpdateTime;
float x;
bool transitionInMotion;
Fader(void) {
transitionInMotion = false;
lastUpdateTime = -1;
x= 0;
destination = 0;
}
float positiveDifference(float x1, float y1) {
if(x1>y1) {
return x1-y1;
} else {
return y1-x1;
}
}
int getValue(float delayAmount) {
float currentTime = ofGetElapsedTimeMillis();
float timePassedSinceNewFaderValue = currentTime - newFaderValueSetTime;
if(timePassedSinceNewFaderValue >= delayAmount) {
transitionInMotion = false;
}
if(transitionInMotion) {
float timeRemaining = delayAmount - timePassedSinceNewFaderValue;
float diff = positiveDifference(x, destination);
float tempX = (diff / timeRemaining);
if(lastUpdateTime == -1) {
lastUpdateTime = currentTime;
} else {
tempX = tempX * (currentTime - lastUpdateTime);
}
if(destination > x) {
x = x + tempX;
} else if (destination < x) {
x = x + (tempX*-1);
}
} else {
x = destination;
}if(x > 0) {
ofLogNotice("Output Value of fader is: " + ofToString(x));
}
lastUpdateTime = currentTime;
return x;
}void setFaderValue(int val, float delayAmount) {
if(delayAmount > 0 && !transitionInMotion) {
transitionInMotion = true;
newFaderValueSetTime = ofGetElapsedTimeMillis();
lastUpdateTime = -1;
}
destination = val;
}
};