簡體   English   中英

將一個值限制在一個范圍內(有點)

[英]Clamping a value to a range (sort of)

我有一個滑塊,它返回從 0.0f 到 1.0f 的值。

我想使用這個值並將其限制為 MIN 和 MAX,但不完全限制。

假設最小值為 0.2f,最大值為 0.3f。 當滑塊為 0 時,我想要 0.2f。 當滑塊在 0.5f 時,我想要 0.25f,依此類推。

只是為了讓滑塊的效果沒有那么強。

給定MIN MAX 和sliderVal,我怎么能夾住sliderVal?

謝謝

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

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

假設您希望滑塊在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

QED

我們可以概括上面的過程。 而不是使用點(0.0, 0.2)(1.0, 0.3) ,使用點(minSlider, maxSlider)(minValue, maxValue)

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

消除變量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;

基本上你有

0.0f -> MIN
1.0f -> MAX

你想要

clampedVal = sliderVal * ( MAX - MIN ) + MIN

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM