浏览代码

Merge pull request #21091 from marcofugaro/pingpong

Add MathUtils.pingpong()
Mr.doob 4 年之前
父节点
当前提交
c4d3bbe7cd

+ 7 - 0
docs/api/en/math/MathUtils.html

@@ -64,6 +64,13 @@
 		Linear mapping of [page:Float x] from range [[page:Float a1], [page:Float a2]] to range [[page:Float b1], [page:Float b2]].
 		</p>
 
+		<h3>[method:Float pingpong]( [param:Float x], [param:Float length] )</h3>
+		<p>
+		[page:Float x] — The value to pingpong.<br />
+		[page:Float length] — The positive value the function will pingpong to. Default is 1.<br /><br />
+
+		Returns a value that alternates between 0 and [param:Float length].</p>
+
 		<h3>[method:Integer ceilPowerOfTwo]( [param:Number n] )</h3>
 		<p>Returns the smallest power of 2 that is greater than or equal to [page:Number n].</p>
 

+ 7 - 0
docs/api/zh/math/MathUtils.html

@@ -61,6 +61,13 @@
 		x从范围[[page:Float a1], [page:Float a2]] 到范围[[page:Float b1], [page:Float b2]]的线性映射。
 		</p>
 
+		<h3>[method:Float pingpong]( [param:Float x], [param:Float length] )</h3>
+		<p>
+		[page:Float x] — The value to pingpong.<br />
+		[page:Float length] — The positive value the function will pingpong to. Default is 1.<br /><br />
+
+		Returns a value that alternates between 0 and [param:Float length].</p>
+
 		<h3>[method:Integer ceilPowerOfTwo]( [param:Number n] )</h3>
 		<p>返回大于等于 [page:Number n] 的2的最小次幂。</p>
 

+ 9 - 0
src/math/MathUtils.d.ts

@@ -85,6 +85,15 @@ export namespace MathUtils {
 	 */
 	export function lerp( x: number, y: number, t: number ): number;
 
+	/**
+	 * Returns a value that alternates between 0 and length.
+	 *
+	 * @param x The value to pingpong.
+	 * @param length The positive value the function will pingpong to. Default is 1.
+	 * @return {number}
+	 */
+	export function pingpong( x: number, length?: number ): number;
+
 	/**
 	 * @deprecated Use {@link Math#floorPowerOfTwo .floorPowerOfTwo()}
 	 */

+ 8 - 0
src/math/MathUtils.js

@@ -62,6 +62,14 @@ const MathUtils = {
 
 	},
 
+	// https://www.desmos.com/calculator/vcsjnyz7x4
+
+	pingpong: function ( x, length = 1 ) {
+
+		return length - Math.abs( MathUtils.euclideanModulo( x, length * 2 ) - length );
+
+	},
+
 	// http://en.wikipedia.org/wiki/Smoothstep
 
 	smoothstep: function ( x, min, max ) {

+ 9 - 0
test/unit/src/math/MathUtils.tests.js

@@ -152,6 +152,15 @@ export default QUnit.module( 'Maths', () => {
 
 		} );
 
+
+		QUnit.test( "pingpong", ( assert ) => {
+
+			assert.strictEqual( MathUtils.pingpong( 2.5 ), 0.5, "Value at 2.5 is 0.5" );
+			assert.strictEqual( MathUtils.pingpong( 2.5, 2 ), 1.5, "Value at 2.5 with length of 2 is 1.5" );
+			assert.strictEqual( MathUtils.pingpong( - 1.5 ), 0.5, "Value at -1.5 is 0.5" );
+
+		} );
+
 	} );
 
 } );