我已经绞尽脑汁解决这个问题两天了,我尝试了不同的东西,但没有一个能奏效。我正在构建一个应用程序,这是一种quizz。有三个主题包含问题。我想使用3个滑块来定义他们想要对每个主题的问题百分比。
ex : slider one = History
slider two = Maths
slider three = Grammar
如果我选择了更多历史记录,我会向上滑动历史记录滑块,其他滑块应根据3个滑块的值达到100%而减少...
算法的任何想法?当一个滑块达到零值时会发生什么?
数学从未成为我的场景。
非常感谢任何帮助。
提前致谢。
迈克答案 0 :(得分:6)
虽然Snowangelic的答案很好,但我认为如下限制未改变值之间的比例更有意义。
设s1,s2,s3为滑块的当前值,因此s1 + s2 + s3 = 100。您想要为n1,n2,n3求解滑块的新值,以便n1 + n2 + n3 = 100。假设用户将s1更改为n1。然后,这会添加以下约束:
n2 / n3 = s2 / s3
因此,问题的解决方案是n1 + n2 + n3 = 100,
n2 =(100-n1)/(s3 / s2 + 1)或0(如果s2 = 0)和
n3 =(100-n1)/(s2 / s3 + 1)或0(如果s3 = 0)
答案 1 :(得分:1)
以33.333 ...%
启动所有三个滑块当用户向上移动滑块时说10%:将另外两个滑块向下移动5%。但是,如果两个滑块中的一个达到0 =>只移动百分之十的另一个。所以它给出了这样的东西:
User moved slider of x (my be positive or negative)
for first slider
if slider -x/2 > 0 and x/2 < 100
move this slider of -x/2
else
move the other slider of -x/2
for second slider
if slider -x/2 > 0 and x/2 < 100
move this slider of -x/2
else
move the other slider of -x/2
end
另一种可能性是考虑可用资源的总和为100,将资源分成n个桶(在您的情况下为3)。当用户移动滑块时,他会修复相应存储桶中的资源数量。因此,您可以从其他存储桶中获取资源,也可以将资源放在其他存储桶中。
你有类似的东西:
state 1 ; modified bucket ; new number of ressources in that bucket
modification = new number of ressources in the bucket - number of rescources in the state 1
for (int i=0 ; modification > 0 ; i++){
i=i%nbr of buckets;
if(bucket i != modified bucket){
if(number of ressources in bucket i-- > 0 && number of ressources in bucket i-- < 100){
number of ressources in bucket i--;
modification --;
}
}
}
即假设修改为正(修改后的桶中的新数字高于之前)。这个小算法适用于任意数量的存储桶(在您的情况下为滑块)。
答案 2 :(得分:0)
应该审查以下算法,当然还要优化。这只是我放在一起的东西,我没有测试过它。
使用最大值和最小值初始化每个滑块并根据需要设置初始值,但要尊重x + y + z = 1
。
[self.slider1 setMinimumValue:0.0];
[self.slider1 setMaximumValue:1.0];
[self.slider1 setValue:0.20];
[self.slider2 setMinimumValue:0.0];
[self.slider2 setMaximumValue:1.0];
[self.slider2 setValue:0.30];
[self.slider3 setMinimumValue:0.0];
[self.slider3 setMaximumValue:1.0];
[self.slider3 setValue:0.50];
将三个滑块设置为相同的选择器:
[self.slider1 addTarget:self action:@selector(valueChanged:) forControlEvents:UIControlEventValueChanged];
[self.slider2 addTarget:self action:@selector(valueChanged:) forControlEvents:UIControlEventValueChanged];
[self.slider3 addTarget:self action:@selector(valueChanged:) forControlEvents:UIControlEventValueChanged];
选择器应该做类似的事情:
- (void)valueChanged:(UISlider *)slider {
UISlider *sliderX = nil;
UISlider *sliderY = nil;
UISlider *sliderZ = nil;
if (slider == self.slider1) {
sliderX = self.slider1;
sliderY = self.slider2;
sliderZ = self.slider3;
} else if (slider == self.slider2) {
sliderY = self.slider1;
sliderX = self.slider2;
sliderZ = self.slider3;
} else {
sliderY = self.slider1;
sliderZ = self.slider2;
sliderX = self.slider3;
}
float x = sliderX.value;
float y = sliderY.value;
float z = sliderZ.value;
// x + y + z = 1
// Get the amout x has changed
float oldX = 1 - y - z;
float difference = x - oldX;
float newY = y - difference / 2;
float newZ = z - difference / 2;
if (newY < 0) {
newZ += y + newY;
newY = 0;
}
if (newZ < 0) {
newY += z + newZ;
newZ = 0;
}
[sliderY setValue:newY animated:YES];
[sliderZ setValue:newZ animated:YES];
}
如果此代码有问题,请告诉我,我可以解决它!