三维空间中直角坐标与球坐标的相互转换

三维直角坐标系

三维直角坐标系是一种利用直角坐标(x,y,z)来表示一个点 P 在三维空间的位置的三维正交坐标系

注:本文所讨论的三维直角坐标系,默认其x-轴、y-轴、z-轴满足右手定则(如右图所示)。

在三维空间的任何一点 P ,可以用直角坐标(x,y,z)来表达其位置。如左下图显示了三维直角坐标的几何意义:点P在x-轴、y-轴、z-轴上的投影距离分别为x、y、z。如右下图所示,两个点 P 与 Q 的直角坐标分别为(3,0,5)与(-5,-5,7) 。

球坐标系

球坐标系是一种利用球坐标(r,θ,φ)来表示一个点 P 在三维空间的位置的三维正交坐标系

 下图描述了球坐标的几何意义:原点O与目标点P之间的径向距离为r,O到P的连线与正z-轴之间的夹角为天顶角θ,O到P的连线在xy-平面上的投影线与正x-轴之间的夹角为方位角φ

假设 P 点在三维空间的位置的三个坐标是 (r,\ \theta,\ \phi)。那么, 0 ≤ r 是从原点到 P 点的距离, 0 ≤ θ ≤ π 是从原点到 P 点的连线与正 z-轴的夹角, 0 ≤ φ < 2π 是从原点到 P 点的连线在 xy-平面的投影线,与正 x-轴的夹角。当 r=0 时,\theta 与 \phi 都一起失去意义。当 \theta = 0 或 \theta = \pi 时,\phi 失去意义。

三维空间下直角坐标与球坐标的相互转换

直接坐标转球坐标

{r}=\sqrt{x^2 + y^2 + z^2} 、

{\theta}=\arctan \left( \frac{\sqrt{x^2 + y^2}}{z} \right)=\arccos \left( {\frac{z}{\sqrt{x^2 + y^2 + z^2}}} \right) 、

{\phi}=\arctan \left( {\frac{y}{x}} \right) 。

球坐标转直角坐标

x=r \sin\theta \cos\phi 、

y=r \sin\theta \sin\phi 、

z=r \cos\theta 。

基于Flex的坐标转换实现

直角坐标定义类CartesianCoord.cs

package hans_gis.coord
{
	public class CartesianCoord
	{
		public var x:Number;
		public var y:Number;
		public var z:Number;
		
		static private var temp:CartesianCoord = CartesianCoord.ZERO;
		
		public function CartesianCoord(x:Number=0, y:Number=0, z:Number=0)
		{
			this.x = x;
			this.y = y;
			this.z = z;
		}
		
		public function clone():CartesianCoord
		{
			return new CartesianCoord(this.x, this.y, this.z);
		}
		
		public function copyTo(n:CartesianCoord):void
		{
			n.x = this.x;
			n.y = this.y;
			n.z = this.z;
		}
		
		public function copyFrom(n:CartesianCoord):void
		{
			this.x = n.x; 
			this.y = n.y; 
			this.z = n.z; 
		}
		
		public function reset(newx:Number = 0, newy:Number = 0, newz:Number = 0):void
		{
			this.x = newx; 
			this.y = newy; 
			this.z = newz; 
		}
		
		static public function get ZERO():CartesianCoord
		{
			return new CartesianCoord(0, 0, 0);
		}
	}
}

球坐标定义类SphericalCoord.cs

package hans_gis.coord
{
	public class SphericalCoord
	{
		public var radius:Number;
		public var theta:Number;
		public var phi:Number;
		
		static private var temp:SphericalCoord = SphericalCoord.ZERO;
		
		public function SphericalCoord(radius:Number=0, theta:Number=0, phi:Number=0)
		{
			this.radius = radius;
			this.theta = theta;
			this.phi = phi;
		}
		
		public function clone():SphericalCoord
		{
			return new SphericalCoord(this.radius, this.theta, this.phi);
		}
		
		public function copyTo(n:SphericalCoord):void
		{
			n.radius = this.radius;
			n.theta = this.theta;
			n.phi = this.phi;
		}
		
		public function copyFrom(n:SphericalCoord):void
		{
			this.radius = n.radius; 
			this.theta = n.theta; 
			this.phi = n.phi; 
		}
		
		public function reset(newradius:Number = 0, newtheta:Number = 0, newphi:Number = 0):void
		{
			this.radius = newradius; 
			this.theta = newtheta; 
			this.phi = newphi; 
		}
		
		static public function get ZERO():SphericalCoord
		{
			return new SphericalCoord(0, 0, 0);
		}
	}
}

坐标转换定义类CoordsTransform.cs

package hans_gis.coord
{
	public class CoordsTransform
	{
		public function CoordsTransform()
		{
		}
		
		public function CartesianToSpherical(coord:CartesianCoord):SphericalCoord{
			var radius = this.GetModuloFromCartesianCoord(coord);
			var theta = this.GetThetaFromCartesianCoord(coord);
			var phi = this.GetPhiFromCartesianCoord(coord);
			return new SphericalCoord(radius, theta, phi);
		}
		
		protected function GetModuloFromCartesianCoord(coord:CartesianCoord):Number
		{
			return Math.sqrt( coord.x*coord.x + coord.y*coord.y + coord.z*coord.z );
		}
		
		protected function GetThetaFromCartesianCoord(coord:CartesianCoord):Number{
//			return Math.atan(Math.sqrt(coord.x*coord.x + coord.y*coord.y)/coord.z);
			return Math.acos(coord.z/this.GetModuloFromCartesianCoord(coord));
		}
		
		protected function GetPhiFromCartesianCoord(coord:CartesianCoord):Number{
			return Math.atan(coord.y/coord.x);
		}
		
		public function SphericalToCartesian(coord:SphericalCoord):CartesianCoord{
			var x = this.GetXFromSphericalCoord(coord);
			var y = this.GetYFromSphericalCoord(coord);
			var z = this.GetZFromSphericalCoord(coord);
			return new CartesianCoord(x, y, z);
		}
		
		protected function GetXFromSphericalCoord(coord:SphericalCoord):Number{
			return coord.radius*Math.sin(coord.theta)*Math.cos(coord.phi);
		}
		
		protected function GetYFromSphericalCoord(coord:SphericalCoord):Number{
			return coord.radius*Math.sin(coord.theta)*Math.sin(coord.phi);
		}
		
		protected function GetZFromSphericalCoord(coord:SphericalCoord):Number{
			return coord.radius*Math.cos(coord.theta);
		}
	}
}

实例运行结果

附:实例下载

posted @ 2012-11-21 10:20  百折不回  阅读(44318)  评论(3编辑  收藏  举报