Browse Source

first quick attempt at a spherical coordinate class.

Ben Houston 9 years ago
parent
commit
35c696c820
3 changed files with 94 additions and 24 deletions
  1. 12 24
      examples/js/controls/OrbitControls.js
  2. 81 0
      src/math/Spherical.js
  3. 1 0
      utils/build/includes/common.json

+ 12 - 24
examples/js/controls/OrbitControls.js

@@ -133,12 +133,7 @@ THREE.OrbitControls = function ( object, domElement ) {
 			offset.applyQuaternion( quat );
 
 			// angle from z-axis around y-axis
-
-			theta = Math.atan2( offset.x, offset.z );
-
-			// angle from y-axis
-
-			phi = Math.atan2( Math.sqrt( offset.x * offset.x + offset.z * offset.z ), offset.y );
+			spherical.fromDirection( offset );
 
 			if ( scope.autoRotate && state === STATE.NONE ) {
 
@@ -146,17 +141,16 @@ THREE.OrbitControls = function ( object, domElement ) {
 
 			}
 
-			theta += thetaDelta;
-			phi += phiDelta;
+			spherical.add( sphericalDelta );
 
 			// restrict theta to be between desired limits
-			theta = Math.max( scope.minAzimuthAngle, Math.min( scope.maxAzimuthAngle, theta ) );
+			spherical.theta = Math.max( scope.minAzimuthAngle, Math.min( scope.maxAzimuthAngle, spherical.theta ) );
 
 			// restrict phi to be between desired limits
-			phi = Math.max( scope.minPolarAngle, Math.min( scope.maxPolarAngle, phi ) );
+			spherical.phi = Math.max( scope.minPolarAngle, Math.min( scope.maxPolarAngle, spherical.phi ) );
 
 			// restrict phi to be betwee EPS and PI-EPS
-			phi = Math.max( EPS, Math.min( Math.PI - EPS, phi ) );
+			spherical.phi = Math.max( EPS, Math.min( Math.PI - EPS, spherical.phi ) );
 
 			var radius = offset.length() * scale;
 
@@ -166,9 +160,7 @@ THREE.OrbitControls = function ( object, domElement ) {
 			// move target to panned location
 			scope.target.add( panOffset );
 
-			offset.x = radius * Math.sin( phi ) * Math.sin( theta );
-			offset.y = radius * Math.cos( phi );
-			offset.z = radius * Math.sin( phi ) * Math.cos( theta );
+			offset = spherical.direction( offset ).multiplyScalar( radius );
 
 			// rotate offset back to "camera-up-vector-is-up" space
 			offset.applyQuaternion( quatInverse );
@@ -179,13 +171,11 @@ THREE.OrbitControls = function ( object, domElement ) {
 
 			if ( scope.enableDamping === true ) {
 
-				thetaDelta *= ( 1 - scope.dampingFactor );
-				phiDelta *= ( 1 - scope.dampingFactor );
+				sphericalDelta.multiplyScalar( 1 - scope.dampingFactor );
 
 			} else {
 
-				thetaDelta = 0;
-				phiDelta = 0;
+				sphericalDelta.set( 0, 0 );
 
 			}
 
@@ -254,11 +244,9 @@ THREE.OrbitControls = function ( object, domElement ) {
 	var EPS = 0.000001;
 
 	// current position in spherical coordinates
-	var theta;
-	var phi;
+	var spherical = new THREE.Spherical();
+	var sphericalDelta = new THREE.Spherical();
 
-	var phiDelta = 0;
-	var thetaDelta = 0;
 	var scale = 1;
 	var panOffset = new THREE.Vector3();
 	var zoomChanged = false;
@@ -289,13 +277,13 @@ THREE.OrbitControls = function ( object, domElement ) {
 
 	function rotateLeft( angle ) {
 
-		thetaDelta -= angle;
+		sphericalDelta.theta -= angle;
 
 	}
 
 	function rotateUp( angle ) {
 
-		phiDelta -= angle;
+		sphericalDelta.phi -= angle;
 
 	}
 

+ 81 - 0
src/math/Spherical.js

@@ -0,0 +1,81 @@
+/**
+ * @author bhouston / http://clara.io
+ * @author WestLangley / http://github.com/WestLangley
+ */
+
+THREE.Spherical = function ( phi, theta ) {
+
+	this.phi = ( phi !== undefined ) ? phi : 0; // up / down towards top and bottom pole
+	this.theta = ( theta !== undefined ) ? theta : 0; // around the equator of the sphere
+
+	return this;
+	
+};
+
+THREE.Spherical.prototype = {
+
+	constructor: THREE.Spherical,
+
+	set: function ( phi, theta ) {
+
+    this.phi = phi;
+    this.theta = theta;
+
+  },
+
+	clone: function () {
+
+		return new this.constructor().copy( this );
+
+	},
+
+	copy: function ( other ) {
+
+		this.phi.copy( other.phi );
+		this.theta.copy( other.theta );
+
+		return this;
+
+	},
+
+  add: function ( other ) {
+
+    this.phi += other.phi;
+    this.theta += other.theta;
+
+    return this;
+
+  },
+
+  multiplyScalar: function( scalar ) {
+
+    this.phi *= scalar;
+    this.theta *= scalar;
+
+    return this;
+  },
+
+  fromDirection: function( direction ) {
+
+    this.theta = Math.atan2( direction.x, direction.z ); // equator angle around y-up axis
+    this.phi = Math.atan2( Math.sqrt( direction.x * direction.x + direction.z * direction.z ), direction.y ); // polar angle
+
+    return this;
+
+  },
+
+  direction: function( optionalTarget ) {
+
+    var result = optionalTarget || new THREE.Vector3();
+		var sinPhi = Math.sin( this.phi );
+    result.set(
+      sinPhi * Math.sin( this.theta ),
+      Math.cos( this.phi ),
+      sinPhi * Math.cos( this.theta )
+    );
+
+    return result;
+
+  }
+
+};

+ 1 - 0
utils/build/includes/common.json

@@ -15,6 +15,7 @@
 	"src/math/Sphere.js",
 	"src/math/Frustum.js",
 	"src/math/Plane.js",
+	"src/math/Spherical.js",
 	"src/math/Math.js",
 	"src/math/Spline.js",
 	"src/math/Triangle.js",