Browse Source

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.
Meriipu 5 years ago
parent
commit
7f9bfee0ac

+ 6 - 6
core/math/math_funcs.h

@@ -231,19 +231,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_ 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;
 		}
-		double x = CLAMP((p_weight - p_from) / (p_to - p_from), 0.0, 1.0);
-		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;
 		}
-		float x = CLAMP((p_weight - p_from) / (p_to - p_from), 0.0f, 1.0f);
-		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_ 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; }

+ 19 - 6
modules/gdscript/doc_classes/@GDScript.xml

@@ -318,7 +318,7 @@
 			</argument>
 			<description>
 				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].
 				[codeblock]
 				a = exp(2) # Approximately 7.39
@@ -505,6 +505,8 @@
 			</argument>
 			<description>
 				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>
 		</method>
 		<method name="is_inf">
@@ -641,6 +643,7 @@
 				[codeblock]
 				log(10) # Returns 2.302585
 				[/codeblock]
+				[b]Note:[/b] The logarithm of [code]0[/code] returns [code]-inf[/code], while negative values return [code]-nan[/code].
 			</description>
 		</method>
 		<method name="max">
@@ -686,7 +689,9 @@
 				Moves [code]from[/code] toward [code]to[/code] by the [code]delta[/code] value.
 				Use a negative [code]delta[/code] value to move away.
 				[codeblock]
+				move_toward(5, 10, 4) # Returns 9
 				move_toward(10, 5, 4) # Returns 6
+				move_toward(10, 5, -1.5) # Returns 11.5
 				[/codeblock]
 			</description>
 		</method>
@@ -696,12 +701,17 @@
 			<argument index="0" name="value" type="int">
 			</argument>
 			<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]
 				nearest_po2(3) # Returns 4
 				nearest_po2(4) # Returns 4
 				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]
+				[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>
 		</method>
 		<method name="ord">
@@ -1093,12 +1103,15 @@
 			</argument>
 			<argument index="1" name="to" type="float">
 			</argument>
-			<argument index="2" name="weight" type="float">
+			<argument index="2" name="s" type="float">
 			</argument>
 			<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]
-				smoothstep(0, 2, 0.5) # Returns 0.15
+				smoothstep(0, 2, -5.0) # Returns 0.0
+				smoothstep(0, 2, 0.5) # Returns 0.15625
 				smoothstep(0, 2, 1.0) # Returns 0.5
 				smoothstep(0, 2, 2.0) # Returns 1.0
 				[/codeblock]
@@ -1114,7 +1127,7 @@
 				[codeblock]
 				sqrt(9) # Returns 3
 				[/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>
 		</method>
 		<method name="step_decimals">

+ 1 - 1
modules/gdscript/gdscript_functions.cpp

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