将值限制在某个范围内(某种程度)

时间:2012-06-30 04:35:00

标签: c++ algorithm math

我有一个滑块,返回0.0f到1.0f的值。

我想使用这个值并将其钳制到MIN和MAX,但不能完全钳制。

Say min为0.2f,max为0.3f。当滑块为0时,我想要0.2f。当滑块为0.5f时,我想要0.25f,依此类推。

这样滑块的效果就不那么强了。

给定MIN MAX和sliderVal,我如何钳制sliderVal?

由于

4 个答案:

答案 0 :(得分:6)

slider_range = slider_max - slider_min;
range = range_max - range_min;

value = (double)(slider_pos - slider_min) / slider_range * range + range_min;

答案 1 :(得分:5)

假设您希望滑块在0.2f0.3f之间线性变化,则从[0.0 1.0]间隔到[0.2 0.3]的转换非常简单:

newVal = 0.2f + (sliderVal)*0.1f;

从数学角度来看,根据您的描述,您希望输出相对于输入是线性的。因此,输入和输出值之间的传递函数必须是以下形式:

y = mx + b

x值视为输入(滑块值),将y值视为输出(新的期望值)。因此,您有两点:(0.0, 0.2)(1.0, 0.3)将这些点替换为上述等式:

0.2 = (0.0)m + b
0.3 = (1.0)m + b

现在你有一个线性方程组,这个系统很容易解决:

0.2 = (0.0)m + b --> b = 0.2
0.3 = (1.0)m + b --> 0.3 = m + 0.2 --> m = 0.1

因此,传递函数是:

y = 0.1 * x + 0.2

Q.E.D。

我们可以概括上述过程。不使用积分(0.0, 0.2)(1.0, 0.3),而是使用积分(minSlider, maxSlider)(minValue, maxValue)

minValue = (minSlider)m + b
maxValue = (maxSlider)m + b

Elimate变量b

minValue = (minSlider)m + b
-maxValue = -(maxSlider)m - b

--> minValue-maxValue = (minSlider-maxSlider)m
m = (minValue-maxValue)/(minSlider-maxSlider)

消除变量m

minValue*maxSlider = (minSlider*maxSlider)m + b*maxSlider
-maxValue*minSlider = -(minSlider*maxSlider)m - b*minSlider

--> minValue*maxSlider - maxValue*minSlider = b(maxSlider-minSlider)
b = (minValue*maxSlider - maxValue*minSlider)/(maxSlider-minSlider)

您可以验证这些等式为mb提供了完全相同的值。如果我们假设最小滑块值始终为0.0

m = (minValue-maxValue)/(minSlider-maxSlider)
b = (minValue*maxSlider - maxValue*minSlider)/(maxSlider-minSlider)

--> m = (maxValue-minValue)/(maxSlider)
    b = minValue

在C ++中:

const double maxSlider = 1.0;
const double minValue = 0.2;
const double maxValue = 0.3;
double value = (maxValue-minValue)/(maxSlider)*getSliderPosition() + minValue;

答案 2 :(得分:3)

基本上你有

0.0f -> MIN
1.0f -> MAX

你想要

clampedVal = sliderVal * ( MAX - MIN ) + MIN

答案 3 :(得分:0)

std::lerp 就是这样做的。它接受三个浮点数,并在第一个和第二个之间插入第三个参数。

<块引用>

来自cppreference的引用:

#include <iostream>
#include <cmath>
 
int main()
{
    float a=10.0f, b=20.0f;
 
    std::cout << "a=" << a << ", " << "b=" << b << '\n'
              << "mid point=" << std::lerp(a,b,0.5f) << '\n'
              << std::boolalpha << (a == std::lerp(a,b,0.0f)) << ' '
              << std::boolalpha << (b == std::lerp(a,b,1.0f)) << '\n';
}

输出:

a=10, b=20
mid point=15
true true