Jelajahi Sumber

add radius to Spherical Coordinate class.

Ben Houston 9 tahun lalu
induk
melakukan
a9867fe4ad

+ 3 - 5
examples/js/controls/EditorControls.js

@@ -86,17 +86,15 @@ THREE.EditorControls = function ( object, domElement ) {
 
 		vector.copy( object.position ).sub( center );
 
-		var spherical = new THREE.Spherical().fromDirection( vector );
+		var spherical = new THREE.Spherical().fromVector3( vector );
 
 		spherical.theta += delta.x;
 		spherical.phi += delta.y;
 
 		spherical.makeSafe();
 
-		var radius = vector.length();
-
-		vector = spherical.direction().multiplyScalar( radius );
-
+		vector = spherical.toVector3();
+		
 		object.position.copy( center ).add( vector );
 
 		object.lookAt( center );

+ 7 - 7
examples/js/controls/OrbitControls.js

@@ -133,7 +133,7 @@ THREE.OrbitControls = function ( object, domElement ) {
 			offset.applyQuaternion( quat );
 
 			// angle from z-axis around y-axis
-			spherical.fromDirection( offset );
+			spherical.fromVector3( offset );
 
 			if ( scope.autoRotate && state === STATE.NONE ) {
 
@@ -149,18 +149,18 @@ THREE.OrbitControls = function ( object, domElement ) {
 			// restrict phi to be between desired limits
 			spherical.phi = Math.max( scope.minPolarAngle, Math.min( scope.maxPolarAngle, spherical.phi ) );
 
-			// restrict phi to be betwee EPS and PI-EPS
-			spherical.phi = Math.max( EPS, Math.min( Math.PI - EPS, spherical.phi ) );
+			spherical.makeSafe();
 
-			var radius = offset.length() * scale;
+
+			spherical.radius *= scale;
 
 			// restrict radius to be between desired limits
-			radius = Math.max( scope.minDistance, Math.min( scope.maxDistance, radius ) );
+			spherical.radius = Math.max( scope.minDistance, Math.min( scope.maxDistance, spherical.radius ) );
 
 			// move target to panned location
 			scope.target.add( panOffset );
 
-			offset = spherical.direction( offset ).multiplyScalar( radius );
+			offset = spherical.toVector3( offset );
 
 			// rotate offset back to "camera-up-vector-is-up" space
 			offset.applyQuaternion( quatInverse );
@@ -175,7 +175,7 @@ THREE.OrbitControls = function ( object, domElement ) {
 
 			} else {
 
-				sphericalDelta.set( 0, 0 );
+				sphericalDelta.set( 0, 0, 0 );
 
 			}
 

+ 25 - 10
src/math/Spherical.js

@@ -1,10 +1,14 @@
 /**
  * @author bhouston / http://clara.io
  * @author WestLangley / http://github.com/WestLangley
+ *
+ * Ref: https://en.wikipedia.org/wiki/Spherical_coordinate_system
+ *
  */
 
-THREE.Spherical = function ( phi, theta ) {
+THREE.Spherical = function ( radius, phi, theta ) {
 
+	this.radius = ( radius !== undefined ) ? radius : 1.0;
 	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
 
@@ -16,8 +20,9 @@ THREE.Spherical.prototype = {
 
 	constructor: THREE.Spherical,
 
-	set: function ( phi, theta ) {
+	set: function ( radius, phi, theta ) {
 
+		this.radius = radius;
     this.phi = phi;
     this.theta = theta;
 
@@ -31,6 +36,7 @@ THREE.Spherical.prototype = {
 
 	copy: function ( other ) {
 
+		this.radius.copy( other.radius );
 		this.phi.copy( other.phi );
 		this.theta.copy( other.theta );
 
@@ -40,6 +46,7 @@ THREE.Spherical.prototype = {
 
   add: function ( other ) {
 
+		this.radius += other.radius;
     this.phi += other.phi;
     this.theta += other.theta;
 
@@ -49,6 +56,7 @@ THREE.Spherical.prototype = {
 
   multiplyScalar: function( scalar ) {
 
+		this.radius *= scalar;
     this.phi *= scalar;
     this.theta *= scalar;
 
@@ -63,23 +71,30 @@ THREE.Spherical.prototype = {
 
 	},
 
-  fromDirection: function( direction ) {
+  fromVector3: function( vec3 ) {
 
-    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
+		this.radius = vec3.length();
+		if( this.radius === 0 ) {
+			this.theta = 0;
+			this.phi = 0;
+		}
+		else {
+    	this.theta = Math.atan2( vec3.x, vec3.z ); // equator angle around y-up axis
+    	this.phi = Math.acos( vec3.y / this.radius ); // polar angle
+		}
 
     return this;
 
   },
 
-  direction: function( optionalTarget ) {
+  toVector3: function( optionalTarget ) {
 
     var result = optionalTarget || new THREE.Vector3();
-		var sinPhi = Math.sin( this.phi );
+		var sinPhiRadius = Math.sin( this.phi ) * this.radius;
     result.set(
-      sinPhi * Math.sin( this.theta ),
-      Math.cos( this.phi ),
-      sinPhi * Math.cos( this.theta )
+      sinPhiRadius * Math.sin( this.theta ),
+      Math.cos( this.phi ) * this.radius,
+      sinPhiRadius * Math.cos( this.theta )
     );
 
     return result;