1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-11 13:10:58 +00:00

GDScript: Clarified/fixed inaccuracies in the built-in function docs.

The input to smoothstep is not actually a weight, and the decscription
of smoothstep was pretty hard to understand and easy to misinterpret.

Clarified what it means to be approximately equal.

nearest_po2 does not do what the descriptions says it does. For one,
it returns the same power if the input is a power of 2. Second, it
returns 0 if the input is negative or 0, while the smallest possible
integral power of 2 actually is 1 (2^0 = 1). Due to the implementation
and how it is used in a lot of places, it does not seem wise to change
such a core function however, and I decided it is better to alter the
description of the built-in.

Added a few examples/clarifications/edge-cases.

(cherry picked from commit 7f9bfee0ac)
This commit is contained in:
Meriipu
2020-07-25 16:11:23 +02:00
committed by Rémi Verschelde
parent 5e978d1df5
commit 347a9df0a1
3 changed files with 33 additions and 17 deletions

View File

@@ -233,15 +233,19 @@ public:
static _ALWAYS_INLINE_ double range_lerp(double p_value, double p_istart, double p_istop, double p_ostart, double p_ostop) { return Math::lerp(p_ostart, p_ostop, Math::inverse_lerp(p_istart, p_istop, p_value)); } static _ALWAYS_INLINE_ double range_lerp(double p_value, double p_istart, double p_istop, double p_ostart, double p_ostop) { return Math::lerp(p_ostart, p_ostop, Math::inverse_lerp(p_istart, p_istop, p_value)); }
static _ALWAYS_INLINE_ float range_lerp(float p_value, float p_istart, float p_istop, float p_ostart, float p_ostop) { return Math::lerp(p_ostart, p_ostop, Math::inverse_lerp(p_istart, p_istop, p_value)); } static _ALWAYS_INLINE_ float range_lerp(float p_value, float p_istart, float p_istop, float p_ostart, float p_ostop) { return Math::lerp(p_ostart, p_ostop, Math::inverse_lerp(p_istart, p_istop, p_value)); }
static _ALWAYS_INLINE_ double smoothstep(double p_from, double p_to, double p_weight) { static _ALWAYS_INLINE_ double smoothstep(double p_from, double p_to, double p_s) {
if (is_equal_approx(p_from, p_to)) return p_from; if (is_equal_approx(p_from, p_to)) {
double x = CLAMP((p_weight - p_from) / (p_to - p_from), 0.0, 1.0); return p_from;
return x * x * (3.0 - 2.0 * x); }
double s = CLAMP((p_s - p_from) / (p_to - p_from), 0.0, 1.0);
return s * s * (3.0 - 2.0 * s);
} }
static _ALWAYS_INLINE_ float smoothstep(float p_from, float p_to, float p_weight) { static _ALWAYS_INLINE_ float smoothstep(float p_from, float p_to, float p_s) {
if (is_equal_approx(p_from, p_to)) return p_from; if (is_equal_approx(p_from, p_to)) {
float x = CLAMP((p_weight - p_from) / (p_to - p_from), 0.0f, 1.0f); return p_from;
return x * x * (3.0f - 2.0f * x); }
float s = CLAMP((p_s - p_from) / (p_to - p_from), 0.0f, 1.0f);
return s * s * (3.0f - 2.0f * s);
} }
static _ALWAYS_INLINE_ double move_toward(double p_from, double p_to, double p_delta) { return abs(p_to - p_from) <= p_delta ? p_to : p_from + SGN(p_to - p_from) * p_delta; } static _ALWAYS_INLINE_ double move_toward(double p_from, double p_to, double p_delta) { return abs(p_to - p_from) <= p_delta ? p_to : p_from + SGN(p_to - p_from) * p_delta; }
static _ALWAYS_INLINE_ float move_toward(float p_from, float p_to, float p_delta) { return abs(p_to - p_from) <= p_delta ? p_to : p_from + SGN(p_to - p_from) * p_delta; } static _ALWAYS_INLINE_ float move_toward(float p_from, float p_to, float p_delta) { return abs(p_to - p_from) <= p_delta ? p_to : p_from + SGN(p_to - p_from) * p_delta; }

View File

