ソースを参照

Vector2: Add `angleTo()`. (#25678)

Michael Herzog 2 年 前
コミット
ed6458e374

+ 5 - 0
docs/api/en/math/Vector2.html

@@ -100,6 +100,11 @@
 		Computes the angle in radians of this vector with respect to the positive x-axis.
 		</p>
 
+		<h3>[method:Float angleTo]( [param:Vector2 v] )</h3>
+		<p>
+		Returns the angle between this vector and vector [page:Vector2 v] in radians.
+		</p>
+
 		<h3>[method:this applyMatrix3]( [param:Matrix3 m] )</h3>
 		<p>
 		Multiplies this vector (with an implicit 1 as the 3rd component) by m.

+ 5 - 0
docs/api/it/math/Vector2.html

@@ -100,6 +100,11 @@
 			Calcola l'angolo in radianti di questo vettore rispetto all'asse x positivo. 
 		</p>
 
+		<h3>[method:Float angleTo]( [param:Vector2 v] )</h3>
+		<p>
+			Restituisce l'angolo tra questo vettore e il vettore [page:Vector2 v] in radianti.
+		</p>
+
 		<h3>[method:this applyMatrix3]( [param:Matrix3 m] )</h3>
 		<p>
 			Moltiplica questo vettore (con un 1 implicito come terza componente) per m.

+ 5 - 0
docs/api/zh/math/Vector2.html

@@ -97,6 +97,11 @@
 			计算该向量相对于x轴正方向的弧度角度。
 		</p>
 
+		<h3>[method:Float angleTo]( [param:Vector2 v] )</h3>
+		<p>
+		以弧度返回该向量与向量[page:Vector2 v]之间的角度。
+		</p>
+
 		<h3>[method:this applyMatrix3]( [param:Matrix3 m] )</h3>
 		<p>
 			将该向量乘以三阶矩阵m(第三个值隐式地为1)。

+ 16 - 0
src/math/Vector2.js

@@ -1,3 +1,5 @@
+import * as MathUtils from './MathUtils.js';
+
 class Vector2 {
 
 	constructor( x = 0, y = 0 ) {
@@ -353,6 +355,20 @@ class Vector2 {
 
 	}
 
+	angleTo( v ) {
+
+		const denominator = Math.sqrt( this.lengthSq() * v.lengthSq() );
+
+		if ( denominator === 0 ) return Math.PI / 2;
+
+		const theta = this.dot( v ) / denominator;
+
+		// clamp, to handle numerical problems
+
+		return Math.acos( MathUtils.clamp( theta, - 1, 1 ) );
+
+	}
+
 	distanceTo( v ) {
 
 		return Math.sqrt( this.distanceToSquared( v ) );

+ 18 - 0
test/unit/src/math/Vector2.tests.js

@@ -363,6 +363,24 @@ export default QUnit.module( 'Maths', () => {
 
 		} );
 
+		QUnit.test( 'angleTo', ( assert ) => {
+
+			const a = new Vector2( - 0.18851655680720186, 0.9820700116639124 );
+			const b = new Vector2( 0.18851655680720186, - 0.9820700116639124 );
+
+			assert.equal( a.angleTo( a ), 0 );
+			assert.equal( a.angleTo( b ), Math.PI );
+
+			const x = new Vector2( 1, 0 );
+			const y = new Vector2( 0, 1 );
+
+			assert.equal( x.angleTo( y ), Math.PI / 2 );
+			assert.equal( y.angleTo( x ), Math.PI / 2 );
+
+			assert.ok( Math.abs( x.angleTo( new Vector2( 1, 1 ) ) - ( Math.PI / 4 ) ) < 0.0000001 );
+
+		} );
+
 		QUnit.todo( 'distanceTo', ( assert ) => {
 
 			assert.ok( false, 'everything\'s gonna be alright' );