我希望那里的某个人可能知道如何更好地解决我为自己创造的问题:)我目前正在寻找一种方法来编写这种逻辑: 想象一下,我有一个控制滑块,用户控制并从0到255,想象我有一个时间滑块,从0毫秒到20,000毫秒。
现在,如果我将时间滑块设置为20,000,并将控制滑块从0移动到255,我预计代码将在20秒内输出0到255之间的转换点。我有这样做的代码很好,它将在下面附上。
然而,让我们说在过渡期间10秒钟,用户将控制滑块从255移回0.在10秒后,转换点x应该是127.我想要发生的是x值在剩余的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;
}
};
这是使用OpenFrameworks的c ++,因此是某些函数的前缀。无论如何,我希望我对这个问题有足够的了解。
问题的代码要点,我认为值范围的映射函数的方式 - 例如,采取这一行: 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。
我希望这能更好地解释逻辑。干杯!
答案 0 :(得分:0)
我已经解决了我提出的问题。以下是寻找解决此类问题的人的逻辑和代码的概要。
如果目的地大于x ,将增加 如果目的地小于x
,将减少
x定义为启动计时器之前设置的值
当且仅当
时,计时器处于活动状态计时器大于零 目的地大于或小于x
增加量定义为x,目的地之间的距离除以到达目的地的剩余时间乘以自上次设定x以来的差值。
e.g。 假设x是127,目标是200.剩余时间是10,000毫秒
正差= 200-127 = 73超过10,000
除以剩余时间,乘以自上次更新以来的时间变化。
(200-127 / 10,000)* 60(自上次更新以来的毫秒数)
=增加的数量......
假设x = 200且目的地为90.剩余时间为10,000毫秒
正差异为200-90 = 110。
(110 / 10,000)* 60(自上次更新以来的毫秒数)= 0.66 ..将从x中移除...
并且因为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;
}
};