@@ -320,7 +320,7 @@
</argument> </argument>
<description> <description>
The natural exponential function. It raises the mathematical constant [b]e[/b] to the power of [code]s[/code] and returns it. The natural exponential function. It raises the mathematical constant [b]e[/b] to the power of [code]s[/code] and returns it.
[b]e[/b] has an approximate value of 2.71828. [b]e[/b] has an approximate value of 2.71828, and can be obtained with [code]exp(1)[/code].
For exponents to other bases use the method [method pow]. For exponents to other bases use the method [method pow].
[codeblock] [codeblock]
a = exp(2) # Approximately 7.39 a = exp(2) # Approximately 7.39
@@ -501,6 +501,8 @@
</argument> </argument>
<description> <description>
Returns [code]true[/code] if [code]a[/code] and [code]b[/code] are approximately equal to each other. Returns [code]true[/code] if [code]a[/code] and [code]b[/code] are approximately equal to each other.
Here, approximately equal means that [code]a[/code] and [code]b[/code] are within a small internal epsilon of each other, which scales with the magnitude of the numbers.
Infinity values of the same sign are considered equal.
</description> </description>
</method> </method>
<method name="is_inf"> <method name="is_inf">
@@ -638,6 +640,7 @@
[codeblock] [codeblock]
log(10) # Returns 2.302585 log(10) # Returns 2.302585
[/codeblock] [/codeblock]
[b]Note:[/b] The logarithm of [code]0[/code] returns [code]-inf[/code], while negative values return [code]-nan[/code].
</description> </description>
</method> </method>
<method name="max"> <method name="max">
@@ -683,7 +686,9 @@
Moves [code]from[/code] toward [code]to[/code] by the [code]delta[/code] value. Moves [code]from[/code] toward [code]to[/code] by the [code]delta[/code] value.
Use a negative [code]delta[/code] value to move away. Use a negative [code]delta[/code] value to move away.
[codeblock] [codeblock]
move_toward(5, 10, 4) # Returns 9
move_toward(10, 5, 4) # Returns 6 move_toward(10, 5, 4) # Returns 6
move_toward(10, 5, -1.5) # Returns 11.5
[/codeblock] [/codeblock]
</description> </description>
</method> </method>
@@ -693,12 +698,17 @@
<argument index="0" name="value" type="int"> <argument index="0" name="value" type="int">
</argument> </argument>
<description> <description>
Returns the nearest larger power of 2 for integer [code]value[/code]. Returns the nearest equal or larger power of 2 for integer [code]value[/code].
In other words, returns the smallest value [code]a[/code] where [code]a = pow(2, n)[/code] such that [code]value &lt;= a[/code] for some non-negative integer [code]n[/code].
[codeblock] [codeblock]
nearest_po2(3) # Returns 4 nearest_po2(3) # Returns 4
nearest_po2(4) # Returns 4 nearest_po2(4) # Returns 4
nearest_po2(5) # Returns 8 nearest_po2(5) # Returns 8
nearest_po2(0) # Returns 0 (this may not be what you expect)
nearest_po2(-1) # Returns 0 (this may not be what you expect)
[/codeblock] [/codeblock]
[b]WARNING:[/b] Due to the way it is implemented, this function returns [code]0[/code] rather than [code]1[/code] for non-positive values of [code]value[/code] (in reality, 1 is the smallest integer power of 2).
</description> </description>
</method> </method>
<method name="ord"> <method name="ord">
@@ -1078,15 +1088,17 @@
</argument> </argument>
<argument index="1" name="to" type="float"> <argument index="1" name="to" type="float">
</argument> </argument>
<argument index="2" name="weight" type="float"> <argument index="2" name="s" type="float">
</argument> </argument>
<description> <description>
Returns a number smoothly interpolated between the [code]from[/code] and [code]to[/code], based on the [code]weight[/code]. Similar to [method lerp], but interpolates faster at the beginning and slower at the end. Returns the result of smoothly interpolating the value of [code]s[/code] between [code]0[/code] and [code]1[/code], based on the where [code]s[/code] lies with respect to the edges [code]from[/code] and [code]to[/code].
The return value is [code]0[/code] if [code]s &lt;= from[/code], and [code]1[/code] if [code]s &gt;= to[/code]. If [code]s[/code] lies between [code]from[/code] and [code]to[/code], the returned value follows an S-shaped curve that maps [code]s[/code] between [code]0[/code] and [code]1[/code].
This S-shaped curve is the cubic Hermite interpolator, given by [code]f(s) = 3*s^2 - 2*s^3[/code].
[codeblock] [codeblock]
smoothstep(0, 2, -5.0) # Returns 0.0 smoothstep(0, 2, -5.0) # Returns 0.0
smoothstep(0, 2, 0.5) # Returns 0.15625 smoothstep(0, 2, 0.5) # Returns 0.15625
smoothstep(0, 2, 1.0) # Returns 0.5 smoothstep(0, 2, 1.0) # Returns 0.5
smoothstep(0, 2, 2.0) # Returns 1.0 smoothstep(0, 2, 2.0) # Returns 1.0
[/codeblock] [/codeblock]
</description> </description>
</method> </method>
@@ -1100,7 +1112,7 @@
[codeblock] [codeblock]
sqrt(9) # Returns 3 sqrt(9) # Returns 3
[/codeblock] [/codeblock]
If you need negative inputs, use [code]System.Numerics.Complex[/code] in C#. [b]Note:[/b]Negative values of [code]s[/code] return NaN. If you need negative inputs, use [code]System.Numerics.Complex[/code] in C#.
</description> </description>
</method> </method>
<method name="step_decimals"> <method name="step_decimals">

View File

@@ -1715,7 +1715,7 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) {
return mi; return mi;
} break; } break;
case MATH_SMOOTHSTEP: { case MATH_SMOOTHSTEP: {
MethodInfo mi("smoothstep", PropertyInfo(Variant::REAL, "from"), PropertyInfo(Variant::REAL, "to"), PropertyInfo(Variant::REAL, "weight")); MethodInfo mi("smoothstep", PropertyInfo(Variant::REAL, "from"), PropertyInfo(Variant::REAL, "to"), PropertyInfo(Variant::REAL, "s"));
mi.return_val.type = Variant::REAL; mi.return_val.type = Variant::REAL;
return mi; return mi;
} break; } break;